indi-0.5/0000755000175000017500000000000011017761434010115 5ustar jrjrindi-0.5/config.guess0000755000175000017500000012512310605175720012440 0ustar jrjr#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2005-07-08' # This file 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_MACHINE}" in i?86) test -z "$VENDOR" && VENDOR=pc ;; *) test -z "$VENDOR" && VENDOR=unknown ;; esac test -f /etc/SuSE-release -o -f /.buildenv && VENDOR=suse # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerppc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; x86:Interix*:[34]*) echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' exit ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux exit ;; cris:Linux:*:*) echo cris-axis-linux exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux exit ;; frv:Linux:*:*) echo frv-${VENDOR}-linux exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && { echo "${CPU}-${VENDOR}-linux"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && { echo "${CPU}-${VENDOR}-linux"; exit; } ;; ppc:Linux:*:*) echo powerpc-${VENDOR}-linux exit ;; ppc64:Linux:*:*) echo powerpc64-${VENDOR}-linux exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-${VENDOR}-linux${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-${VENDOR}-linux ;; PA8*) echo hppa2.0-${VENDOR}-linux ;; *) echo hppa-${VENDOR}-linux ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-${VENDOR}-linux exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR}-linux exit ;; x86_64:Linux:*:*) echo x86_64-${VENDOR}-linux exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-${VENDOR}-linux" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-${VENDOR}-linuxaout" exit ;; coff-i386) echo "${UNAME_MACHINE}-${VENDOR}-linuxcoff" exit ;; "") # Either a pre-BFD a.out linker (linuxoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-${VENDOR}-linuxoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #ifdef __INTEL_COMPILER LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-${VENDOR}-linux-${LIBC}" | sed 's/linux-gnu/linux/' exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in *86) UNAME_PROCESSOR=i686 ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: indi-0.5/ChangeLog0000644000175000017500000000416010610507203011656 0ustar jrjrFrom 0.4 to 0.5 # Devices: + True Technology Filter Wheel + SBIG STV # Features: + Added INDI Observer pattern to enable flexible inter-driver communication. + getINDI now supports BLOBs. + LX200 Drivers use client timestamp to update the telescope internal clock. The old behavior was to use to system's time. + Added a new INDI Standard Property: UTC_OFFSET. + Dropping threaded INDI server in favor of the slightly better non-threaded version due to performance considerations. # Bugs + SBIG CCD driver was updated to fix problems with CFITSIO. + Updated TTY API to include error reporting, in addition to fixing a few bugs. + Fixed INDI Mac OSX Crash. # Known Issues + Astrophysics Mount driver (apmount) is not working. It is currently under new development and is intented to be released in the next version as it matures. + Meade LPI exposure is locked to 1 second. The Video4Linux support for timed exposures is limited. A fix should be available in the next release. + The SBIG driver does not allow autoguiding. When one selects the guider CCD, any exposure on the imaging CCD is cancelled and vice-versa. From v0.3 to v0.4: # Devices: + SBIG CCD + SBIG CFW + RoboFocus + FLI Precision Focuser + Orion Atlas / Sky Scan # Other: + Added more API documentation and revised existing documentation for accuracy and consistency. + Fixed UTC correction bug in LX200 driver. + Fixed pallete selection in V4L 2 drivers. + Fixed bug in eventloop that can cause IE timers to crash. + Added variable focus speed for Meade Autostar and GPS. + Added CFITSIO, a mature and robust FITS library. + New RS232 API for common access routines. From v0.2 to v0.3: # Devices: + Apogee CCD (Experimental) + SkyCommander + Temma Takahashi + FLI Filter Wheel + Meade Lunar Planetary Imager (Experimental) + Astrophysics AP # Other: + Support for Video 4 Linux 2 + Multi-threaded INDI server + Binary transfer via BLOB + INDI scripting tools + Various bug fixing INDI Library v0.5 conforms to INDI wire protocol v1.6 indi-0.5/Makefile.cvs0000644000175000017500000000007510605175720012350 0ustar jrjrdefault: all all: aclocal autoheader automake autoconf indi-0.5/AUTHORS0000644000175000017500000000041610610535265011165 0ustar jrjrJasem Mutlaq Elwood C. Downey INDI drivers were written by numerous volunteers across the globe. Please refer to each driver to find the author's contact info. Thank you for making INDI such a great software! indi-0.5/ltmain.sh0000644000175000017500000055307610605175720011754 0ustar jrjr# ltmain.sh - Provide generalized library-building support services. # NOTE: Changing this file will not affect anything until you rerun configure. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # Originally by Gordon Matzigkeit , 1996 # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. basename="s,^.*/,,g" # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" # The name of this program: progname=`echo "$progpath" | $SED $basename` modename="$progname" # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 PROGRAM=ltmain.sh PACKAGE=libtool VERSION=1.5.18 TIMESTAMP=" (1.1220.2.245 2005/05/16 08:55:27)" # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Check that we have a working $echo. if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then # Yippee, $echo works! : else # Restart under the correct shell, and then maybe $echo will work. exec $SHELL "$progpath" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat <&2 $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit $EXIT_FAILURE fi # Global variables. mode=$default_mode nonopt= prev= prevopt= run= show="$echo" show_help= execute_dlfiles= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" quote_scanset='[[~#^*{};<>?'"'"' ]' ##################################### # Shell function definitions: # This seems to be the best place for them # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. func_win32_libid () { win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then win32_nmres=`eval $NM -f posix -A $1 | \ sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'` if test "X$win32_nmres" = "Ximport" ; then win32_libid_type="x86 archive import" else win32_libid_type="x86 archive static" fi fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $echo $win32_libid_type } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac CC_quoted="$CC_quoted $arg" done case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac CC_quoted="$CC_quoted $arg" done case "$@ " in " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then $echo "$modename: unable to infer tagged configuration" $echo "$modename: specify a tag with \`--tag'" 1>&2 exit $EXIT_FAILURE # else # $echo "$modename: using $tagname tagged configuration" fi ;; esac fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 exit $EXIT_FAILURE fi } # func_extract_archives gentop oldlib ... func_extract_archives () { my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" my_status="" $show "${rm}r $my_gentop" $run ${rm}r "$my_gentop" $show "$mkdir $my_gentop" $run $mkdir "$my_gentop" my_status=$? if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then exit $my_status fi for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` my_xdir="$my_gentop/$my_xlib" $show "${rm}r $my_xdir" $run ${rm}r "$my_xdir" $show "$mkdir $my_xdir" $run $mkdir "$my_xdir" status=$? if test "$status" -ne 0 && test ! -d "$my_xdir"; then exit $status fi case $host in *-darwin*) $show "Extracting $my_xabs" # Do not bother doing anything if just a dry run if test -z "$run"; then darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` if test -n "$darwin_arches"; then darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= $show "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we have a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` lipo -create -output "$darwin_file" $darwin_files done # $darwin_filelist ${rm}r unfat-$$ cd "$darwin_orig_dir" else cd "$darwin_orig_dir" func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches fi # $run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # End of Shell function definitions ##################################### # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Parse our command line options once, thoroughly. while test "$#" -gt 0 do arg="$1" shift case $arg in -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in execute_dlfiles) execute_dlfiles="$execute_dlfiles $arg" ;; tag) tagname="$arg" preserve_args="${preserve_args}=$arg" # Check whether tagname contains only valid characters case $tagname in *[!-_A-Za-z0-9,/]*) $echo "$progname: invalid tag name: $tagname" 1>&2 exit $EXIT_FAILURE ;; esac case $tagname in CC) # Don't test for the "default" C tag, as we know, it's there, but # not specially marked. ;; *) if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then taglist="$taglist $tagname" # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" else $echo "$progname: ignoring unknown tag $tagname" 1>&2 fi ;; esac ;; *) eval "$prev=\$arg" ;; esac prev= prevopt= continue fi # Have we seen a non-optional argument yet? case $arg in --help) show_help=yes ;; --version) $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" $echo $echo "Copyright (C) 2005 Free Software Foundation, Inc." $echo "This is free software; see the source for copying conditions. There is NO" $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." exit $? ;; --config) ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath # Now print the configurations for the tags. for tagname in $taglist; do ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" done exit $? ;; --debug) $echo "$progname: enabling shell trace mode" set -x preserve_args="$preserve_args $arg" ;; --dry-run | -n) run=: ;; --features) $echo "host: $host" if test "$build_libtool_libs" = yes; then $echo "enable shared libraries" else $echo "disable shared libraries" fi if test "$build_old_libs" = yes; then $echo "enable static libraries" else $echo "disable static libraries" fi exit $? ;; --finish) mode="finish" ;; --mode) prevopt="--mode" prev=mode ;; --mode=*) mode="$optarg" ;; --preserve-dup-deps) duplicate_deps="yes" ;; --quiet | --silent) show=: preserve_args="$preserve_args $arg" ;; --tag) prevopt="--tag" prev=tag ;; --tag=*) set tag "$optarg" ${1+"$@"} shift prev=tag preserve_args="$preserve_args --tag" ;; -dlopen) prevopt="-dlopen" prev=execute_dlfiles ;; -*) $echo "$modename: unrecognized option \`$arg'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; *) nonopt="$arg" break ;; esac done if test -n "$prevopt"; then $echo "$modename: option \`$prevopt' requires an argument" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= if test -z "$show_help"; then # Infer the operation mode. if test -z "$mode"; then $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 case $nonopt in *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) mode=link for arg do case $arg in -c) mode=compile break ;; esac done ;; *db | *dbx | *strace | *truss) mode=execute ;; *install*|cp|mv) mode=install ;; *rm) mode=uninstall ;; *) # If we have no mode, but dlfiles were specified, then do execute mode. test -n "$execute_dlfiles" && mode=execute # Just use the default operation mode. if test -z "$mode"; then if test -n "$nonopt"; then $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 else $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 fi fi ;; esac fi # Only execute mode is allowed to have -dlopen flags. if test -n "$execute_dlfiles" && test "$mode" != execute; then $echo "$modename: unrecognized option \`-dlopen'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$modename --help --mode=$mode' for more information." # These modes are in order of execution frequency so that they run quickly. case $mode in # libtool compile mode compile) modename="$modename: compile" # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= for arg do case "$arg_mode" in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) if test -n "$libobj" ; then $echo "$modename: you cannot specify \`-o' more than once" 1>&2 exit $EXIT_FAILURE fi arg_mode=target continue ;; -static | -prefer-pic | -prefer-non-pic) later="$later $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" # Double-quote args containing other shell metacharacters. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac lastarg="$lastarg $arg" done IFS="$save_ifs" lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` # Add the arguments to base_compile. base_compile="$base_compile $lastarg" continue ;; * ) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` case $lastarg in # Double-quote args containing other shell metacharacters. # Many Bourne shells cannot handle close brackets correctly # in scan sets, and some SunOS ksh mistreat backslash-escaping # in scan sets (worked around with variable expansion), # and furthermore cannot handle '|' '&' '(' ')' in scan sets # at all, so we specify them separately. *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") lastarg="\"$lastarg\"" ;; esac base_compile="$base_compile $lastarg" done # for arg case $arg_mode in arg) $echo "$modename: you must specify an argument for -Xcompile" exit $EXIT_FAILURE ;; target) $echo "$modename: you must specify a target with \`-o'" 1>&2 exit $EXIT_FAILURE ;; *) # Get the name of the library object. [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo xform='[cCFSifmso]' case $libobj in *.ada) xform=ada ;; *.adb) xform=adb ;; *.ads) xform=ads ;; *.asm) xform=asm ;; *.c++) xform=c++ ;; *.cc) xform=cc ;; *.ii) xform=ii ;; *.class) xform=class ;; *.cpp) xform=cpp ;; *.cxx) xform=cxx ;; *.f90) xform=f90 ;; *.for) xform=for ;; *.java) xform=java ;; esac libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` case $libobj in *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; *) $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 exit $EXIT_FAILURE ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -static) build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` case $qlibobj in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") qlibobj="\"$qlibobj\"" ;; esac if test "X$libobj" != "X$qlibobj"; then $echo "$modename: libobj name \`$libobj' may not contain shell special characters." exit $EXIT_FAILURE fi objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$obj"; then xdir= else xdir=$xdir/ fi lobj=${xdir}$objdir/$objname if test -z "$base_compile"; then $echo "$modename: you must specify a compilation command" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi $run $rm $removelist trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" removelist="$removelist $output_obj $lockfile" trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $run ln "$progpath" "$lockfile" 2>/dev/null; do $show "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $echo "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit $EXIT_FAILURE fi $echo "$srcfile" > "$lockfile" fi if test -n "$fix_srcfile_path"; then eval srcfile=\"$fix_srcfile_path\" fi qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` case $qsrcfile in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") qsrcfile="\"$qsrcfile\"" ;; esac $run $rm "$libobj" "${libobj}T" # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then $echo "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then $show "$mv $output_obj $lobj" if $run $mv $output_obj $lobj; then : else error=$? $run $rm $removelist exit $error fi fi # Append the name of the PIC object to the libtool object file. test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then $echo "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then $show "$mv $output_obj $obj" if $run $mv $output_obj $obj; then : else error=$? $run $rm $removelist exit $error fi fi # Append the name of the non-PIC object the libtool object file. # Only append if the libtool object file exists. test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi else if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi fi build_libtool_libs=no build_old_libs=yes prefer_static_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test ;; *) qarg=$arg ;; esac libtool_args="$libtool_args $qarg" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) compile_command="$compile_command @OUTPUT@" finalize_command="$finalize_command @OUTPUT@" ;; esac case $prev in dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. compile_command="$compile_command @SYMFILE@" finalize_command="$finalize_command @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" else dlprefiles="$dlprefiles $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" if test ! -f "$arg"; then $echo "$modename: symbol file \`$arg' does not exist" exit $EXIT_FAILURE fi prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat $save_arg` do # moreargs="$moreargs $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then pic_object= non_pic_object= # Read the .lo file # If there is no directory component, then add one. case $arg in */* | *\\*) . $arg ;; *) . ./$arg ;; esac if test -z "$pic_object" || \ test -z "$non_pic_object" || test "$pic_object" = none && \ test "$non_pic_object" = none; then $echo "$modename: cannot find name of object for \`$arg'" 1>&2 exit $EXIT_FAILURE fi # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. libobjs="$libobjs $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object non_pic_objects="$non_pic_objects $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi fi else # Only an error if not doing a dry-run. if test -z "$run"; then $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 exit $EXIT_FAILURE else # Dry-run case. # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` libobjs="$libobjs $pic_object" non_pic_objects="$non_pic_objects $non_pic_object" fi fi done else $echo "$modename: link input file \`$save_arg' does not exist" exit $EXIT_FAILURE fi arg=$save_arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 exit $EXIT_FAILURE ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) rpath="$rpath $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) xrpath="$xrpath $arg" ;; esac fi prev= continue ;; xcompiler) compiler_flags="$compiler_flags $qarg" prev= compile_command="$compile_command $qarg" finalize_command="$finalize_command $qarg" continue ;; xlinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $wl$qarg" prev= compile_command="$compile_command $wl$qarg" finalize_command="$finalize_command $wl$qarg" continue ;; xcclinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $qarg" prev= compile_command="$compile_command $qarg" finalize_command="$finalize_command $qarg" continue ;; shrext) shrext_cmds="$arg" prev= continue ;; darwin_framework) compiler_flags="$compiler_flags $arg" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" prev= continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then compile_command="$compile_command $link_static_flag" finalize_command="$finalize_command $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 continue ;; -avoid-version) avoid_version=yes continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then $echo "$modename: more than one -exported-symbols argument is not allowed" exit $EXIT_FAILURE fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=darwin_framework compiler_flags="$compiler_flags $arg" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" ;; esac continue ;; -L*) dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 exit $EXIT_FAILURE fi dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "*) ;; *) deplibs="$deplibs -L$dir" lib_search_path="$lib_search_path $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) case :$dllsearchpath: in *":$dir:"*) ;; *) dllsearchpath="$dllsearchpath:$dir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-pw32* | *-*-beos*) # These systems don't actually have a C or math library (as such) continue ;; *-*-mingw* | *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework deplibs="$deplibs -framework System" continue esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi deplibs="$deplibs $arg" continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. -model) compile_command="$compile_command $arg" compiler_flags="$compiler_flags $arg" finalize_command="$finalize_command $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) compiler_flags="$compiler_flags $arg" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" continue ;; -module) module=yes continue ;; # -64, -mips[0-9] enable 64-bit mode on the SGI compiler # -r[0-9][0-9]* specifies the processor on the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler # +DA*, +DD* enable 64-bit mode on the HP compiler # -q* pass through compiler args for the IBM compiler # -m* pass through architecture-specific compiler args for GCC -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" if test "$with_gcc" = "yes" ; then compiler_flags="$compiler_flags $arg" fi continue ;; -shrext) prev=shrext continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) # The PATH hackery in wrapper scripts is required on Windows # in order for the loader to find any dlls it needs. $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 exit $EXIT_FAILURE ;; esac case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac continue ;; -static) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -Wc,*) args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" case $flag in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") flag="\"$flag\"" ;; esac arg="$arg $wl$flag" compiler_flags="$compiler_flags $flag" done IFS="$save_ifs" arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ;; -Wl,*) args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" case $flag in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") flag="\"$flag\"" ;; esac arg="$arg $wl$flag" compiler_flags="$compiler_flags $wl$flag" linker_flags="$linker_flags $flag" done IFS="$save_ifs" arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # Some other compiler flag. -* | +*) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac ;; *.$objext) # A standard object. objs="$objs $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then pic_object= non_pic_object= # Read the .lo file # If there is no directory component, then add one. case $arg in */* | *\\*) . $arg ;; *) . ./$arg ;; esac if test -z "$pic_object" || \ test -z "$non_pic_object" || test "$pic_object" = none && \ test "$non_pic_object" = none; then $echo "$modename: cannot find name of object for \`$arg'" 1>&2 exit $EXIT_FAILURE fi # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. libobjs="$libobjs $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object non_pic_objects="$non_pic_objects $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi fi else # Only an error if not doing a dry-run. if test -z "$run"; then $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 exit $EXIT_FAILURE else # Dry-run case. # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` libobjs="$libobjs $pic_object" non_pic_objects="$non_pic_objects $non_pic_object" fi fi ;; *.$libext) # An archive. deplibs="$deplibs $arg" old_deplibs="$old_deplibs $arg" continue ;; *.la) # A libtool-controlled library. if test "$prev" = dlfiles; then # This library was specified with -dlopen. dlfiles="$dlfiles $arg" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. dlprefiles="$dlprefiles $arg" prev= else deplibs="$deplibs $arg" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" fi done # argument parsing loop if test -n "$prev"; then $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" fi oldlibs= # calculate the name of the file, without its directory outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` if test "X$output_objdir" = "X$output"; then output_objdir="$objdir" else output_objdir="$output_objdir/$objdir" fi # Create the object directory. if test ! -d "$output_objdir"; then $show "$mkdir $output_objdir" $run $mkdir $output_objdir status=$? if test "$status" -ne 0 && test ! -d "$output_objdir"; then exit $status fi fi # Determine the type of output case $output in "") $echo "$modename: you must specify an output file" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac case $host in *cygwin* | *mingw* | *pw32*) # don't eliminate duplications in $postdeps and $predeps duplicate_compiler_generated_deps=yes ;; *) duplicate_compiler_generated_deps=$duplicate_deps ;; esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if test "X$duplicate_deps" = "Xyes" ; then case "$libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi libs="$libs $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; esac pre_post_deps="$pre_post_deps $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 exit $EXIT_FAILURE ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else compiler_flags="$compiler_flags $deplib" fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 continue fi name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then library_names= old_library= case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` test "X$ladir" = "X$lib" && ladir="." lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` ;; *) $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) lib="$deplib" ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` if eval $echo \"$deplib\" 2>/dev/null \ | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then $echo $echo "*** Warning: Trying to link with static lib archive $deplib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have" $echo "*** because the file extensions .$libext of this argument makes me believe" $echo "*** that it is just a static archive that I should not used here." else $echo $echo "*** Warning: Linking the shared library $output against the" $echo "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. newdlprefiles="$newdlprefiles $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else newdlfiles="$newdlfiles $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else $echo "$modename: cannot find the library \`$lib'" 1>&2 exit $EXIT_FAILURE fi # Check to see that this really is a libtool archive. if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` test "X$ladir" = "X$lib" && ladir="." dlname= dlopen= dlpreopen= libdir= library_names= old_library= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && dlfiles="$dlfiles $dlopen" test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 exit $EXIT_FAILURE fi # It is a libtool convenience library, so add in its objects. convenience="$convenience $ladir/$objdir/$old_library" old_convenience="$old_convenience $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then $echo "$modename: \`$lib' is not a convenience library" 1>&2 exit $EXIT_FAILURE fi continue fi # $pass = conv # Get the name of the library we link against. linklib= for l in $old_library $library_names; do linklib="$l" done if test -z "$linklib"; then $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 exit $EXIT_FAILURE fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 exit $EXIT_FAILURE fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. dlprefiles="$dlprefiles $lib $dependency_libs" else newdlfiles="$newdlfiles $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 abs_ladir="$ladir" fi ;; esac laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then $echo "$modename: warning: library \`$lib' was moved." 1>&2 dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$libdir" absdir="$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" fi fi # $installed = yes name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir"; then $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 exit $EXIT_FAILURE fi # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then newdlprefiles="$newdlprefiles $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then newdlprefiles="$newdlprefiles $dir/$dlname" else newdlprefiles="$newdlprefiles $dir/$linklib" fi fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then newlib_search_path="$newlib_search_path $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { test "$prefer_static_libs" = no || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath " in *" $dir "*) ;; *" $absdir "*) ;; *) temp_rpath="$temp_rpath $dir" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically if test -n "$library_names" && { test "$prefer_static_libs" = no || test -z "$old_library"; }; then if test "$installed" = no; then notinst_deplibs="$notinst_deplibs $lib" need_relink=yes fi # This is a shared library # Warn about portability, can't link against -module's on # some systems (darwin) if test "$shouldnotlink" = yes && test "$pass" = link ; then $echo if test "$linkmode" = prog; then $echo "*** Warning: Linking the executable $output against the loadable module" else $echo "*** Warning: Linking the shared library $output against the loadable module" fi $echo "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names realname="$2" shift; shift libname=`eval \\$echo \"$libname_spec\"` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw*) major=`expr $current - $age` versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" soname=`$echo $soroot | ${SED} -e 's/^.*\///'` newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else $show "extracting exported symbol list from \`$soname'" save_ifs="$IFS"; IFS='~' cmds=$extract_expsyms_cmds for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else $show "generating import library for \`$soname'" save_ifs="$IFS"; IFS='~' cmds=$old_archive_from_expsyms_cmds for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5* ) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a module then we can not link against # it, someone is ignoring the new warnings I added if /usr/bin/file -L $add 2> /dev/null | $EGREP "bundle" >/dev/null ; then $echo "** Warning, lib $linklib is a module, not a shared library" if test -z "$old_library" ; then $echo $echo "** And there doesn't seem to be a static archive available" $echo "** The link will probably fail, sorry" else add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$dir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case "$libdir" in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then $echo "$modename: configuration error: unsupported hardcode properties" exit $EXIT_FAILURE fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && \ test "$hardcode_minus_L" != yes && \ test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case "$libdir" in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. $echo $echo "*** Warning: This system can not link to static lib archive $lib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then $echo "*** But as you try to build a module library, libtool will still create " $echo "*** a static module, that should work as long as the dlopening application" $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then $echo $echo "*** However, this would only work if libtool was able to extract symbol" $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" $echo "*** not find such a program. So, this module is probably useless." $echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else convenience="$convenience $dir/$old_library" old_convenience="$old_convenience $dir/$old_library" deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` case " $xrpath " in *" $temp_xrpath "*) ;; *) xrpath="$xrpath $temp_xrpath";; esac;; *) temp_deplibs="$temp_deplibs $libdir";; esac done dependency_libs="$temp_deplibs" fi newlib_search_path="$newlib_search_path $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do case $deplib in -L*) path="$deplib" ;; *.la) dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$deplib" && dir="." # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 absdir="$dir" fi ;; esac if grep "^installed=no" $deplib > /dev/null; then path="$absdir/$objdir" else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` if test -z "$libdir"; then $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi if test "$absdir" != "$libdir"; then $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 fi path="$absdir" fi depdepl= case $host in *-*-darwin*) # we do not want to link against static libs, # but need to link against shared eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$path/$depdepl" ; then depdepl="$path/$depdepl" fi # do not add paths which are already there case " $newlib_search_path " in *" $path "*) ;; *) newlib_search_path="$newlib_search_path $path";; esac fi path="" ;; *) path="-L$path" ;; esac ;; -l*) case $host in *-*-darwin*) # Again, we only want to link against shared libraries eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` for tmp in $newlib_search_path ; do if test -f "$tmp/lib$tmp_libs.dylib" ; then eval depdepl="$tmp/lib$tmp_libs.dylib" break fi done path="" ;; *) continue ;; esac ;; *) continue ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac case " $deplibs " in *" $depdepl "*) ;; *) deplibs="$depdepl $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) lib_search_path="$lib_search_path $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) tmp_libs="$tmp_libs $deplib" ;; esac ;; *) tmp_libs="$tmp_libs $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then tmp_libs="$tmp_libs $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$deplibs"; then $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 fi if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 fi if test -n "$rpath"; then $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 fi if test -n "$xrpath"; then $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 fi if test -n "$export_symbols" || test -n "$export_symbols_regex"; then $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 fi # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" objs="$objs$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) if test "$module" = no; then $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 exit $EXIT_FAILURE else $echo $echo "*** Warning: Linking the shared library $output against the non-libtool" $echo "*** objects $objs is not portable!" libobjs="$libobjs $objs" fi fi if test "$dlself" != no; then $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 fi set dummy $rpath if test "$#" -gt 2; then $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 fi install_libdir="$2" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 fi else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 IFS="$save_ifs" if test -n "$8"; then $echo "$modename: too many parameters to \`-version-info'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$2" number_minor="$3" number_revision="$4" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in darwin|linux|osf|windows) current=`expr $number_major + $number_minor` age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) current=`expr $number_major + $number_minor - 1` age="$number_minor" revision="$number_minor" ;; esac ;; no) current="$2" revision="$3" age="$4" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE ;; esac if test "$age" -gt "$current"; then $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header major=.`expr $current - $age` versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... minor_current=`expr $current + 1` verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current"; ;; irix | nonstopux) major=`expr $current - $age + 1` case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do iface=`expr $revision - $loop` loop=`expr $loop - 1` verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) major=.`expr $current - $age` versuffix="$major.$age.$revision" ;; osf) major=.`expr $current - $age` versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do iface=`expr $current - $loop` loop=`expr $loop - 1` verstring="$verstring:${iface}.0" done # Make executables depend on our current version. verstring="$verstring:${current}.0" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. major=`expr $current - $age` versuffix="-$major" ;; *) $echo "$modename: unknown library version type \`$version_type'" 1>&2 $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit $EXIT_FAILURE ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi if test "$mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$echo "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi removelist="$removelist $p" ;; *) ;; esac done if test -n "$removelist"; then $show "${rm}r $removelist" $run ${rm}r $removelist fi fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then oldlibs="$oldlibs $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` fi # Eliminate all temporary directories. for path in $notinst_path; do lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'` deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'` dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do temp_xrpath="$temp_xrpath -R$libdir" case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) dlfiles="$dlfiles $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) dlprefiles="$dlprefiles $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework deplibs="$deplibs -framework System" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then deplibs="$deplibs -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $rm conftest.c cat > conftest.c </dev/null` for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null \ | grep " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ | ${SED} 10q \ | $EGREP "$file_magic_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $echo $echo "*** Warning: linker path does not have real file for library $a_deplib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have" $echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $echo "*** with $libname but no candidates were found. (...for file magic test)" else $echo "*** with $libname and none of the candidates passed a file format test" $echo "*** using a file magic. Last file checked: $potlib" fi fi else # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" fi done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` for a_deplib in $deplibs; do name="`expr $a_deplib : '-l\(.*\)'`" # If $name is empty we are operating on a -L argument. if test -n "$name" && test "$name" != "0"; then if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) newdeplibs="$newdeplibs $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval \\$echo \"$libname_spec\"` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval $echo \"$potent_lib\" 2>/dev/null \ | ${SED} 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $echo $echo "*** Warning: linker path does not have real file for library $a_deplib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have" $echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $echo "*** with $libname but no candidates were found. (...for regex pattern test)" else $echo "*** with $libname and none of the candidates passed a file format test" $echo "*** using a regex pattern. Last file checked: $potlib" fi fi else # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" fi done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ -e 's/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` done fi if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ | grep . >/dev/null; then $echo if test "X$deplibs_check_method" = "Xnone"; then $echo "*** Warning: inter-library dependencies are not supported in this platform." else $echo "*** Warning: inter-library dependencies are not known to be supported." fi $echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes fi ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then $echo $echo "*** Warning: libtool could not satisfy all declared inter-library" $echo "*** dependencies of module $libname. Therefore, libtool will create" $echo "*** a static module, that should work as long as the dlopening" $echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then $echo $echo "*** However, this would only work if libtool was able to extract symbol" $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" $echo "*** not find such a program. So, this module is probably useless." $echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else $echo "*** The inter-library dependencies that have been dropped here will be" $echo "*** automatically added whenever a program is linked with this library" $echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then $echo $echo "*** Since this library must not contain undefined symbols," $echo "*** because either the platform does not support them or" $echo "*** it was explicitly requested with -no-undefined," $echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" dep_rpath="$dep_rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" if test -n "$hardcode_libdir_flag_spec_ld"; then eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" else eval dep_rpath=\"$hardcode_libdir_flag_spec\" fi fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names realname="$2" shift; shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" for link do linknames="$linknames $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then $show "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $run $rm $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" if len=`expr "X$cmd" : ".*"` && test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then $show "$cmd" $run eval "$cmd" || exit $? skipped_export=false else # The command line is too long to execute in one step. $show "using reloadable object file for export list..." skipped_export=: fi done IFS="$save_ifs" if test -n "$export_symbols_regex"; then $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' $show "$mv \"${export_symbols}T\" \"$export_symbols\"" $run eval '$mv "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) tmp_deplibs="$tmp_deplibs $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" else gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $convenience libobjs="$libobjs $func_extract_archives_result" fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" linker_flags="$linker_flags $flag" fi # Make a backup of the uninstalled library when relinking if test "$mode" = relink; then $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && len=`expr "X$test_cmds" : ".*"` && test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise. $echo "creating reloadable object files..." # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output output_la=`$echo "X$output" | $Xsed -e "$basename"` # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= delfiles= last_robj= k=1 output=$output_objdir/$output_la-${k}.$objext # Loop over the list of objects to be linked. for obj in $save_libobjs do eval test_cmds=\"$reload_cmds $objlist $last_robj\" if test "X$objlist" = X || { len=`expr "X$test_cmds" : ".*"` && test "$len" -le "$max_cmd_len"; }; then objlist="$objlist $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. eval concat_cmds=\"$reload_cmds $objlist $last_robj\" else # All subsequent reloadable object files will link in # the last one created. eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext k=`expr $k + 1` output=$output_objdir/$output_la-${k}.$objext objlist=$obj len=1 fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" if ${skipped_export-false}; then $show "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $run $rm $export_symbols libobjs=$output # Append the command to create the export file. eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" fi # Set up a command to remove the reloadable object files # after they are used. i=0 while test "$i" -lt "$k" do i=`expr $i + 1` delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" done $echo "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi # Append the command to remove the reloadable object files # to the just-reset $cmds. eval cmds=\"\$cmds~\$rm $delfiles\" fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$mode" = relink; then $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$deplibs"; then $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 fi if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 fi if test -n "$rpath"; then $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 fi if test -n "$xrpath"; then $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 fi case $output in *.lo) if test -n "$objs$old_deplibs"; then $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 exit $EXIT_FAILURE fi libobj="$output" obj=`$echo "X$output" | $Xsed -e "$lo2o"` ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $run $rm $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" else gentop="$output_objdir/${obj}x" generated="$generated $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # Create the old-style object. reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" cmds=$reload_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $run eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" cmds=$reload_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; esac if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 fi if test "$preload" = yes; then if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && test "$dlopen_self_static" = unknown; then $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." fi fi case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` ;; esac case $host in *darwin*) # Don't allow lazy linking, it breaks C++ global constructors if test "$tagname" = CXX ; then compile_command="$compile_command ${wl}-bind_at_load" finalize_command="$finalize_command ${wl}-bind_at_load" fi ;; esac compile_command="$compile_command $compile_deplibs" finalize_command="$finalize_command $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) case :$dllsearchpath: in *":$libdir:"*) ;; *) dllsearchpath="$dllsearchpath:$libdir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` fi dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then dlsyms="${outputname}S.c" else $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 fi fi if test -n "$dlsyms"; then case $dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${outputname}.nm" $show "$rm $nlist ${nlist}S ${nlist}T" $run $rm "$nlist" "${nlist}S" "${nlist}T" # Parse the name list into a source file. $show "creating $output_objdir/$dlsyms" test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ /* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ /* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ #ifdef __cplusplus extern \"C\" { #endif /* Prevent the only kind of declaration conflicts we can make. */ #define lt_preloaded_symbols some_other_symbol /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then $show "generating symbol list for \`$output'" test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` for arg in $progfiles; do $show "extracting global C symbols from \`$arg'" $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' fi if test -n "$export_symbols_regex"; then $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $run $rm $export_symbols $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' else $run eval "${SED} -e 's/\([ ][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' $run eval 'mv "$nlist"T "$nlist"' fi fi for arg in $dlprefiles; do $show "extracting global C symbols from \`$arg'" name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` $run eval '$echo ": $name " >> "$nlist"' $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" done if test -z "$run"; then # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $mv "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if grep -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else grep -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' else $echo '/* NONE */' >> "$output_objdir/$dlsyms" fi $echo >> "$output_objdir/$dlsyms" "\ #undef lt_preloaded_symbols #if defined (__STDC__) && __STDC__ # define lt_ptr void * #else # define lt_ptr char * # define const #endif /* The mapping between symbol names and symbols. */ " case $host in *cygwin* | *mingw* ) $echo >> "$output_objdir/$dlsyms" "\ /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs */ struct { " ;; * ) $echo >> "$output_objdir/$dlsyms" "\ const struct { " ;; esac $echo >> "$output_objdir/$dlsyms" "\ const char *name; lt_ptr address; } lt_preloaded_symbols[] = {\ " eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" $echo >> "$output_objdir/$dlsyms" "\ {0, (lt_ptr) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " fi pic_flag_for_symtable= case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) case "$compile_command " in *" -static "*) ;; *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; esac;; *-*-hpux*) case "$compile_command " in *" -static "*) ;; *) pic_flag_for_symtable=" $pic_flag";; esac esac # Now compile the dynamic symbol file. $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? # Clean up the generated files. $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" # Transform the symbol file into the correct name. compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` ;; *) $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 exit $EXIT_FAILURE ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` fi if test "$need_relink" = no || test "$build_libtool_libs" != yes; then # Replace the output file specification. compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. $show "$link_command" $run eval "$link_command" status=$? # Delete the generated files. if test -n "$dlsyms"; then $show "$rm $output_objdir/${outputname}S.${objext}" $run $rm "$output_objdir/${outputname}S.${objext}" fi exit $status fi if test -n "$shlibpath_var"; then # We should set the shlibpath_var rpath= for dir in $temp_rpath; do case $dir in [\\/]* | [A-Za-z]:[\\/]*) # Absolute path. rpath="$rpath$dir:" ;; *) # Relative path: add a thisdir entry. rpath="$rpath\$thisdir/$dir:" ;; esac done temp_rpath="$rpath" fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do rpath="$rpath$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $run $rm $output # Link the executable and exit $show "$link_command" $run eval "$link_command" || exit $? exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 $echo "$modename: \`$output' will be relinked during installation" 1>&2 else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname $show "$link_command" $run eval "$link_command" || exit $? # Now create the wrapper script. $show "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` relink_command="$var=\"$var_value\"; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` fi # Quote $echo for shipping. if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then case $progpath in [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; esac qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` else qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` fi # Only actually do things if our run command is non-null. if test -z "$run"; then # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) cwrappersource=`$echo ${objdir}/lt-${outputname}.c` cwrapper=`$echo ${output}.exe` $rm $cwrappersource $cwrapper trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 cat > $cwrappersource <> $cwrappersource<<"EOF" #include #include #include #include #include #include #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef DIR_SEPARATOR #define DIR_SEPARATOR '/' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) #define HAVE_DOS_BASED_FILE_SYSTEM #ifndef DIR_SEPARATOR_2 #define DIR_SEPARATOR_2 '\\' #endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) const char *program_name = NULL; void * xmalloc (size_t num); char * xstrdup (const char *string); char * basename (const char *name); char * fnqualify(const char *path); char * strendzap(char *str, const char *pat); void lt_fatal (const char *message, ...); int main (int argc, char *argv[]) { char **newargz; int i; program_name = (char *) xstrdup ((char *) basename (argv[0])); newargz = XMALLOC(char *, argc+2); EOF cat >> $cwrappersource <> $cwrappersource <<"EOF" newargz[1] = fnqualify(argv[0]); /* we know the script has the same name, without the .exe */ /* so make sure newargz[1] doesn't end in .exe */ strendzap(newargz[1],".exe"); for (i = 1; i < argc; i++) newargz[i+1] = xstrdup(argv[i]); newargz[argc+1] = NULL; EOF cat >> $cwrappersource <> $cwrappersource <<"EOF" } void * xmalloc (size_t num) { void * p = (void *) malloc (num); if (!p) lt_fatal ("Memory exhausted"); return p; } char * xstrdup (const char *string) { return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL ; } char * basename (const char *name) { const char *base; #if defined (HAVE_DOS_BASED_FILE_SYSTEM) /* Skip over the disk name in MSDOS pathnames. */ if (isalpha (name[0]) && name[1] == ':') name += 2; #endif for (base = name; *name; name++) if (IS_DIR_SEPARATOR (*name)) base = name + 1; return (char *) base; } char * fnqualify(const char *path) { size_t size; char *p; char tmp[LT_PATHMAX + 1]; assert(path != NULL); /* Is it qualified already? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha (path[0]) && path[1] == ':') return xstrdup (path); #endif if (IS_DIR_SEPARATOR (path[0])) return xstrdup (path); /* prepend the current directory */ /* doesn't handle '~' */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */ p = XMALLOC(char, size); sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path); return p; } char * strendzap(char *str, const char *pat) { size_t len, patlen; assert(str != NULL); assert(pat != NULL); len = strlen(str); patlen = strlen(pat); if (patlen <= len) { str += len - patlen; if (strcmp(str, pat) == 0) *str = '\0'; } return str; } static void lt_error_core (int exit_status, const char * mode, const char * message, va_list ap) { fprintf (stderr, "%s: %s: ", program_name, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, "FATAL", message, ap); va_end (ap); } EOF # we should really use a build-platform specific compiler # here, but OTOH, the wrappers (shell script and this C one) # are only useful if you want to execute the "real" binary. # Since the "real" binary is built for $host, then this # wrapper might as well be built for $host, too. $run $LTCC -s -o $cwrapper $cwrappersource ;; esac $rm $output trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 $echo > $output "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='${SED} -e 1s/^X//' sed_quote_subst='$sed_quote_subst' # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variable: notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$echo are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then echo=\"$qecho\" file=\"\$0\" # Make sure echo works. if test \"X\$1\" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then # Yippee, \$echo works! : else # Restart under the correct shell, and then maybe \$echo will work. exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} fi fi\ " $echo >> $output "\ # Find the directory that this script lives in. thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` done # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $echo >> $output "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || \\ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $mkdir \"\$progdir\" else $rm \"\$progdir/\$file\" fi" $echo >> $output "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $echo \"\$relink_command_output\" >&2 $rm \"\$progdir/\$file\" exit $EXIT_FAILURE fi fi $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $rm \"\$progdir/\$program\"; $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } $rm \"\$progdir/\$file\" fi" else $echo >> $output "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $echo >> $output "\ if test -f \"\$progdir/\$program\"; then" # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $echo >> $output "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` export $shlibpath_var " fi # fixup the dll searchpath if we need to. if test -n "$dllsearchpath"; then $echo >> $output "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi $echo >> $output "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2*) $echo >> $output "\ exec \$progdir\\\\\$program \${1+\"\$@\"} " ;; *) $echo >> $output "\ exec \$progdir/\$program \${1+\"\$@\"} " ;; esac $echo >> $output "\ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" exit $EXIT_FAILURE fi else # The program doesn't exist. \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 \$echo \"This script is just a wrapper for \$program.\" 1>&2 $echo \"See the $PACKAGE documentation for more information.\" 1>&2 exit $EXIT_FAILURE fi fi\ " chmod +x $output fi exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $addlibs oldobjs="$oldobjs $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do $echo "X$obj" | $Xsed -e 's%^.*/%%' done | sort | sort -uc >/dev/null 2>&1); then : else $echo "copying selected object files to avoid basename conflicts..." if test -z "$gentop"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" $show "${rm}r $gentop" $run ${rm}r "$gentop" $show "$mkdir $gentop" $run $mkdir "$gentop" status=$? if test "$status" -ne 0 && test ! -d "$gentop"; then exit $status fi fi save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase counter=`expr $counter + 1` case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" $run ln "$obj" "$gentop/$newobj" || $run cp "$obj" "$gentop/$newobj" oldobjs="$oldobjs $gentop/$newobj" ;; *) oldobjs="$oldobjs $obj" ;; esac done fi eval cmds=\"$old_archive_cmds\" if len=`expr "X$cmds" : ".*"` && test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts $echo "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done for obj in $save_oldobjs do oldobjs="$objlist $obj" objlist="$objlist $obj" eval test_cmds=\"$old_archive_cmds\" if len=`expr "X$test_cmds" : ".*"` && test "$len" -le "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do eval cmd=\"$cmd\" IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" done if test -n "$generated"; then $show "${rm}r$generated" $run ${rm}r$generated fi # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" $show "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` relink_command="$var=\"$var_value\"; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. if test -z "$run"; then for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` if test -z "$libdir"; then $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi newdependency_libs="$newdependency_libs $libdir/$name" ;; *) newdependency_libs="$newdependency_libs $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` if test -z "$libdir"; then $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi newdlfiles="$newdlfiles $libdir/$name" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` if test -z "$libdir"; then $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi newdlprefiles="$newdlprefiles $libdir/$name" done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlfiles="$newdlfiles $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlprefiles="$newdlprefiles $abs" done dlprefiles="$newdlprefiles" fi $rm $output # place dlname in correct position for cygwin tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; esac $echo > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $echo >> $output "\ relink_command=\"$relink_command\"" fi done fi # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? ;; esac exit $EXIT_SUCCESS ;; # libtool install mode install) modename="$modename: install" # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then # Aesthetically quote it. arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac install_prog="$arg " arg="$1" shift else install_prog= arg="$nonopt" fi # The real first argument should be the name of the installation program. # Aesthetically quote it. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac install_prog="$install_prog$arg" # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= for arg do if test -n "$dest"; then files="$files $dest" dest="$arg" continue fi case $arg in -d) isdir=yes ;; -f) prev="-f" ;; -g) prev="-g" ;; -m) prev="-m" ;; -o) prev="-o" ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then prev= else dest="$arg" continue fi ;; esac # Aesthetically quote the argument. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac install_prog="$install_prog $arg" done if test -z "$install_prog"; then $echo "$modename: you must specify an install program" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test -n "$prev"; then $echo "$modename: the \`$prev' option requires an argument" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test -z "$files"; then if test -z "$dest"; then $echo "$modename: no file or destination specified" 1>&2 else $echo "$modename: you must specify a destination" 1>&2 fi $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Strip any trailing slash from the destination. dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` test "X$destdir" = "X$dest" && destdir=. destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` # Not a directory, so check to see that there is only one file specified. set dummy $files if test "$#" -gt 2; then $echo "$modename: \`$dest' is not a directory" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. staticlibs="$staticlibs $file" ;; *.la) # Check to see that this really is a libtool archive. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi library_names= old_library= relink_command= # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) current_libdirs="$current_libdirs $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) future_libdirs="$future_libdirs $libdir" ;; esac fi dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ test "X$dir" = "X$file/" && dir= dir="$dir$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. if test "$inst_prefix_dir" = "$destdir"; then $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 exit $EXIT_FAILURE fi if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi $echo "$modename: warning: relinking \`$file'" 1>&2 $show "$relink_command" if $run eval "$relink_command"; then : else $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 exit $EXIT_FAILURE fi fi # See the names of the shared library. set dummy $library_names if test -n "$2"; then realname="$2" shift shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. $show "$install_prog $dir/$srcname $destdir/$realname" $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? if test -n "$stripme" && test -n "$striplib"; then $show "$striplib $destdir/$realname" $run eval "$striplib $destdir/$realname" || exit $? fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. for linkname do if test "$linkname" != "$realname"; then $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" fi done fi # Do each command in the postinstall commands. lib="$destdir/$realname" cmds=$postinstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # Install the pseudo-library for information purposes. name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` instname="$dir/$name"i $show "$install_prog $instname $destdir/$name" $run eval "$install_prog $instname $destdir/$name" || exit $? # Maybe install the static library, too. test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` ;; *.$objext) staticdest="$destfile" destfile= ;; *) $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; esac # Install the libtool object if requested. if test -n "$destfile"; then $show "$install_prog $file $destfile" $run eval "$install_prog $file $destfile" || exit $? fi # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` $show "$install_prog $staticobj $staticdest" $run eval "$install_prog \$staticobj \$staticdest" || exit $? fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then file=`$echo $file|${SED} 's,.exe$,,'` stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin*|*mingw*) wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` ;; *) wrapper=$file ;; esac if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then notinst_deplibs= relink_command= # To insure that "foo" is sourced, and not "foo.exe", # finese the cygwin/MSYS system by explicitly sourcing "foo." # which disallows the automatic-append-.exe behavior. case $build in *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; *) wrapperdot=${wrapper} ;; esac # If there is no directory component, then add one. case $file in */* | *\\*) . ${wrapperdot} ;; *) . ./${wrapperdot} ;; esac # Check the variables that should have been set. if test -z "$notinst_deplibs"; then $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 exit $EXIT_FAILURE fi finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then # If there is no directory component, then add one. case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac fi libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 finalize=no fi done relink_command= # To insure that "foo" is sourced, and not "foo.exe", # finese the cygwin/MSYS system by explicitly sourcing "foo." # which disallows the automatic-append-.exe behavior. case $build in *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; *) wrapperdot=${wrapper} ;; esac # If there is no directory component, then add one. case $file in */* | *\\*) . ${wrapperdot} ;; *) . ./${wrapperdot} ;; esac outputname= if test "$fast_install" = no && test -n "$relink_command"; then if test "$finalize" = yes && test -z "$run"; then tmpdir="/tmp" test -n "$TMPDIR" && tmpdir="$TMPDIR" tmpdir="$tmpdir/libtool-$$" save_umask=`umask` umask 0077 if $mkdir "$tmpdir"; then umask $save_umask else umask $save_umask $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 continue fi file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` $show "$relink_command" if $run eval "$relink_command"; then : else $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 ${rm}r "$tmpdir" continue fi file="$outputname" else $echo "$modename: warning: cannot relink \`$file'" 1>&2 fi else # Install the binary that we compiled earlier. file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyways case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` ;; esac ;; esac $show "$install_prog$stripme $file $destfile" $run eval "$install_prog\$stripme \$file \$destfile" || exit $? test -n "$outputname" && ${rm}r "$tmpdir" ;; esac done for file in $staticlibs; do name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` # Set up the ranlib parameters. oldlib="$destdir/$name" $show "$install_prog $file $oldlib" $run eval "$install_prog \$file \$oldlib" || exit $? if test -n "$stripme" && test -n "$old_striplib"; then $show "$old_striplib $oldlib" $run eval "$old_striplib $oldlib" || exit $? fi # Do each command in the postinstall commands. cmds=$old_postinstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" done if test -n "$future_libdirs"; then $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 fi if test -n "$current_libdirs"; then # Maybe just do a dry run. test -n "$run" && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi ;; # libtool finish mode finish) modename="$modename: finish" libdirs="$nonopt" admincmds= if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for dir do libdirs="$libdirs $dir" done for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. cmds=$finish_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || admincmds="$admincmds $cmd" done IFS="$save_ifs" fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $run eval "$cmds" || admincmds="$admincmds $cmds" fi done fi # Exit here if they wanted silent mode. test "$show" = : && exit $EXIT_SUCCESS $echo "----------------------------------------------------------------------" $echo "Libraries have been installed in:" for libdir in $libdirs; do $echo " $libdir" done $echo $echo "If you ever happen to want to link against installed libraries" $echo "in a given directory, LIBDIR, you must either use libtool, and" $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" $echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" $echo " during execution" fi if test -n "$runpath_var"; then $echo " - add LIBDIR to the \`$runpath_var' environment variable" $echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $echo " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $echo " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi $echo $echo "See any operating system documentation about shared libraries for" $echo "more information, such as the ld(1) and ld.so(8) manual pages." $echo "----------------------------------------------------------------------" exit $EXIT_SUCCESS ;; # libtool execute mode execute) modename="$modename: execute" # The first argument is the command name. cmd="$nonopt" if test -z "$cmd"; then $echo "$modename: you must specify a COMMAND" 1>&2 $echo "$help" exit $EXIT_FAILURE fi # Handle -dlopen flags immediately. for file in $execute_dlfiles; do if test ! -f "$file"; then $echo "$modename: \`$file' is not a file" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi dir= case $file in *.la) # Check to see that this really is a libtool archive. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Read the libtool library. dlname= library_names= # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" continue fi dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$file" && dir=. if test -f "$dir/$objdir/$dlname"; then dir="$dir/$objdir" else $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 exit $EXIT_FAILURE fi ;; *.lo) # Just add the directory containing the .lo file. dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$file" && dir=. ;; *) $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -*) ;; *) # Do a test to see if this is really a libtool program. if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` args="$args \"$file\"" done if test -z "$run"; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables if test "${save_LC_ALL+set}" = set; then LC_ALL="$save_LC_ALL"; export LC_ALL fi if test "${save_LANG+set}" = set; then LANG="$save_LANG"; export LANG fi # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" $echo "export $shlibpath_var" fi $echo "$cmd$args" exit $EXIT_SUCCESS fi ;; # libtool clean and uninstall mode clean | uninstall) modename="$modename: $mode" rm="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) rm="$rm $arg"; rmforce=yes ;; -*) rm="$rm $arg" ;; *) files="$files $arg" ;; esac done if test -z "$rm"; then $echo "$modename: you must specify an RM program" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi rmdirs= origobjdir="$objdir" for file in $files; do dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` if test "X$dir" = "X$file"; then dir=. objdir="$origobjdir" else objdir="$dir/$origobjdir" fi name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` test "$mode" = uninstall && objdir="$dir" # Remember objdir for removal later, being careful to avoid duplicates if test "$mode" = clean; then case " $rmdirs " in *" $objdir "*) ;; *) rmdirs="$rmdirs $objdir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if (test -L "$file") >/dev/null 2>&1 \ || (test -h "$file") >/dev/null 2>&1 \ || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then . $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do rmfiles="$rmfiles $objdir/$n" done test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" if test "$mode" = uninstall; then if test -n "$library_names"; then # Do each command in the postuninstall commands. cmds=$postuninstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" if test "$?" -ne 0 && test "$rmforce" != yes; then exit_status=1 fi done IFS="$save_ifs" fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. cmds=$old_postuninstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" if test "$?" -ne 0 && test "$rmforce" != yes; then exit_status=1 fi done IFS="$save_ifs" fi # FIXME: should reinstall the best remaining shared library. fi fi ;; *.lo) # Possibly a libtool object, so verify it. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then # Read the .lo file . $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" \ && test "$pic_object" != none; then rmfiles="$rmfiles $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" \ && test "$non_pic_object" != none; then rmfiles="$rmfiles $dir/$non_pic_object" fi fi ;; *) if test "$mode" = clean ; then noexename=$name case $file in *.exe) file=`$echo $file|${SED} 's,.exe$,,'` noexename=`$echo $name|${SED} 's,.exe$,,'` # $file with .exe has already been added to rmfiles, # add $file without .exe rmfiles="$rmfiles $file" ;; esac # Do a test to see if this is a libtool program. if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then relink_command= . $dir/$noexename # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then rmfiles="$rmfiles $objdir/lt-$name" fi if test "X$noexename" != "X$name" ; then rmfiles="$rmfiles $objdir/lt-${noexename}.c" fi fi fi ;; esac $show "$rm $rmfiles" $run $rm $rmfiles || exit_status=1 done objdir="$origobjdir" # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then $show "rmdir $dir" $run rmdir $dir >/dev/null 2>&1 fi done exit $exit_status ;; "") $echo "$modename: you must specify a MODE" 1>&2 $echo "$generic_help" 1>&2 exit $EXIT_FAILURE ;; esac if test -z "$exec_cmd"; then $echo "$modename: invalid operation mode \`$mode'" 1>&2 $echo "$generic_help" 1>&2 exit $EXIT_FAILURE fi fi # test -z "$show_help" if test -n "$exec_cmd"; then eval exec $exec_cmd exit $EXIT_FAILURE fi # We need to display help for each of the modes. case $mode in "") $echo \ "Usage: $modename [OPTION]... [MODE-ARG]... Provide generalized library-building support services. --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --finish same as \`--mode=finish' --help display this help message and exit --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] --quiet same as \`--silent' --silent don't print informational messages --tag=TAG use configuration variables from tag TAG --version print version information MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for a more detailed description of MODE. Report bugs to ." exit $EXIT_SUCCESS ;; clean) $echo \ "Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $echo \ "Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -prefer-pic try to building PIC objects only -prefer-non-pic try to building non-PIC objects only -static always build a \`.o' file suitable for static linking COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $echo \ "Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $echo \ "Usage: $modename [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $echo \ "Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $echo \ "Usage: $modename [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -static do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $echo \ "Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) $echo "$modename: invalid operation mode \`$mode'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; esac $echo $echo "Try \`$modename --help' for more information about other modes." exit $? # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: indi-0.5/indi.kdevelop0000644000175000017500000001170710605175720012600 0ustar jrjr Jasem Mutlaq mutlaqja@ikarustech.com 0.4 KDevAutoProject C++ C++ Code . false src/indi default src/indi true executable / true optimized GccOptions GppOptions G77Options -O2 -g0 --enable-debug=full debug GccOptions GppOptions G77Options -O0 -g3 false 1 false false false false false -f -dP -f -C -d -P -u3 -p ssh true true true true -C true true true false true true true 250 400 250 set m_,_ theValue true true false 3 /usr/lib/qt3 /home/slovin/Projects/indi/html/ /home/slovin/Projects/indi/html/ .h .cpp true false false false true 10 indi-0.5/README.stv0000755000175000017500000001315210542450276011616 0ustar jrjrINDI STV Driver README.stv 2006-09-10, Markus Wildi 1) Credits: The initial work is based on the program STVremote by Shashikiran Ganesh. email: gshashikiran_AT_linuxmail_dot_org. The RS 232 initialization was programmed by Lukas Zimmermann and parts of the FLI CCD driver are reused and slightly adapted. 2) Development environment: I used INDI v 0.4 and kstars 1.2. kstars versions prior to 1.2 do not work with image download on PIII 800 MHz running Linux 2.6.16.5-default. 3) Known bugs: the connection hangs sometimes. At the startup of the driver the header or data check sum may fail. This condition is displayed in the client's log window and on the terminal where the INDI server has been started. Most of the time this is not a severe error condition. If something (foreseeable) goes severely wrong the stv driver does an _exit(1). The STV does not swallow commands at any speed. At many places there are usleep() function calls in the code which fit the above mentioned hardware configuration. Because they slow down the communication these settings are good for any faster configuration but may fail on slower/older ones. In case where the communication is degraded let me know it. There are some characters used on the STV's display used in tracking mode. I need a more or less clear night to translate them to readable characters on the client's display (as far as I remember the content is still readable). 4) Feedback: markus.wildi_AT_datacomm_dot_ch 6) ToDo: Image download: Set the correct window size according the information found in image info (e.g. image_info->height). 5) Recommended hardware set up for true remote operation: Use the STV driver together with the INDI v4ldriver and a video capture card to watch the LCD screen on the local computer. 6) Status: The INDI STV driver is an experimental release. Experimental means that it may hang (despite not often). The terminal where you started the INDI server process will sometimes show messages (on stderr) which can only be understood if one reads the source code (search for parts of the message). The current version is basically a mirror of the STV's built in functions. These primitives can be used in different ways to enhance the versatility of the STV. There are two examples on the tab Settings: 1) set current time (UTC) (time may differ, because it takes a while until it is set and the seconds can only be set in steps of 15 seconds). 2) set the ccd temperature E.g. The STV forgets the time and temperature settings and they must be entered at each power up. A farther reaching example: imagine using the STV remotely and without video capture card. The focusing process of the STV might render impossible. I think an automated process together with an a INDI focuser driver should do that work autonomously. These two examples are implemented in two different ways. Time set is done "blindly". That means the buttons and the rotary knobs (better the software equivalents) are used without any feedback from the STV. The ccd temperature reads the display and stops when the desired temperature appears. 7) Before you start: If you want to use the INDI STV driver, please refer to the SBIG STV manual first. The INDI STV driver is basically a remote front end to your fingers with additional features. Please note that the buffers are labeled as 1 to 32. Buffer number 32 is the LCD screen buffer. Despite SBIG's manual says so, accessible are only buffers 1 through 14 and 32 (at least I found no way to store images e.g. in buffer 20). 8) Recommended approach: Put the STV hardware on your desk an connect it to the computer where the INDI server and client run. First do basic things like changing settings on the STV using the INDI client (tab Buttons and Knobs). Compare the results on the STV display with the results on the INDI client. The STV's two line display should be always synchronous with the INDI client display. Then try to take an image which is finally displayed on the STV's LCD screen and try to download it to the INDI client using the default settings on the tab Image Download. 9) What is not possible: A mixed operation, that is some commands entered at the STV box and some entered via the INDI STV driver, is hardly possible. There is no way how one can retrieve the current status of the STV besides monitoring the display of the STV. 10) What is not supported: The meta data of images, e.g. offset, taken in mosaic mode are not read out currently. 11) Features: STV's display is reproduced on each tab for convenience. Connection tab Set the device and the speed (9600, 19200, 38400, 57600 and 115200). Start/stop update clients display. Settings tab Set the time to UTC. Set the CCD temperature. Buttons and Knobs tab All STV's buttons and knobs are supported. Basically you can use the STV driver as if you were sitting in front of the box. The names and groups are identical to what is printed on the STV's box. The labels of up/down left/right of the rotary knobs are replaced by Increase and Decrease in both cases. Warning: Do not change the STV's speed with File Ops menu. The communication will stop. Download Buffers Status: get a quick overview which buffers are used or empty. The meta information about one image or all images are available and printed in the log window. The buffer on which the buttons One Image (Information and Download) operate on can be selected. The download of one or all images can be initiated either in un- or compressed mode. An arbitrary window can be set on the original window. This speeds the download considerably and is e.g. useful if you want to inspect a single star image. indi-0.5/README0000644000175000017500000001115210610476164010776 0ustar jrjrINDI Library v0.5 April 16, 2006 Running an INDI server ====================== Client applications communiate to INDI driver through the INDI server. Usage: indiserver [options] [driver ...] Purpose: INDI Server Options: -p p : alternate IP port, default 7624 -r n : max restart attempts, default 2 -vv : more verbose to stderr Remaining args are names of INDI drivers to run. For example, to run LX200GPS driver on port 8000, type in: indiserver -p 8000 lx200gps Different clients have different methods of connecting to the indiserver. Refer to your client documenation for more details. Developing device drivers ========================= Developers interested in developing their own device drivers under INDI should refer to the INDI Developers Manual at http://indi.sf.net/manual For driver-specific issues, refer to README.drivers Supported Devices: ================== ** Telescope + LX200 Generic + LX200 Classic + LX200 Autostar + LX200 16" + LX200 GPS + NewGT + NexStar 5i/8i + NexStar GPS, CGE, AS-GT + Astro-Physics AP + Astro-Electronic FS-2 + Losmandy Gemini + Mel Bartels Controllers + Vixen SkySensor 2000 + Argo Navis + SkyCommander + Temma Takahashi ** CCD + Finger Lakes Instruments + Apogee (Experimental) + SBIG ** Video + Any Video4Linux (V4L 1 and V4L 2) compatible camera + Philips webcam + Meade Lunar Planetary Imager (Experimental) + SBIG STV ** Focuser + Meade LX200GPS Microfocuser + Meade 1206 Primary Mirror Focuser + JMI NGF Series + JMI MOTOFOCUS + Robo Focus ** Filter Wheel + Finger Lakes Instruments filter wheel + True Technology Filter Wheel + SBIG CWF INDI Architecture and Construction ================================== The code here demonstrates the use of INDI, an Instrument-Neutral Device Interface protocol. See http://www.clearskyinstitute.com/INDI/INDI.pdf. Architecture: Typical INDI Client / Server / Driver / Device connectivity: INDI Client 1 ----| |---- INDI Driver A ---- Dev X | | INDI Client 2 ----| |---- INDI Driver B ---- Dev Y | | | ... |--- indiserver ---| |-- Dev Z | | | | INDI Client n ----| |---- INDI Driver C ---- Dev T Client INET Server UNIX Driver Hardware processes sockets process pipes processes devices Indiserver is the public network access point where one or more INDI Clients may contact one or more INDI Drivers. Indiserver launches each driver process and arranges for it to receive the INDI protocol from Clients on its stdin and expects to find commands destined for Clients on the driver's stdout. Anything arriving from a driver process' stderr is copied to indiserver's stderr. Indiserver only provides convenient port, fork and data steering services. If desired, a Client may run and connect to INDI Drivers directly. Construction: An INDI driver typically consists of one .c file, eg, mydriver.c, which #includes indiapi.h to access the reference API declarations. It is compiled then linked with indidrivermain.o, eventloop.o ,liblilxml.a, and indicom.a (optional) to form an INDI process. These supporting files contain the implementation of the INDI Driver API and need not be changed in any way. Note that evenloop.[ch] provide a nice callback facility independent of INDI which may be used in other projects if desired. The driver implementation, again in our example mydriver.c, does not contain a main() but is expected to operate as an event-driver program. The driver must implement each ISxxx() function but never call them. The IS() functions are called by the reference implementation main() as messages arrive from Clients. Within each IS function the driver performs the desired tasks then may report back to the Client by calling the IDxxx() functions. The reference API provides IE() functions to allow the driver to add its own callback functions if desired. The driver can arrange for functions to be called when reading a file descriptor will not block; when a time interval has expired; or when there is no other client traffic in progress. The sample indiserver is a stand alone process that may be used to run one or more INDI-compliant drivers. It takes the names of each driver process to run in its command line args. indi-0.5/INSTALL0000644000175000017500000000066510610476211011147 0ustar jrjrINDI Library Setup v0.5 ======================= 1) ./configure 2) make 3) su -c 'make install' Enter root password when prompted. Refer to README for instructions on running indiserver and device drivers. Refer to README.drivers for driver-specific information. INDI SVN Setup ============== If you checkout INDI from the SVN, follow the instructions above. But before ./configure, type in: make -f Makefile.cvs That's it! indi-0.5/README.robofocus0000644000175000017500000000607010605175720012777 0ustar jrjrINDI Robofocus Driver README.robofocus 2006-10-02, Markus Wildi 1) Development environment: I used INDI v 0.4 and kstars 1.2. on PIII 800 MHz running Linux 2.6.16.5-default. 2) Known bugs: There no bugs known. The RoboFocus micro controller does not check if a setting is out of the interval 0 ... ca. 65000. After a position is out of limits it does not respond to any command and must be turned off and on. 3) Feedback: markus.wildi_AT_datacomm_dot_ch 4) ToDo: Make it completely complying with the INDI standard properties. Add Temperature compensation. 5) Status: All commands listed in Appendix I of the RoboFocus manual are implemented. 6) Before you start: Read at first the RoboFocus manual at least chapter 3. Operation of RoboFocus including the description of the RoboFocus Control Program (RFCP) and Appendix I Software Commands. Directions are given as positive or negative numbers. 7) Recommended approach: Use the default settings for duty cycle, step delay and motor steps per tick (a tick is a counter increment by one). Set the back lash correction only to a non zero value in case you measured it. RoboFocus is a slow device and sometimes the position needs to be read out separately. That needs additional time. If the LED indicator became green again of given property the robofocus driver resumed normal operation regardless what happened before. 8) Features Robofocus driver provides the following features: absolute and relative movement, resetting the counter to a given position, maximum and minimum travel, backlash compensation, duty cycle, step delay, number of motor steps per counter increment (tick), the read out of the built in temperature sensor and the four output lines used to control the remote power modules (optional accessories). The settings of the RoboFocus device are polled and displayed in the corresponding fields. Connection tab Port: Set the name of the RS 232 port. The speed is fixed to 9600 baud. Power: set the four digital outputs (used for optional RoboFocus accessory) Temperature: read out of the built in temperature sensor (not a real useful device) Settings: the settings step delay and motor steps per tick determine how fast the stepper motor turns. The duty cycle is can be set to zero for a main mirror focuser setup and to a decent value for a rack and pinion focuser. Read the RoboFocus manual. Motion tab Extrema: the movement of the focuser and the position setting can be limited. Maximum travel: (to me the RoboFocus documentation is unclear.) Set register Position: set the counter to the value given in the input field. Set register Backlash: define the amount of ticks. If the back lash correction and the absolute or relative movement have opposite signs RoboFocus will move into the negative direction of the main movement at the end. Movement: set it currently to IGNORE (this is a ToDo) Position: shows the actual position. Speed, Timer: ignore them (this is a ToDo) Absolute goto: the focuser moves to the absolute position. Relative goto: the focuser moves the defined ticks (negative or positive). indi-0.5/missing0000755000175000017500000002123110605175720011512 0ustar jrjr#! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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, 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. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.3 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar ${1+"$@"} && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar ${1+"$@"} && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" ${1+"$@"} && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" ${1+"$@"} && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 indi-0.5/config.h.in0000644000175000017500000000323710610536353012143 0ustar jrjr/* config.h.in. Generated from configure.in by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_VIDEODEV2_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_USB_H /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* The symbol timezone is an int, not a function */ #undef TIMEZONE_IS_INT /* Version number of package */ #undef VERSION indi-0.5/indi.kdevelop.pcs0000644000175000017500000330377010605175720013373 0ustar jrjrPCS…F/home/slovin/Projects/indi/config.hDûAG9¼V/home/slovin/Projects/indi/src/apogee/Apn.hDòè:Bd/home/slovin/Projects/indi/src/apogee/ApnCamData.hDòç:Øx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.hDòçd¸x/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.hDòçtªx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4020HS.hDò;„œx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.hDòç…Tx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.hDòç•Fx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.hDòç¥8x/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.hDòçµ*z/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.hDòçÅz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.hDòçÕDz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.hDòçålz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.hDòçõ”x/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.hDòç¼x/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.hDòç®x/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.hDòç% x/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.hDòç5’x/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.hDòçE„x/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.hDòçUvx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.hDòçehx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.hDòçuZv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.hDòç…Lv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.hDòç•v/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.hDòç¤Äv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.hDòç´€v/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.hDòçÄ<v/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.hDòçÓøx/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.hDòçã´v/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.hDòçó¦t/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.hDòçbv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.hDòçèr/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.hDòè"¤f/home/slovin/Projects/indi/src/apogee/ApnCamTable.hDòè1ôb/home/slovin/Projects/indi/src/apogee/ApnCamera.hDòè44j/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.hDòèØÜj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.hDòèð"b/home/slovin/Projects/indi/src/apogee/ApnSerial.hDòèhj/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.hDòèHj/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.hDòè&ºb/home/slovin/Projects/indi/src/apogee/ApnUsbSys.hDòè6,\/home/slovin/Projects/indi/src/apogee/Apogee.hDòè8Rf/home/slovin/Projects/indi/src/apogee/ApogeeIoctl.hDòè8îf/home/slovin/Projects/indi/src/apogee/ApogeeLinux.hDòè9”b/home/slovin/Projects/indi/src/apogee/ApogeeUsb.hDòè=h/home/slovin/Projects/indi/src/apogee/ApogeeUsbErr.hDòèOÆl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hDòèPnh/home/slovin/Projects/indi/src/apogee/CameraIO_PCI.hDòèò`/home/slovin/Projects/indi/src/apogee/FpgaRegs.hDòè <\/home/slovin/Projects/indi/src/apogee/stdafx.hDòè ÜV/home/slovin/Projects/indi/src/apogee_ppi.hDòe!xN/home/slovin/Projects/indi/src/base64.cDòeQêN/home/slovin/Projects/indi/src/base64.hDòeV¬^/home/slovin/Projects/indi/src/celestrongps.cppDòPW:Z/home/slovin/Projects/indi/src/celestrongps.hDòPÂd/home/slovin/Projects/indi/src/celestronprotocol.cDòP˜âd/home/slovin/Projects/indi/src/celestronprotocol.hDòP×”T/home/slovin/Projects/indi/src/eventloop.cDòeØ8T/home/slovin/Projects/indi/src/eventloop.hDòeìê\/home/slovin/Projects/indi/src/fli/fli_ioctl.hDò?ït/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cDò?øt/home/slovin/Projects/indi/src/fli/libfli-camera-parport.hDò?!¾l/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cDò?<Ôl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hDò?Xüd/home/slovin/Projects/indi/src/fli/libfli-camera.cDò?t<d/home/slovin/Projects/indi/src/fli/libfli-camera.hDò?€òb/home/slovin/Projects/indi/src/fli/libfli-debug.cDò?‡*b/home/slovin/Projects/indi/src/fli/libfli-debug.hDò?ŒŽt/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.cDò?‘t/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.hDò?ž¼d/home/slovin/Projects/indi/src/fli/libfli-libfli.hDò?¥À^/home/slovin/Projects/indi/src/fli/libfli-mem.cDò?¼^/home/slovin/Projects/indi/src/fli/libfli-mem.hDò?Å2f/home/slovin/Projects/indi/src/fli/libfli-parport.hDò?ËJd/home/slovin/Projects/indi/src/fli/libfli-serial.cDò?ÍŒd/home/slovin/Projects/indi/src/fli/libfli-serial.hDò?ϼ^/home/slovin/Projects/indi/src/fli/libfli-sys.cDò?Ñì^/home/slovin/Projects/indi/src/fli/libfli-sys.hDò?à¨^/home/slovin/Projects/indi/src/fli/libfli-usb.cDò?ç&^/home/slovin/Projects/indi/src/fli/libfli-usb.hDò?éDV/home/slovin/Projects/indi/src/fli/libfli.cDò?ïBV/home/slovin/Projects/indi/src/fli/libfli.hDò?1,F/home/slovin/Projects/indi/src/fq.cDòe5ÌF/home/slovin/Projects/indi/src/fq.hDòeBdP/home/slovin/Projects/indi/src/indiapi.hDòeChP/home/slovin/Projects/indi/src/indicom.cDû@îL P/home/slovin/Projects/indi/src/indicom.hDû@î—îV/home/slovin/Projects/indi/src/indidevapi.hDòe<^/home/slovin/Projects/indi/src/indidrivermain.cDû@íŸpV/home/slovin/Projects/indi/src/indiserver.cDòtèhZ/home/slovin/Projects/indi/src/intelliscope.cDòeÊN/home/slovin/Projects/indi/src/lilxml.cDòe/8N/home/slovin/Projects/indi/src/lilxml.hDòekØV/home/slovin/Projects/indi/src/lx200_16.cppDòen,R/home/slovin/Projects/indi/src/lx200_16.hDòe~Œ`/home/slovin/Projects/indi/src/lx200autostar.cppDòe´\/home/slovin/Projects/indi/src/lx200autostar.hDòe›pZ/home/slovin/Projects/indi/src/lx200basic.cppDòe¨‚V/home/slovin/Projects/indi/src/lx200basic.hDòeÎÔ^/home/slovin/Projects/indi/src/lx200classic.cppDòeùØZ/home/slovin/Projects/indi/src/lx200classic.hDòeˆX/home/slovin/Projects/indi/src/lx200driver.cDû@î´X/home/slovin/Projects/indi/src/lx200driver.hDòe ^/home/slovin/Projects/indi/src/lx200generic.cppDòe™TZ/home/slovin/Projects/indi/src/lx200generic.hDòeå°V/home/slovin/Projects/indi/src/lx200gps.cppDòe hR/home/slovin/Projects/indi/src/lx200gps.hDòe *äZ/home/slovin/Projects/indi/src/orionatlas.cppDòe 6êV/home/slovin/Projects/indi/src/orionatlas.hDòe gâT/home/slovin/Projects/indi/src/robofocus.cDò­ ‡Z`/home/slovin/Projects/indi/src/robofocusdriver.cDò­ ¸¦`/home/slovin/Projects/indi/src/robofocusdriver.hDò­ ÛôZ/home/slovin/Projects/indi/src/sbig_dummy.cppDòe Ü”P/home/slovin/Projects/indi/src/sbigcam.hDòe Þ”R/home/slovin/Projects/indi/src/sbigudrv.hDû@í •ôZ/home/slovin/Projects/indi/src/skycommander.cDòe ÍX/home/slovin/Projects/indi/src/temmadriver.cDòe ß‚X/home/slovin/Projects/indi/src/temmadriver.hDòe n\/home/slovin/Projects/indi/src/trutech_wheel.cDû@î GÎT/home/slovin/Projects/indi/src/v4ldriver.hDòe knV/home/slovin/Projects/indi/src/v4lphilips.hDòe •xZ/home/slovin/Projects/indi/src/webcam/PPort.hDò` ­´X/home/slovin/Projects/indi/src/webcam/ccvt.hDò` ¹âd/home/slovin/Projects/indi/src/webcam/ccvt_types.hDò` ¾ºh/home/slovin/Projects/indi/src/webcam/empty_file.cppDò` ÁÖX/home/slovin/Projects/indi/src/webcam/port.hDò` Â~b/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hDò` Ö¼b/home/slovin/Projects/indi/src/webcam/v4l1_base.hDò` ù´`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.hDò` )®b/home/slovin/Projects/indi/src/webcam/v4l2_base.hDò` LLX/home/slovin/Projects/indi/src/webcam/vcvt.hDò` ‘Ü`/home/slovin/Projects/indi/src/webcam/videodev.hDò` ’tb/home/slovin/Projects/indi/src/webcam/videodev2.hDò` ÛÊF/home/slovin/Projects/indi/config.hÿÿÿÿV/home/slovin/Projects/indi/src/apogee/Apn.hÿÿÿÿd/home/slovin/Projects/indi/src/apogee/ApnCamData.hÿÿÿÿCApnCamDatad/home/slovin/Projects/indi/src/apogee/ApnCamData.h0„CApnCamDatad/home/slovin/Projects/indi/src/apogee/ApnCamData.h33CApnCamDataeÿÿÿÿInitialized/home/slovin/Projects/indi/src/apogee/ApnCamData.h66CApnCamDataÿòòÄvoidclear_hpatternd/home/slovin/Projects/indi/src/apogee/ApnCamData.h‚‚2CApnCamDataPatternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿvoidclear_vpatternd/home/slovin/Projects/indi/src/apogee/ApnCamData.hCApnCamDataÿéé€voidinit_hpatternd/home/slovin/Projects/indi/src/apogee/ApnCamData.h1CApnCamDataÿÉÉ€Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿvoidinit_vpatternd/home/slovin/Projects/indi/src/apogee/ApnCamData.h~~CApnCamDataÿôô€void~ CApnCamDatad/home/slovin/Projects/indi/src/apogee/ApnCamData.h4 4CApnCamDataÿòò€ÿÿÿÿ+m_CameraIdd/home/slovin/Projects/indi/src/apogee/ApnCamData.h<<unsigned shortm_CameraModeld/home/slovin/Projects/indi/src/apogee/ApnCamData.h::charm_ClampColumnsd/home/slovin/Projects/indi/src/apogee/ApnCamData.hFFunsigned short*m_ClampPatternSixteend/home/slovin/Projects/indi/src/apogee/ApnCamData.hss("APN_HPATTERN_FILE(m_ClampPatternTwelved/home/slovin/Projects/indi/src/apogee/ApnCamData.hww'"APN_HPATTERN_FILEm_Colord/home/slovin/Projects/indi/src/apogee/ApnCamData.h]]bool$m_CoolingSupportedd/home/slovin/Projects/indi/src/apogee/ApnCamData.hccbool,m_DefaultGainTwelveBitd/home/slovin/Projects/indi/src/apogee/ApnCamData.hkk&unsigned short0m_DefaultOffsetTwelveBitd/home/slovin/Projects/indi/src/apogee/ApnCamData.hll(unsigned short"m_DefaultRVoltaged/home/slovin/Projects/indi/src/apogee/ApnCamData.hmm!unsigned short.m_EnableSingleRowOffsetd/home/slovin/Projects/indi/src/apogee/ApnCamData.hSSboolm_HFlushDisabled/home/slovin/Projects/indi/src/apogee/ApnCamData.hVVbool m_ImagingColumnsd/home/slovin/Projects/indi/src/apogee/ApnCamData.hDD unsigned shortm_ImagingRowsd/home/slovin/Projects/indi/src/apogee/ApnCamData.hLLunsigned shortm_InterlineCCDd/home/slovin/Projects/indi/src/apogee/ApnCamData.h>>bool*m_MinSuggestedExpTimed/home/slovin/Projects/indi/src/apogee/ApnCamData.ha a double"m_OverscanColumnsd/home/slovin/Projects/indi/src/apogee/ApnCamData.hII!unsigned shortm_OverscanRowsd/home/slovin/Projects/indi/src/apogee/ApnCamData.hOOunsigned shortm_PixelSizeXd/home/slovin/Projects/indi/src/apogee/ApnCamData.hZ Z doublem_PixelSizeYd/home/slovin/Projects/indi/src/apogee/ApnCamData.h[ [ double(m_PostRoiSkipColumnsd/home/slovin/Projects/indi/src/apogee/ApnCamData.hHH$unsigned short&m_PreRoiSkipColumnsd/home/slovin/Projects/indi/src/apogee/ApnCamData.hGG#unsigned short6m_RegulatedCoolingSupportedd/home/slovin/Projects/indi/src/apogee/ApnCamData.hdd#bool0m_ReportedGainSixteenBitd/home/slovin/Projects/indi/src/apogee/ApnCamData.h_ _" double&m_RoiPatternSixteend/home/slovin/Projects/indi/src/apogee/ApnCamData.huu&"APN_HPATTERN_FILE$m_RoiPatternTwelved/home/slovin/Projects/indi/src/apogee/ApnCamData.hyy%"APN_HPATTERN_FILE$m_RowOffsetBinningd/home/slovin/Projects/indi/src/apogee/ApnCamData.hTT"unsigned shortm_Sensord/home/slovin/Projects/indi/src/apogee/ApnCamData.h99charm_SensorTypeCCDd/home/slovin/Projects/indi/src/apogee/ApnCamData.hAAbool&m_ShutterCloseDelayd/home/slovin/Projects/indi/src/apogee/ApnCamData.hXX#unsigned short(m_SkipPatternSixteend/home/slovin/Projects/indi/src/apogee/ApnCamData.htt'"APN_HPATTERN_FILE&m_SkipPatternTwelved/home/slovin/Projects/indi/src/apogee/ApnCamData.hxx&"APN_HPATTERN_FILE"m_SupportsSerialAd/home/slovin/Projects/indi/src/apogee/ApnCamData.h??bool"m_SupportsSerialBd/home/slovin/Projects/indi/src/apogee/ApnCamData.h@@bool$m_TempBackoffPointd/home/slovin/Projects/indi/src/apogee/ApnCamData.hi i double"m_TempRampRateOned/home/slovin/Projects/indi/src/apogee/ApnCamData.hgg!unsigned short"m_TempRampRateTwod/home/slovin/Projects/indi/src/apogee/ApnCamData.hhh!unsigned shortm_TempSetPointd/home/slovin/Projects/indi/src/apogee/ApnCamData.hf f doublem_TotalColumnsd/home/slovin/Projects/indi/src/apogee/ApnCamData.hCCunsigned shortm_TotalRowsd/home/slovin/Projects/indi/src/apogee/ApnCamData.hKKunsigned shortm_UnderscanRowsd/home/slovin/Projects/indi/src/apogee/ApnCamData.hNNunsigned shortm_VFlushBinningd/home/slovin/Projects/indi/src/apogee/ApnCamData.hQQunsigned short"m_VerticalPatternd/home/slovin/Projects/indi/src/apogee/ApnCamData.hqq$"APN_VPATTERN_FILE "APN_HPATTERN_FILEd/home/slovin/Projects/indi/src/apogee/ApnCamData.h--$_APN_HPATTERN_FILE "APN_VPATTERN_FILEd/home/slovin/Projects/indi/src/apogee/ApnCamData.h""$_APN_VPATTERN_FILEx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.hÿÿÿÿ*CApnCamData_CCD3011HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.h:CApnCamData *CApnCamData_CCD3011HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.h*CApnCamData_CCD3011HSÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.h""*CApnCamData_CCD3011HSvoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.h08A*CApnCamData_CCD3011HS Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.h(("*CApnCamData_CCD3011HSvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.h,,!*CApnCamData_CCD3011HSvoid0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.h** *CApnCamData_CCD3011HSvoid.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.h..*CApnCamData_CCD3011HSvoid2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.h))!*CApnCamData_CCD3011HSvoid0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.h-- *CApnCamData_CCD3011HSvoidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.h&&*CApnCamData_CCD3011HSvoid.~ CApnCamData_CCD3011HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011HS.h !*CApnCamData_CCD3011HSÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.hÿÿÿÿ*CApnCamData_CCD3011LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.h9CApnCamData *CApnCamData_CCD3011LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.h*CApnCamData_CCD3011LSÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.h!!*CApnCamData_CCD3011LSvoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.h/7A*CApnCamData_CCD3011LS] Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.h''"*CApnCamData_CCD3011LSvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.h++!*CApnCamData_CCD3011LS]void0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.h)) *CApnCamData_CCD3011LSvoid.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.h--*CApnCamData_CCD3011LS]void2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.h((!*CApnCamData_CCD3011LS]void0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.h,, *CApnCamData_CCD3011LSvoidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.h%%*CApnCamData_CCD3011LSvoid.~ CApnCamData_CCD3011LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD3011LS.h !*CApnCamData_CCD3011LSÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4020HS.hÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.hÿÿÿÿ*CApnCamData_CCD4240HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.h9CApnCamData *CApnCamData_CCD4240HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.h*CApnCamData_CCD4240HSÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.h!!*CApnCamData_CCD4240HSvoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.h/7A*CApnCamData_CCD4240HSï5€ Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.h''"*CApnCamData_CCD4240HSvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.h++!*CApnCamData_CCD4240HSvoid0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.h)) *CApnCamData_CCD4240HSvoid.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.h--*CApnCamData_CCD4240HSvoid2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.h((!*CApnCamData_CCD4240HSvoid0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.h,, *CApnCamData_CCD4240HSvoidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.h%%*CApnCamData_CCD4240HSvoid.~ CApnCamData_CCD4240HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240HS.h !*CApnCamData_CCD4240HSÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.hÿÿÿÿ*CApnCamData_CCD4240LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.h9CApnCamData *CApnCamData_CCD4240LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.h*CApnCamData_CCD4240LSÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.h!!*CApnCamData_CCD4240LSvoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.h/7A*CApnCamData_CCD4240LS „ Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.h''"*CApnCamData_CCD4240LSvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.h++!*CApnCamData_CCD4240LSivoid0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.h)) *CApnCamData_CCD4240LS/void.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.h--*CApnCamData_CCD4240LSvoid2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.h((!*CApnCamData_CCD4240LSvoid0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.h,, *CApnCamData_CCD4240LSvoidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.h%%*CApnCamData_CCD4240LSvoid.~ CApnCamData_CCD4240LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4240LS.h !*CApnCamData_CCD4240LS0ÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.hÿÿÿÿ*CApnCamData_CCD4710HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.h9CApnCamData *CApnCamData_CCD4710HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.h*CApnCamData_CCD4710HS0ÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.h!!*CApnCamData_CCD4710HSvoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.h/7A*CApnCamData_CCD4710HS )–€ Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.h''"*CApnCamData_CCD4710HS ãvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.h++!*CApnCamData_CCD4710HS7void0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.h)) *CApnCamData_CCD4710HS.void.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.h--*CApnCamData_CCD4710HSvoid2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.h((!*CApnCamData_CCD4710HSvoid0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.h,, *CApnCamData_CCD4710HSvoidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.h%%*CApnCamData_CCD4710HSvoid.~ CApnCamData_CCD4710HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710HS.h !*CApnCamData_CCD4710HSÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.hÿÿÿÿ*CApnCamData_CCD4710LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.h9CApnCamData *CApnCamData_CCD4710LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.h*CApnCamData_CCD4710LSÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.h!!*CApnCamData_CCD4710LSvoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.h/7A*CApnCamData_CCD4710LS Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.h''"*CApnCamData_CCD4710LSvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.h++!*CApnCamData_CCD4710LS¶ÛQ€void0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.h)) *CApnCamData_CCD4710LS¶ÛQ€void.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.h--*CApnCamData_CCD4710LSvoid2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.h((!*CApnCamData_CCD4710LS¶ÛQ€void0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.h,, *CApnCamData_CCD4710LSvoidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.h%%*CApnCamData_CCD4710LSvoid.~ CApnCamData_CCD4710LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS.h !*CApnCamData_CCD4710LSÿÿÿÿz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.hÿÿÿÿ,CApnCamData_CCD4710LS2z/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.h9CApnCamData ,CApnCamData_CCD4710LS2z/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.h,CApnCamData_CCD4710LS2ÿÿÿÿInitializez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.h!!,CApnCamData_CCD4710LS2voidset_hpatternz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.h/7A,CApnCamData_CCD4710LS2/ Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.h''",CApnCamData_CCD4710LS2void2set_hpattern_clamp_twelvez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.h++!,CApnCamData_CCD4710LS2void0set_hpattern_roi_sixteenz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.h)) ,CApnCamData_CCD4710LS2void.set_hpattern_roi_twelvez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.h--,CApnCamData_CCD4710LS2tvoid2set_hpattern_skip_sixteenz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.h((!,CApnCamData_CCD4710LS2ivoid0set_hpattern_skip_twelvez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.h,, ,CApnCamData_CCD4710LS2voidset_vpatternz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.h%%,CApnCamData_CCD4710LS2void0~ CApnCamData_CCD4710LS2z/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS2.h ",CApnCamData_CCD4710LS2ÿÿÿÿz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.hÿÿÿÿ,CApnCamData_CCD4710LS3z/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.h9CApnCamData ,CApnCamData_CCD4710LS3z/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.h,CApnCamData_CCD4710LS3ÿÿÿÿInitializez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.h!!,CApnCamData_CCD4710LS3voidset_hpatternz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.h/7A,CApnCamData_CCD4710LS3 Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.h''",CApnCamData_CCD4710LS3void2set_hpattern_clamp_twelvez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.h++!,CApnCamData_CCD4710LS3void0set_hpattern_roi_sixteenz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.h)) ,CApnCamData_CCD4710LS3void.set_hpattern_roi_twelvez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.h--,CApnCamData_CCD4710LS3¶ÛQ€void2set_hpattern_skip_sixteenz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.h((!,CApnCamData_CCD4710LS3void0set_hpattern_skip_twelvez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.h,, ,CApnCamData_CCD4710LS3¶ÛQ€voidset_vpatternz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.h%%,CApnCamData_CCD4710LS3void0~ CApnCamData_CCD4710LS3z/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS3.h ",CApnCamData_CCD4710LS30ÿÿÿÿz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.hÿÿÿÿ,CApnCamData_CCD4710LS4z/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.h9CApnCamData ,CApnCamData_CCD4710LS4z/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.h,CApnCamData_CCD4710LS4ÿÿÿÿInitializez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.h!!,CApnCamData_CCD4710LS4voidset_hpatternz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.h/7A,CApnCamData_CCD4710LS4 Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.h''",CApnCamData_CCD4710LS4void2set_hpattern_clamp_twelvez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.h++!,CApnCamData_CCD4710LS4ivoid0set_hpattern_roi_sixteenz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.h)) ,CApnCamData_CCD4710LS4void.set_hpattern_roi_twelvez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.h--,CApnCamData_CCD4710LS4void2set_hpattern_skip_sixteenz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.h((!,CApnCamData_CCD4710LS4void0set_hpattern_skip_twelvez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.h,, ,CApnCamData_CCD4710LS4voidset_vpatternz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.h%%,CApnCamData_CCD4710LS4void0~ CApnCamData_CCD4710LS4z/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS4.h ",CApnCamData_CCD4710LS4ÿÿÿÿz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.hÿÿÿÿ,CApnCamData_CCD4710LS5z/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.h#ACApnCamData ,CApnCamData_CCD4710LS5z/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.h&&,CApnCamData_CCD4710LS5ÿÿÿÿInitializez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.h)),CApnCamData_CCD4710LS5voidset_hpatternz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.h7?A,CApnCamData_CCD4710LS5 Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.h//",CApnCamData_CCD4710LS5void2set_hpattern_clamp_twelvez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.h33!,CApnCamData_CCD4710LS5void0set_hpattern_roi_sixteenz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.h11 ,CApnCamData_CCD4710LS5void.set_hpattern_roi_twelvez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.h55,CApnCamData_CCD4710LS5void2set_hpattern_skip_sixteenz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.h00!,CApnCamData_CCD4710LS5void0set_hpattern_skip_twelvez/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.h44 ,CApnCamData_CCD4710LS5voidset_vpatternz/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.h--,CApnCamData_CCD4710LS5void0~ CApnCamData_CCD4710LS5z/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4710LS5.h' '",CApnCamData_CCD4710LS5ÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.hÿÿÿÿ*CApnCamData_CCD4720HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.h9CApnCamData *CApnCamData_CCD4720HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.h*CApnCamData_CCD4720HSý‡ÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.h!!*CApnCamData_CCD4720HSvoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.h/7A*CApnCamData_CCD4720HS Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.h''"*CApnCamData_CCD4720HSvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.h++!*CApnCamData_CCD4720HSvoid0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.h)) *CApnCamData_CCD4720HSvoid.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.h--*CApnCamData_CCD4720HSivoid2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.h((!*CApnCamData_CCD4720HSvoid0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.h,, *CApnCamData_CCD4720HSòLvoidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.h%%*CApnCamData_CCD4720HSvoid.~ CApnCamData_CCD4720HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720HS.h !*CApnCamData_CCD4720HSiÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.hÿÿÿÿ*CApnCamData_CCD4720LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.h9CApnCamData *CApnCamData_CCD4720LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.h*CApnCamData_CCD4720LSÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.h!!*CApnCamData_CCD4720LSvoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.h/7A*CApnCamData_CCD4720LS Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.h''"*CApnCamData_CCD4720LSvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.h++!*CApnCamData_CCD4720LS¶ÛQ€void0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.h)) *CApnCamData_CCD4720LS¶ÛQ€void.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.h--*CApnCamData_CCD4720LSvoid2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.h((!*CApnCamData_CCD4720LSvoid0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.h,, *CApnCamData_CCD4720LS¶ÛQ€voidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.h%%*CApnCamData_CCD4720LSvoid.~ CApnCamData_CCD4720LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD4720LS.h !*CApnCamData_CCD4720LSÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.hÿÿÿÿ*CApnCamData_CCD5520HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.h9CApnCamData *CApnCamData_CCD5520HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.h*CApnCamData_CCD5520HSÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.h!!*CApnCamData_CCD5520HSvoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.h/7A*CApnCamData_CCD5520HS·UÇ Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.h''"*CApnCamData_CCD5520HSvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.h++!*CApnCamData_CCD5520HSvoid0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.h)) *CApnCamData_CCD5520HS5void.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.h--*CApnCamData_CCD5520HSvoid2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.h((!*CApnCamData_CCD5520HS a€void0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.h,, *CApnCamData_CCD5520HSvoidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.h%%*CApnCamData_CCD5520HSvoid.~ CApnCamData_CCD5520HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520HS.h !*CApnCamData_CCD5520HSÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.hÿÿÿÿ*CApnCamData_CCD5520LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.h9CApnCamData *CApnCamData_CCD5520LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.h*CApnCamData_CCD5520LSÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.h!!*CApnCamData_CCD5520LSvoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.h/7A*CApnCamData_CCD5520LS/ Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.h''"*CApnCamData_CCD5520LSvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.h++!*CApnCamData_CCD5520LSvoid0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.h)) *CApnCamData_CCD5520LSivoid.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.h--*CApnCamData_CCD5520LStvoid2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.h((!*CApnCamData_CCD5520LSü¨€void0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.h,, *CApnCamData_CCD5520LSvoidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.h%%*CApnCamData_CCD5520LSvoid.~ CApnCamData_CCD5520LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5520LS.h !*CApnCamData_CCD5520LSÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.hÿÿÿÿ*CApnCamData_CCD5710HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.h#ACApnCamData *CApnCamData_CCD5710HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.h&&*CApnCamData_CCD5710HSÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.h))*CApnCamData_CCD5710HSvoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.h7?A*CApnCamData_CCD5710HSýH Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.h//"*CApnCamData_CCD5710HSvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.h33!*CApnCamData_CCD5710HSvoid0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.h11 *CApnCamData_CCD5710HSvoid.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.h55*CApnCamData_CCD5710HSvoid2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.h00!*CApnCamData_CCD5710HSvoid0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.h44 *CApnCamData_CCD5710HSvoidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.h--*CApnCamData_CCD5710HSvoid.~ CApnCamData_CCD5710HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710HS.h' '!*CApnCamData_CCD5710HS0ÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.hÿÿÿÿ*CApnCamData_CCD5710LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.h9CApnCamData *CApnCamData_CCD5710LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.h*CApnCamData_CCD5710LSÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.h!!*CApnCamData_CCD5710LS0voidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.h/7A*CApnCamData_CCD5710LS/ Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.h''"*CApnCamData_CCD5710LSvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.h++!*CApnCamData_CCD5710LSvoid0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.h)) *CApnCamData_CCD5710LSvoid.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.h--*CApnCamData_CCD5710LStvoid2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.h((!*CApnCamData_CCD5710LSvoid0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.h,, *CApnCamData_CCD5710LSvoidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.h%%*CApnCamData_CCD5710LSvoid.~ CApnCamData_CCD5710LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD5710LS.h !*CApnCamData_CCD5710LSÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.hÿÿÿÿ*CApnCamData_CCD7700HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.h9CApnCamData *CApnCamData_CCD7700HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.h*CApnCamData_CCD7700HSÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.h!!*CApnCamData_CCD7700HSvoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.h/7A*CApnCamData_CCD7700HS Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.h''"*CApnCamData_CCD7700HSvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.h++!*CApnCamData_CCD7700HSvoid0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.h)) *CApnCamData_CCD7700HSvoid.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.h--*CApnCamData_CCD7700HS7void2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.h((!*CApnCamData_CCD7700HSvoid0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.h,, *CApnCamData_CCD7700HS.voidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.h%%*CApnCamData_CCD7700HSvoid.~ CApnCamData_CCD7700HSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700HS.h !*CApnCamData_CCD7700HS0ÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.hÿÿÿÿ*CApnCamData_CCD7700LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.h9CApnCamData *CApnCamData_CCD7700LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.h*CApnCamData_CCD7700LSÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.h!!*CApnCamData_CCD7700LSvoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.h/7A*CApnCamData_CCD7700LS Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.h''"*CApnCamData_CCD7700LSvoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.h++!*CApnCamData_CCD7700LSvoid0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.h)) *CApnCamData_CCD7700LSvoid.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.h--*CApnCamData_CCD7700LSvoid2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.h((!*CApnCamData_CCD7700LSvoid0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.h,, *CApnCamData_CCD7700LSivoidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.h%%*CApnCamData_CCD7700LSvoid.~ CApnCamData_CCD7700LSx/home/slovin/Projects/indi/src/apogee/ApnCamData_CCD7700LS.h !*CApnCamData_CCD7700LSÿÿÿÿv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.hÿÿÿÿ(CApnCamData_KAF0261Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.h9CApnCamData (CApnCamData_KAF0261Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.h(CApnCamData_KAF0261EFAKÿÿÿÿInitializev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.h!!(CApnCamData_KAF0261EAvoidset_hpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.h/7A(CApnCamData_KAF0261E Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.h''"(CApnCamData_KAF0261Evoid2set_hpattern_clamp_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.h++!(CApnCamData_KAF0261Evoid0set_hpattern_roi_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.h)) (CApnCamData_KAF0261E1void.set_hpattern_roi_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.h--(CApnCamData_KAF0261Evoid2set_hpattern_skip_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.h((!(CApnCamData_KAF0261Evoid0set_hpattern_skip_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.h,, (CApnCamData_KAF0261Evoidset_vpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.h%%(CApnCamData_KAF0261Evoid,~ CApnCamData_KAF0261Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0261E.h  (CApnCamData_KAF0261EOÿÿÿÿv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.hÿÿÿÿ(CApnCamData_KAF0401Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.h9CApnCamData (CApnCamData_KAF0401Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.h(CApnCamData_KAF0401EFAKÿÿÿÿInitializev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.h!!(CApnCamData_KAF0401Evoidset_hpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.h/7A(CApnCamData_KAF0401E·UÇ Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.h''"(CApnCamData_KAF0401Evoid2set_hpattern_clamp_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.h++!(CApnCamData_KAF0401Evoid0set_hpattern_roi_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.h)) (CApnCamData_KAF0401Evoid.set_hpattern_roi_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.h--(CApnCamData_KAF0401Evoid2set_hpattern_skip_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.h((!(CApnCamData_KAF0401Evoid0set_hpattern_skip_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.h,, (CApnCamData_KAF0401Evoidset_vpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.h%%(CApnCamData_KAF0401Evoid,~ CApnCamData_KAF0401Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF0401E.h  (CApnCamData_KAF0401Eÿÿÿÿv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.hÿÿÿÿ(CApnCamData_KAF1001Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.h9CApnCamData (CApnCamData_KAF1001Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.h(CApnCamData_KAF1001EFAKÿÿÿÿInitializev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.h!!(CApnCamData_KAF1001Eivoidset_hpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.h/7A(CApnCamData_KAF1001Ei Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.h''"(CApnCamData_KAF1001E1void2set_hpattern_clamp_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.h++!(CApnCamData_KAF1001Evoid0set_hpattern_roi_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.h)) (CApnCamData_KAF1001Evoid.set_hpattern_roi_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.h--(CApnCamData_KAF1001E €void2set_hpattern_skip_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.h((!(CApnCamData_KAF1001Evoid0set_hpattern_skip_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.h,, (CApnCamData_KAF1001Evoidset_vpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.h%%(CApnCamData_KAF1001Evoid,~ CApnCamData_KAF1001Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1001E.h  (CApnCamData_KAF1001EOÿÿÿÿv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.hÿÿÿÿ(CApnCamData_KAF1301Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.h9CApnCamData (CApnCamData_KAF1301Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.h(CApnCamData_KAF1301EFAKÿÿÿÿInitializev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.h!!(CApnCamData_KAF1301Evoidset_hpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.h/7A(CApnCamData_KAF1301E Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.h''"(CApnCamData_KAF1301E1void2set_hpattern_clamp_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.h++!(CApnCamData_KAF1301Evoid0set_hpattern_roi_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.h)) (CApnCamData_KAF1301Evoid.set_hpattern_roi_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.h--(CApnCamData_KAF1301Evoid2set_hpattern_skip_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.h((!(CApnCamData_KAF1301Evoid0set_hpattern_skip_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.h,, (CApnCamData_KAF1301Evoidset_vpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.h%%(CApnCamData_KAF1301Evoid,~ CApnCamData_KAF1301Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1301E.h  (CApnCamData_KAF1301Eÿÿÿÿv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.hÿÿÿÿ(CApnCamData_KAF1401Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.h9CApnCamData (CApnCamData_KAF1401Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.h(CApnCamData_KAF1401EFAKÿÿÿÿInitializev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.h!!(CApnCamData_KAF1401EAvoidset_hpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.h/7A(CApnCamData_KAF1401E Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.h''"(CApnCamData_KAF1401Eõ÷void2set_hpattern_clamp_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.h++!(CApnCamData_KAF1401Evoid0set_hpattern_roi_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.h)) (CApnCamData_KAF1401E1void.set_hpattern_roi_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.h--(CApnCamData_KAF1401Evoid2set_hpattern_skip_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.h((!(CApnCamData_KAF1401Evoid0set_hpattern_skip_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.h,, (CApnCamData_KAF1401Evoidset_vpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.h%%(CApnCamData_KAF1401Eivoid,~ CApnCamData_KAF1401Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1401E.h  (CApnCamData_KAF1401EOÿÿÿÿv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.hÿÿÿÿ(CApnCamData_KAF1602Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.h9CApnCamData (CApnCamData_KAF1602Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.h(CApnCamData_KAF1602EFAKÿÿÿÿInitializev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.h!!(CApnCamData_KAF1602Evoidset_hpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.h/7A(CApnCamData_KAF1602E·UÇ Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.h''"(CApnCamData_KAF1602E2void2set_hpattern_clamp_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.h++!(CApnCamData_KAF1602Evoid0set_hpattern_roi_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.h)) (CApnCamData_KAF1602Evoid.set_hpattern_roi_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.h--(CApnCamData_KAF1602Evoid2set_hpattern_skip_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.h((!(CApnCamData_KAF1602Evoid0set_hpattern_skip_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.h,, (CApnCamData_KAF1602Evoidset_vpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.h%%(CApnCamData_KAF1602Evoid,~ CApnCamData_KAF1602Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF1602E.h  (CApnCamData_KAF1602Eÿÿÿÿx/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.hÿÿÿÿ*CApnCamData_KAF16801Ex/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.h9CApnCamData *CApnCamData_KAF16801Ex/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.h*CApnCamData_KAF16801EÿÿÿÿInitializex/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.h!!*CApnCamData_KAF16801Evoidset_hpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.h/7A*CApnCamData_KAF16801E Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.h''"*CApnCamData_KAF16801Evoid2set_hpattern_clamp_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.h++!*CApnCamData_KAF16801Evoid0set_hpattern_roi_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.h)) *CApnCamData_KAF16801Evoid.set_hpattern_roi_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.h--*CApnCamData_KAF16801Evoid2set_hpattern_skip_sixteenx/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.h((!*CApnCamData_KAF16801Evoid0set_hpattern_skip_twelvex/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.h,, *CApnCamData_KAF16801Evoidset_vpatternx/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.h%%*CApnCamData_KAF16801Evoid.~ CApnCamData_KAF16801Ex/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF16801E.h !*CApnCamData_KAF16801Eÿÿÿÿv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.hÿÿÿÿ(CApnCamData_KAF3200Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.h9CApnCamData (CApnCamData_KAF3200Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.h(CApnCamData_KAF3200EFAKÿÿÿÿInitializev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.h!!(CApnCamData_KAF3200Evoidset_hpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.h/7A(CApnCamData_KAF3200E Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.h''"(CApnCamData_KAF3200Evoid2set_hpattern_clamp_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.h++!(CApnCamData_KAF3200Evoid0set_hpattern_roi_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.h)) (CApnCamData_KAF3200Evoid.set_hpattern_roi_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.h--(CApnCamData_KAF3200Evoid2set_hpattern_skip_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.h((!(CApnCamData_KAF3200Evoid0set_hpattern_skip_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.h,, (CApnCamData_KAF3200Evoidset_vpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.h%%(CApnCamData_KAF3200Evoid,~ CApnCamData_KAF3200Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF3200E.h  (CApnCamData_KAF3200Eÿÿÿÿt/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.hÿÿÿÿ&CApnCamData_KAF4202t/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.h9CApnCamData &CApnCamData_KAF4202t/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.h&CApnCamData_KAF4202FAKÿÿÿÿInitializet/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.h!!&CApnCamData_KAF4202FAKvoidset_hpatternt/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.h/7A&CApnCamData_KAF4202t Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteent/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.h''"&CApnCamData_KAF4202void2set_hpattern_clamp_twelvet/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.h++!&CApnCamData_KAF4202void0set_hpattern_roi_sixteent/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.h)) &CApnCamData_KAF4202void.set_hpattern_roi_twelvet/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.h--&CApnCamData_KAF4202void2set_hpattern_skip_sixteent/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.h((!&CApnCamData_KAF4202void0set_hpattern_skip_twelvet/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.h,, &CApnCamData_KAF4202voidset_vpatternt/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.h%%&CApnCamData_KAF4202void*~ CApnCamData_KAF4202t/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF4202.h &CApnCamData_KAF4202FAKÿÿÿÿv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.hÿÿÿÿ(CApnCamData_KAF6303Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.h9CApnCamData (CApnCamData_KAF6303Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.h(CApnCamData_KAF6303EFAKÿÿÿÿInitializev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.h!!(CApnCamData_KAF6303Evoidset_hpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.h/7A(CApnCamData_KAF6303E Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.h''"(CApnCamData_KAF6303Evoid2set_hpattern_clamp_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.h++!(CApnCamData_KAF6303Evoid0set_hpattern_roi_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.h)) (CApnCamData_KAF6303Evoid.set_hpattern_roi_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.h--(CApnCamData_KAF6303Evoid2set_hpattern_skip_sixteenv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.h((!(CApnCamData_KAF6303Evoid0set_hpattern_skip_twelvev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.h,, (CApnCamData_KAF6303Evoidset_vpatternv/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.h%%(CApnCamData_KAF6303E3void,~ CApnCamData_KAF6303Ev/home/slovin/Projects/indi/src/apogee/ApnCamData_KAF6303E.h  (CApnCamData_KAF6303Eÿÿÿÿr/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.hÿÿÿÿ$CApnCamData_TH7899r/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.h9CApnCamData $CApnCamData_TH7899r/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.h$CApnCamData_TH78997HTÿÿÿÿInitializer/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.h!!$CApnCamData_TH7899voidset_hpatternr/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.h/7A$CApnCamData_TH7899 ¸€ Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿMaskÿÿÿÿunsigned shortÿÿÿÿBinningLimitÿÿÿÿunsigned shortÿÿÿÿRefNumElementsÿÿÿÿunsigned shortÿÿÿÿSigNumElementsÿÿÿÿunsigned shortÿÿÿÿ BinNumElements[]ÿÿÿÿunsigned shortÿÿÿÿ RefPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ SigPatternData[]ÿÿÿÿunsigned shortÿÿÿÿ$BinPatternData[][]ÿÿÿÿunsigned shortÿÿÿÿvoid4set_hpattern_clamp_sixteenr/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.h''"$CApnCamData_TH7899void2set_hpattern_clamp_twelver/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.h++!$CApnCamData_TH7899void0set_hpattern_roi_sixteenr/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.h)) $CApnCamData_TH7899void.set_hpattern_roi_twelver/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.h--$CApnCamData_TH7899void2set_hpattern_skip_sixteenr/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.h((!$CApnCamData_TH7899.void0set_hpattern_skip_twelver/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.h,, $CApnCamData_TH7899voidset_vpatternr/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.h%%$CApnCamData_TH7899void(~ CApnCamData_TH7899r/home/slovin/Projects/indi/src/apogee/ApnCamData_TH7899.h $CApnCamData_TH7899ÿÿÿÿf/home/slovin/Projects/indi/src/apogee/ApnCamTable.hÿÿÿÿ"ApnCamModelLookupf/home/slovin/Projects/indi/src/apogee/ApnCamTable.h„„Z Z CamIdÿÿÿÿunsigned shortÿÿÿÿInterfaceÿÿÿÿunsigned shortÿÿÿÿszCamModelÿÿÿÿ char*ÿÿÿÿvoidb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÿÿÿÿCApnCamerab/home/slovin/Projects/indi/src/apogee/ApnCamera.h?NhBufferDriftScanb/home/slovin/Projects/indi/src/apogee/ApnCamera.hnnXCApnCamerabufferNameÿÿÿÿ char*ÿÿÿÿ delayÿÿÿÿintÿÿÿÿrowCountÿÿÿÿintÿÿÿÿ nblockÿÿÿÿintÿÿÿÿ npipeÿÿÿÿintÿÿÿÿboolBufferImageb/home/slovin/Projects/indi/src/apogee/ApnCamera.hmm$CApnCamera + bufferNameÿÿÿÿ char*ÿÿÿÿboolCApnCamerab/home/slovin/Projects/indi/src/apogee/ApnCamera.hBB CApnCameraaÿÿÿÿCloseDriverb/home/slovin/Projects/indi/src/apogee/ApnCamera.hIICApnCamerabool Exposeb/home/slovin/Projects/indi/src/apogee/ApnCamera.hll+CApnCameraADurationÿÿÿÿ doubleÿÿÿÿ Lightÿÿÿÿboolÿÿÿÿbool$GetExposurePixelsHb/home/slovin/Projects/indi/src/apogee/ApnCamera.hvv%CApnCamera€unsigned short$GetExposurePixelsVb/home/slovin/Projects/indi/src/apogee/ApnCamera.hww%CApnCameraunsigned shortGetImageDatab/home/slovin/Projects/indi/src/apogee/ApnCamera.hMP!CApnCamerapImageDataÿÿÿÿunsigned short*ÿÿÿÿ Widthÿÿÿÿunsigned short&ÿÿÿÿ Heightÿÿÿÿunsigned short&ÿÿÿÿ Countÿÿÿÿunsigned long&ÿÿÿÿboolGetLineDatab/home/slovin/Projects/indi/src/apogee/ApnCamera.hRSCApnCamera ÏpLineBufferÿÿÿÿunsigned short*ÿÿÿÿSizeÿÿÿÿunsigned short&ÿÿÿÿboolImageReadyb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÕ ÕCApnCameraboolInitDefaultsb/home/slovin/Projects/indi/src/apogee/ApnCamera.hjjCApnCamera +€longInitDriverb/home/slovin/Projects/indi/src/apogee/ApnCamera.hEGCApnCamera o€ CamIdAÿÿÿÿunsigned longÿÿÿÿ CamIdBÿÿÿÿunsigned shortÿÿÿÿ Optionÿÿÿÿunsigned longÿÿÿÿboolInitTwelveBitADb/home/slovin/Projects/indi/src/apogee/ApnCamera.hññCApnCamera +u€long LoadClampPatternb/home/slovin/Projects/indi/src/apogee/ApnCamera.hééCApnCamera +„€longLoadRoiPatternb/home/slovin/Projects/indi/src/apogee/ApnCamera.hëë.CApnCameraBinningÿÿÿÿunsigned shortÿÿÿÿlongLoadSkipPatternb/home/slovin/Projects/indi/src/apogee/ApnCamera.hêêCApnCamera€long&LoadVerticalPatternb/home/slovin/Projects/indi/src/apogee/ApnCamera.hèèCApnCamera +Ž€longPauseTimerb/home/slovin/Projects/indi/src/apogee/ApnCamera.hss#CApnCamerapPauseStateÿÿÿÿboolÿÿÿÿbool PostStopExposureb/home/slovin/Projects/indi/src/apogee/ApnCamera.hKK+CApnCameraDigitizeDataÿÿÿÿboolÿÿÿÿlongPreStartExposeb/home/slovin/Projects/indi/src/apogee/ApnCamera.hJJ3CApnCamera $BitsPerPixelÿÿÿÿunsigned shortÿÿÿÿlongQueryStatusRegsb/home/slovin/Projects/indi/src/apogee/ApnCamera.h`f+CApnCameraStatusRegÿÿÿÿunsigned short&ÿÿÿÿHeatsinkTempRegÿÿÿÿunsigned short&ÿÿÿÿCcdTempRegÿÿÿÿunsigned short&ÿÿÿÿCoolerDriveRegÿÿÿÿunsigned short&ÿÿÿÿVoltageRegÿÿÿÿunsigned short&ÿÿÿÿTdiCounterÿÿÿÿunsigned short&ÿÿÿÿSequenceCounterÿÿÿÿunsigned short&ÿÿÿÿlongReadb/home/slovin/Projects/indi/src/apogee/ApnCamera.hUU5CApnCameraregÿÿÿÿunsigned shortÿÿÿÿvalÿÿÿÿunsigned short&ÿÿÿÿlongResetSystemb/home/slovin/Projects/indi/src/apogee/ApnCamera.hrrCApnCamera€bool,SetNetworkTransferModeb/home/slovin/Projects/indi/src/apogee/ApnCamera.hh hCCApnCameraÿÿÿ€TransferModeÿÿÿÿApn_NetworkModeÿÿÿÿvoid"SignalImagingDoneb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÖ ÖCApnCamera€voidStopExposureb/home/slovin/Projects/indi/src/apogee/ApnCamera.hpp'CApnCamera +€DigitizeDataÿÿÿÿboolÿÿÿÿbool&UpdateGeneralStatusb/home/slovin/Projects/indi/src/apogee/ApnCamera.hôôCApnCameravoid Writeb/home/slovin/Projects/indi/src/apogee/ApnCamera.hVV5CApnCamera Óregÿÿÿÿunsigned shortÿÿÿÿvalÿÿÿÿunsigned shortÿÿÿÿlong,WriteHorizontalPatternb/home/slovin/Projects/indi/src/apogee/ApnCamera.híï!CApnCamera +€Patternÿÿÿÿ$APN_HPATTERN_FILE*ÿÿÿÿregÿÿÿÿunsigned shortÿÿÿÿbinningÿÿÿÿunsigned shortÿÿÿÿlongWriteMultiMRMDb/home/slovin/Projects/indi/src/apogee/ApnCamera.h\^CApnCamera reg[]ÿÿÿÿunsigned shortÿÿÿÿ val[]ÿÿÿÿunsigned shortÿÿÿÿ countÿÿÿÿunsigned shortÿÿÿÿlongWriteMultiSRMDb/home/slovin/Projects/indi/src/apogee/ApnCamera.hXZCApnCameraregÿÿÿÿunsigned shortÿÿÿÿ val[]ÿÿÿÿunsigned shortÿÿÿÿ countÿÿÿÿunsigned shortÿÿÿÿlong(WriteTwelveBitOffsetb/home/slovin/Projects/indi/src/apogee/ApnCamera.hòòCApnCamera€long(read_AvailableMemoryb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÉ ÉCApnCamera +u€longread_CameraModeb/home/slovin/Projects/indi/src/apogee/ApnCamera.h‰‰"CApnCameraApn_CameraMode.read_CoolerBackoffPointb/home/slovin/Projects/indi/src/apogee/ApnCamera.hš š$CApnCamera +A double read_CoolerDriveb/home/slovin/Projects/indi/src/apogee/ApnCamera.hœ œCApnCamera double"read_CoolerEnableb/home/slovin/Projects/indi/src/apogee/ApnCamera.h• •CApnCamera€bool&read_CoolerSetPointb/home/slovin/Projects/indi/src/apogee/ApnCamera.h˜ ˜ CApnCamera double"read_CoolerStatusb/home/slovin/Projects/indi/src/apogee/ApnCamera.h——%CApnCameraÿÿÿ€ Apn_CoolerStatus&read_DisableShutterb/home/slovin/Projects/indi/src/apogee/ApnCamera.h} }CApnCamerabool,read_ExternalIoReadoutb/home/slovin/Projects/indi/src/apogee/ApnCamera.h„ „!CApnCameraboolread_FanModeb/home/slovin/Projects/indi/src/apogee/ApnCamera.hŸŸCApnCameraApn_FanMode"read_FastSequenceb/home/slovin/Projects/indi/src/apogee/ApnCamera.h† †CApnCamera€bool(read_FirmwareVersionb/home/slovin/Projects/indi/src/apogee/ApnCamera.hzz'CApnCamera +€unsigned short*read_ForceShutterOpenb/home/slovin/Projects/indi/src/apogee/ApnCamera.h  CApnCamerarboolread_ImageCountb/home/slovin/Projects/indi/src/apogee/ApnCamera.hµµ"CApnCamera€unsigned short$read_ImagingStatusb/home/slovin/Projects/indi/src/apogee/ApnCamera.hŽŽ"CApnCameraApn_Status"read_InputVoltageb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÈ ÈCApnCamera +m€ double*read_IoPortAssignmentb/home/slovin/Projects/indi/src/apogee/ApnCamera.h¾¾(CApnCamera +kunsigned shortread_IoPortDatab/home/slovin/Projects/indi/src/apogee/ApnCamera.hÂÂ"CApnCamera +@unsigned short(read_IoPortDirectionb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÀÀ'CApnCameraunsigned shortread_LedModeb/home/slovin/Projects/indi/src/apogee/ApnCamera.hCApnCamera Ù€Apn_LedModeread_LedStateb/home/slovin/Projects/indi/src/apogee/ApnCamera.h’’4CApnCamera€ LedIdÿÿÿÿunsigned shortÿÿÿÿApn_LedState read_MaxBinningVb/home/slovin/Projects/indi/src/apogee/ApnCamera.h© ©2CApnCameraunsigned short(read_MaxExposureTimeb/home/slovin/Projects/indi/src/apogee/ApnCamera.hË Ë!CApnCamera +v€ double0read_NetworkTransferModeb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÍÍ,CApnCamera +w€Apn_NetworkMode(read_OverscanColumnsb/home/slovin/Projects/indi/src/apogee/ApnCamera.hªª'CApnCameraunsigned shortread_Presentb/home/slovin/Projects/indi/src/apogee/ApnCamera.hy yCApnCamera€bool(read_SequenceCounterb/home/slovin/Projects/indi/src/apogee/ApnCamera.h¸¸'CApnCamera +cunsigned short$read_SequenceDelayb/home/slovin/Projects/indi/src/apogee/ApnCamera.h± ±CApnCamera€ double,read_ShutterAmpControlb/home/slovin/Projects/indi/src/apogee/ApnCamera.h !CApnCamera€bool"read_ShutterStateb/home/slovin/Projects/indi/src/apogee/ApnCamera.h| |CApnCamerabool0read_ShutterStrobePeriodb/home/slovin/Projects/indi/src/apogee/ApnCamera.h® ®%CApnCamera æ double4read_ShutterStrobePositionb/home/slovin/Projects/indi/src/apogee/ApnCamera.h¬ ¬'CApnCamera€ doubleread_TDICounterb/home/slovin/Projects/indi/src/apogee/ApnCamera.h¹¹"CApnCamera +c€unsigned shortread_TDIRateb/home/slovin/Projects/indi/src/apogee/ApnCamera.h¼ ¼CApnCamera doubleread_TDIRowsb/home/slovin/Projects/indi/src/apogee/ApnCamera.hººCApnCamera +dunsigned shortread_TempCCDb/home/slovin/Projects/indi/src/apogee/ApnCamera.h CApnCamera +B€ double"read_TempHeatsinkb/home/slovin/Projects/indi/src/apogee/ApnCamera.hž žCApnCamera +F double,read_TestLedBrightnessb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÐ Ð#CApnCamera +{€ double$read_TwelveBitGainb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÅÅ%CApnCamera +qunsigned short4read_VariableSequenceDelayb/home/slovin/Projects/indi/src/apogee/ApnCamera.h³ ³%CApnCamera +]boolsensorInfob/home/slovin/Projects/indi/src/apogee/ApnCamera.h,,CApnCamera +®bool write_CameraModeb/home/slovin/Projects/indi/src/apogee/ApnCamera.hŠ Š6CApnCameraCameraModeÿÿÿÿApn_CameraModeÿÿÿÿvoid0write_CoolerBackoffPointb/home/slovin/Projects/indi/src/apogee/ApnCamera.h› ›8CApnCamera +@BackoffPointÿÿÿÿ doubleÿÿÿÿvoid$write_CoolerEnableb/home/slovin/Projects/indi/src/apogee/ApnCamera.h– –0CApnCamera #CoolerEnableÿÿÿÿboolÿÿÿÿvoid(write_CoolerSetPointb/home/slovin/Projects/indi/src/apogee/ApnCamera.h™ ™0CApnCamera +>€SetPointÿÿÿÿ doubleÿÿÿÿvoidwrite_DataBitsb/home/slovin/Projects/indi/src/apogee/ApnCamera.hŒ Œ7CApnCamera‚€BitResolutionÿÿÿÿApn_Resolutionÿÿÿÿvoid(write_DisableShutterb/home/slovin/Projects/indi/src/apogee/ApnCamera.h~ ~4CApnCamera DisableShutterÿÿÿÿboolÿÿÿÿvoid.write_ExternalIoReadoutb/home/slovin/Projects/indi/src/apogee/ApnCamera.h… …:CApnCamera"ExternalIoReadoutÿÿÿÿboolÿÿÿÿvoidwrite_FanModeb/home/slovin/Projects/indi/src/apogee/ApnCamera.h   -CApnCameraeFanModeÿÿÿÿApn_FanModeÿÿÿÿvoid$write_FastSequenceb/home/slovin/Projects/indi/src/apogee/ApnCamera.h‡ ‡0CApnCameraFastSequenceÿÿÿÿboolÿÿÿÿvoid,write_ForceShutterOpenb/home/slovin/Projects/indi/src/apogee/ApnCamera.h€ €8CApnCamera  ForceShutterOpenÿÿÿÿboolÿÿÿÿvoid write_ImageCountb/home/slovin/Projects/indi/src/apogee/ApnCamera.h¶ ¶1CApnCamera Countÿÿÿÿunsigned shortÿÿÿÿvoid,write_IoPortAssignmentb/home/slovin/Projects/indi/src/apogee/ApnCamera.h¿ ¿BCApnCamera IoPortAssignmentÿÿÿÿunsigned shortÿÿÿÿvoid write_IoPortDatab/home/slovin/Projects/indi/src/apogee/ApnCamera.hà Ã6CApnCameraIoPortDataÿÿÿÿunsigned shortÿÿÿÿvoid*write_IoPortDirectionb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÁ Á@CApnCamera +m€IoPortDirectionÿÿÿÿunsigned shortÿÿÿÿvoidwrite_LedModeb/home/slovin/Projects/indi/src/apogee/ApnCamera.h‘ ‘-CApnCameraLedModeÿÿÿÿApn_LedModeÿÿÿÿvoidwrite_LedStateb/home/slovin/Projects/indi/src/apogee/ApnCamera.h“ “FCApnCamera LedIdÿÿÿÿunsigned shortÿÿÿÿLedStateÿÿÿÿApn_LedStateÿÿÿÿvoid2write_NetworkTransferModeb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÎ ÎBCApnCamera€TransferModeÿÿÿÿApn_NetworkModeÿÿÿÿvoid"write_RoiBinningHb/home/slovin/Projects/indi/src/apogee/ApnCamera.h¢ ¢5CApnCamera +LBinningHÿÿÿÿunsigned shortÿÿÿÿvoid"write_RoiBinningVb/home/slovin/Projects/indi/src/apogee/ApnCamera.h£ £5CApnCameraBinningVÿÿÿÿunsigned shortÿÿÿÿvoid write_RoiPixelsVb/home/slovin/Projects/indi/src/apogee/ApnCamera.h¥ ¥3CApnCamera +NPixelsVÿÿÿÿunsigned shortÿÿÿÿvoidwrite_RoiStartYb/home/slovin/Projects/indi/src/apogee/ApnCamera.h§ §1CApnCamera StartYÿÿÿÿunsigned shortÿÿÿÿvoid&write_SequenceDelayb/home/slovin/Projects/indi/src/apogee/ApnCamera.h² ²,CApnCamera Delayÿÿÿÿ doubleÿÿÿÿvoid.write_ShutterAmpControlb/home/slovin/Projects/indi/src/apogee/ApnCamera.h‚ ‚:CApnCamera‚€"ShutterAmpControlÿÿÿÿboolÿÿÿÿvoid2write_ShutterStrobePeriodb/home/slovin/Projects/indi/src/apogee/ApnCamera.h¯ ¯3CApnCameras Periodÿÿÿÿ doubleÿÿÿÿvoid6write_ShutterStrobePositionb/home/slovin/Projects/indi/src/apogee/ApnCamera.h­ ­7CApnCamera[Positionÿÿÿÿ doubleÿÿÿÿvoidwrite_TDIRateb/home/slovin/Projects/indi/src/apogee/ApnCamera.h½ ½(CApnCameraTdiRateÿÿÿÿ doubleÿÿÿÿvoidwrite_TDIRowsb/home/slovin/Projects/indi/src/apogee/ApnCamera.h» »0CApnCamera +c€TdiRowsÿÿÿÿunsigned shortÿÿÿÿvoid.write_TestLedBrightnessb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÑ Ñ<CApnCamera +z€"TestLedBrightnessÿÿÿÿ doubleÿÿÿÿvoid&write_TwelveBitGainb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÆ Æ<CApnCamera +r€TwelveBitGainÿÿÿÿunsigned shortÿÿÿÿvoid6write_VariableSequenceDelayb/home/slovin/Projects/indi/src/apogee/ApnCamera.h´ ´BCApnCamera*VariableSequenceDelayÿÿÿÿboolÿÿÿÿvoid~ CApnCamerab/home/slovin/Projects/indi/src/apogee/ApnCamera.hCCCApnCameraaÿÿÿÿJm_ApnSensorInfob/home/slovin/Projects/indi/src/apogee/ApnCamera.hÜÜCApnCamData*m_CameraIdb/home/slovin/Projects/indi/src/apogee/ApnCamera.h//unsigned short"m_CameraInterfaceb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÚÚ Apn_Interfacem_CameraModelb/home/slovin/Projects/indi/src/apogee/ApnCamera.h..charm_ClampColumnsb/home/slovin/Projects/indi/src/apogee/ApnCamera.h66unsigned shortm_Colorb/home/slovin/Projects/indi/src/apogee/ApnCamera.hCCboolm_DataBitsb/home/slovin/Projects/indi/src/apogee/ApnCamera.hããApn_Resolution,m_DefaultGainTwelveBitb/home/slovin/Projects/indi/src/apogee/ApnCamera.hJJ&unsigned short0m_DefaultOffsetTwelveBitb/home/slovin/Projects/indi/src/apogee/ApnCamera.hKK(unsigned short"m_DefaultRVoltageb/home/slovin/Projects/indi/src/apogee/ApnCamera.hLL!unsigned short$m_DigitizeOverscanb/home/slovin/Projects/indi/src/apogee/ApnCamera.hââboolm_HFlushDisableb/home/slovin/Projects/indi/src/apogee/ApnCamera.h??bool m_ImagingColumnsb/home/slovin/Projects/indi/src/apogee/ApnCamera.h55 unsigned shortm_ImagingRowsb/home/slovin/Projects/indi/src/apogee/ApnCamera.h;;unsigned shortm_InterlineCCDb/home/slovin/Projects/indi/src/apogee/ApnCamera.h00bool*m_MinSuggestedExpTimeb/home/slovin/Projects/indi/src/apogee/ApnCamera.hF F double"m_OverscanColumnsb/home/slovin/Projects/indi/src/apogee/ApnCamera.h99!unsigned shortm_OverscanRowsb/home/slovin/Projects/indi/src/apogee/ApnCamera.h==unsigned shortm_PixelSizeXb/home/slovin/Projects/indi/src/apogee/ApnCamera.hA A doublem_PixelSizeYb/home/slovin/Projects/indi/src/apogee/ApnCamera.hB B double(m_PostRoiSkipColumnsb/home/slovin/Projects/indi/src/apogee/ApnCamera.h88$unsigned short&m_PreRoiSkipColumnsb/home/slovin/Projects/indi/src/apogee/ApnCamera.h77#unsigned short0m_ReportedGainSixteenBitb/home/slovin/Projects/indi/src/apogee/ApnCamera.hE E! double*m_ResetVerticalArraysb/home/slovin/Projects/indi/src/apogee/ApnCamera.h÷÷boolm_RoiBinningHb/home/slovin/Projects/indi/src/apogee/ApnCamera.hààunsigned shortm_RoiBinningVb/home/slovin/Projects/indi/src/apogee/ApnCamera.hàà,unsigned shortm_RoiPixelsHb/home/slovin/Projects/indi/src/apogee/ApnCamera.hßßunsigned shortm_RoiPixelsVb/home/slovin/Projects/indi/src/apogee/ApnCamera.hßß*unsigned shortm_RoiStartXb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÞÞunsigned shortm_RoiStartYb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÞÞ(unsigned shortm_Sensorb/home/slovin/Projects/indi/src/apogee/ApnCamera.h--charm_SensorTypeCCDb/home/slovin/Projects/indi/src/apogee/ApnCamera.h33bool&m_ShutterCloseDelayb/home/slovin/Projects/indi/src/apogee/ApnCamera.h@@#unsigned short"m_SupportsSerialAb/home/slovin/Projects/indi/src/apogee/ApnCamera.h11bool"m_SupportsSerialBb/home/slovin/Projects/indi/src/apogee/ApnCamera.h22bool"m_TempRampRateOneb/home/slovin/Projects/indi/src/apogee/ApnCamera.hHH!unsigned short"m_TempRampRateTwob/home/slovin/Projects/indi/src/apogee/ApnCamera.hII!unsigned shortm_TotalColumnsb/home/slovin/Projects/indi/src/apogee/ApnCamera.h44unsigned shortm_TotalRowsb/home/slovin/Projects/indi/src/apogee/ApnCamera.h::unsigned shortm_UnderscanRowsb/home/slovin/Projects/indi/src/apogee/ApnCamera.h<<unsigned shortm_VFlushBinningb/home/slovin/Projects/indi/src/apogee/ApnCamera.h>>unsigned short"m_pvtBitsPerPixelb/home/slovin/Projects/indi/src/apogee/ApnCamera.h&&!unsigned shortm_pvtCameraModeb/home/slovin/Projects/indi/src/apogee/ApnCamera.húúApn_CameraMode.m_pvtCoolerBackoffPointb/home/slovin/Projects/indi/src/apogee/ApnCamera.h ! double m_pvtCoolerDriveb/home/slovin/Projects/indi/src/apogee/ApnCamera.h  double"m_pvtCoolerEnableb/home/slovin/Projects/indi/src/apogee/ApnCamera.hbool"m_pvtCoolerStatusb/home/slovin/Projects/indi/src/apogee/ApnCamera.h# Apn_CoolerStatus&m_pvtCurrentCcdTempb/home/slovin/Projects/indi/src/apogee/ApnCamera.h  double0m_pvtCurrentHeatsinkTempb/home/slovin/Projects/indi/src/apogee/ApnCamera.h " double(m_pvtExposurePixelsHb/home/slovin/Projects/indi/src/apogee/ApnCamera.h$unsigned short(m_pvtExposurePixelsVb/home/slovin/Projects/indi/src/apogee/ApnCamera.h&:unsigned shortm_pvtFanModeb/home/slovin/Projects/indi/src/apogee/ApnCamera.hApn_FanModem_pvtHeightb/home/slovin/Projects/indi/src/apogee/ApnCamera.h((unsigned shortm_pvtImageCountb/home/slovin/Projects/indi/src/apogee/ApnCamera.hþþunsigned short(m_pvtImageInProgressb/home/slovin/Projects/indi/src/apogee/ApnCamera.h boolm_pvtImageReadyb/home/slovin/Projects/indi/src/apogee/ApnCamera.h bool$m_pvtImagingStatusb/home/slovin/Projects/indi/src/apogee/ApnCamera.h Apn_Status"m_pvtInputVoltageb/home/slovin/Projects/indi/src/apogee/ApnCamera.h! ! double*m_pvtIoPortAssignmentb/home/slovin/Projects/indi/src/apogee/ApnCamera.h""%unsigned short(m_pvtIoPortDirectionb/home/slovin/Projects/indi/src/apogee/ApnCamera.h##$unsigned shortm_pvtLedModeb/home/slovin/Projects/indi/src/apogee/ApnCamera.h  Apn_LedModem_pvtLedStateAb/home/slovin/Projects/indi/src/apogee/ApnCamera.h  Apn_LedStatem_pvtLedStateBb/home/slovin/Projects/indi/src/apogee/ApnCamera.h  Apn_LedState0m_pvtNetworkTransferModeb/home/slovin/Projects/indi/src/apogee/ApnCamera.hüü)Apn_NetworkMode$m_pvtSequenceDelayb/home/slovin/Projects/indi/src/apogee/ApnCamera.h  double"m_pvtShutterStateb/home/slovin/Projects/indi/src/apogee/ApnCamera.h bool0m_pvtShutterStrobePeriodb/home/slovin/Projects/indi/src/apogee/ApnCamera.h " double4m_pvtShutterStrobePositionb/home/slovin/Projects/indi/src/apogee/ApnCamera.h $ doublem_pvtStatusRegb/home/slovin/Projects/indi/src/apogee/ApnCamera.hunsigned shortm_pvtTDIRateb/home/slovin/Projects/indi/src/apogee/ApnCamera.h  doublem_pvtTDIRowsb/home/slovin/Projects/indi/src/apogee/ApnCamera.hÿÿunsigned short,m_pvtTestLedBrightnessb/home/slovin/Projects/indi/src/apogee/ApnCamera.h  double$m_pvtTwelveBitGainb/home/slovin/Projects/indi/src/apogee/ApnCamera.h"unsigned shortm_pvtWidthb/home/slovin/Projects/indi/src/apogee/ApnCamera.h''unsigned shortj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.hÿÿÿÿCApnCamera_NETj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h RCApnCamera CApnCamera_NETj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h))CApnCamera_NET.TEÿÿÿÿCloseDriverj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h00CApnCamera_NETboolGetImageDataj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h7:CApnCamera_NETpImageDataÿÿÿÿunsigned short*ÿÿÿÿ Widthÿÿÿÿunsigned short&ÿÿÿÿ Heightÿÿÿÿunsigned short&ÿÿÿÿ Countÿÿÿÿunsigned long&ÿÿÿÿboolGetLineDataj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h<=CApnCamera_NETpLineBufferÿÿÿÿunsigned short*ÿÿÿÿSizeÿÿÿÿunsigned short&ÿÿÿÿboolInitDriverj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h,.CApnCamera_NET CamIdAÿÿÿÿunsigned longÿÿÿÿ CamIdBÿÿÿÿunsigned shortÿÿÿÿ Optionÿÿÿÿunsigned longÿÿÿÿbool PostStopExposurej/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h44+CApnCamera_NETDigitizeDataÿÿÿÿboolÿÿÿÿlongPreStartExposej/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h223CApnCamera_NETBitsPerPixelÿÿÿÿunsigned shortÿÿÿÿlongQueryStatusRegsj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.hJP)CApnCamera_NETStatusRegÿÿÿÿunsigned short&ÿÿÿÿHeatsinkTempRegÿÿÿÿunsigned short&ÿÿÿÿCcdTempRegÿÿÿÿunsigned short&ÿÿÿÿCoolerDriveRegÿÿÿÿunsigned short&ÿÿÿÿVoltageRegÿÿÿÿunsigned short&ÿÿÿÿTdiCounterÿÿÿÿunsigned short&ÿÿÿÿSequenceCounterÿÿÿÿunsigned short&ÿÿÿÿlongReadj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h??5CApnCamera_NETregÿÿÿÿunsigned shortÿÿÿÿvalÿÿÿÿunsigned short&ÿÿÿÿlong Writej/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h@@5CApnCamera_NETÿÿÿ€regÿÿÿÿunsigned shortÿÿÿÿvalÿÿÿÿunsigned shortÿÿÿÿlongWriteMultiMRMDj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.hFHCApnCamera_NET reg[]ÿÿÿÿunsigned shortÿÿÿÿ val[]ÿÿÿÿunsigned shortÿÿÿÿ countÿÿÿÿunsigned shortÿÿÿÿlongWriteMultiSRMDj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.hBDCApnCamera_NETõyregÿÿÿÿunsigned shortÿÿÿÿ val[]ÿÿÿÿunsigned shortÿÿÿÿ countÿÿÿÿunsigned shortÿÿÿÿlong ~ CApnCamera_NETj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h* *CApnCamera_NETÿÿÿÿ"m_pvtBitsPerPixelj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h##!unsigned shortm_pvtHeightj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h&&unsigned shortm_pvtWidthj/home/slovin/Projects/indi/src/apogee/ApnCamera_NET.h%%unsigned shortj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.hÿÿÿÿCApnCamera_USBj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.hMCApnCamera CApnCamera_USBj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h%%CApnCamera_USB.BSÿÿÿÿCloseDriverj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h,,CApnCamera_USBboolGetImageDataj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h25CApnCamera_USBpImageDataÿÿÿÿunsigned short*ÿÿÿÿ Widthÿÿÿÿunsigned short&ÿÿÿÿ Heightÿÿÿÿunsigned short&ÿÿÿÿ Countÿÿÿÿunsigned long&ÿÿÿÿboolGetLineDataj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h78CApnCamera_USBpLineBufferÿÿÿÿunsigned short*ÿÿÿÿSizeÿÿÿÿunsigned short&ÿÿÿÿboolInitDriverj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h(*CApnCamera_USB CamIdAÿÿÿÿunsigned longÿÿÿÿ CamIdBÿÿÿÿunsigned shortÿÿÿÿ Optionÿÿÿÿunsigned longÿÿÿÿbool PostStopExposurej/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h00+CApnCamera_USBDigitizeDataÿÿÿÿboolÿÿÿÿlongPreStartExposej/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h..3CApnCamera_USBBitsPerPixelÿÿÿÿunsigned shortÿÿÿÿlongQueryStatusRegsj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.hEK)CApnCamera_USBStatusRegÿÿÿÿunsigned short&ÿÿÿÿHeatsinkTempRegÿÿÿÿunsigned short&ÿÿÿÿCcdTempRegÿÿÿÿunsigned short&ÿÿÿÿCoolerDriveRegÿÿÿÿunsigned short&ÿÿÿÿVoltageRegÿÿÿÿunsigned short&ÿÿÿÿTdiCounterÿÿÿÿunsigned short&ÿÿÿÿSequenceCounterÿÿÿÿunsigned short&ÿÿÿÿlongReadj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h::5CApnCamera_USBregÿÿÿÿunsigned shortÿÿÿÿvalÿÿÿÿunsigned short&ÿÿÿÿlong Writej/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h;;5CApnCamera_USBregÿÿÿÿunsigned shortÿÿÿÿvalÿÿÿÿunsigned shortÿÿÿÿlongWriteMultiMRMDj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.hACCApnCamera_USB reg[]ÿÿÿÿunsigned shortÿÿÿÿ val[]ÿÿÿÿunsigned shortÿÿÿÿ countÿÿÿÿunsigned shortÿÿÿÿlongWriteMultiSRMDj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h=?CApnCamera_USB Æ€regÿÿÿÿunsigned shortÿÿÿÿ val[]ÿÿÿÿunsigned shortÿÿÿÿ countÿÿÿÿunsigned shortÿÿÿÿlong ~ CApnCamera_USBj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h& &CApnCamera_USBÿÿÿÿ"m_pvtBitsPerPixelj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h!unsigned shortm_pvtHeightj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h""unsigned shortm_pvtWidthj/home/slovin/Projects/indi/src/apogee/ApnCamera_USB.h!!unsigned shortb/home/slovin/Projects/indi/src/apogee/ApnSerial.hÿÿÿÿCApnSerialb/home/slovin/Projects/indi/src/apogee/ApnSerial.h!D CApnSerialb/home/slovin/Projects/indi/src/apogee/ApnSerial.h%% CApnSerialý?ÿÿÿÿClosePortb/home/slovin/Projects/indi/src/apogee/ApnSerial.h,,CApnSerial IDboolGetBaudRateb/home/slovin/Projects/indi/src/apogee/ApnSerial.h..8CApnSerialÄBaudRateÿÿÿÿunsigned long*ÿÿÿÿboolGetFlowControlb/home/slovin/Projects/indi/src/apogee/ApnSerial.h22FCApnSerial·UÇDFlowControlÿÿÿÿ,Apn_SerialFlowControl*ÿÿÿÿboolGetParityb/home/slovin/Projects/indi/src/apogee/ApnSerial.h667CApnSerial ?D Parityÿÿÿÿ"Apn_SerialParity*ÿÿÿÿboolInitPortb/home/slovin/Projects/indi/src/apogee/ApnSerial.h(*&CApnSerial )òD CamIdAÿÿÿÿunsigned longÿÿÿÿ CamIdBÿÿÿÿunsigned shortÿÿÿÿSerialIdÿÿÿÿunsigned shortÿÿÿÿboolReadb/home/slovin/Projects/indi/src/apogee/ApnSerial.h:;'CApnSerial »DReadBufferÿÿÿÿ char*ÿÿÿÿReadCountÿÿÿÿunsigned short*ÿÿÿÿboolSetBaudRateb/home/slovin/Projects/indi/src/apogee/ApnSerial.h007CApnSerialDBaudRateÿÿÿÿunsigned longÿÿÿÿboolSetFlowControlb/home/slovin/Projects/indi/src/apogee/ApnSerial.h44ECApnSerialDFlowControlÿÿÿÿ*Apn_SerialFlowControlÿÿÿÿboolSetParityb/home/slovin/Projects/indi/src/apogee/ApnSerial.h886CApnSerialõoÄ Parityÿÿÿÿ Apn_SerialParityÿÿÿÿbool Writeb/home/slovin/Projects/indi/src/apogee/ApnSerial.h=>%CApnSerialDWriteBufferÿÿÿÿ char*ÿÿÿÿWriteCountÿÿÿÿunsigned shortÿÿÿÿbool~ CApnSerialb/home/slovin/Projects/indi/src/apogee/ApnSerial.h& &CApnSerialÿÿÿÿ"m_CameraInterfaceb/home/slovin/Projects/indi/src/apogee/ApnSerial.hAA Apn_Interfacem_SerialIdb/home/slovin/Projects/indi/src/apogee/ApnSerial.hB B shortj/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.hÿÿÿÿCApnSerial_NETj/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.h!<CApnSerial CApnSerial_NETj/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.h$$CApnSerial_NET.TEÿÿÿÿClosePortj/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.h++CApnSerial_NETboolGetBaudRatej/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.h--,CApnSerial_NETBaudRateÿÿÿÿunsigned long*ÿÿÿÿboolGetFlowControlj/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.h00:CApnSerial_NETFlowControlÿÿÿÿ,Apn_SerialFlowControl*ÿÿÿÿboolGetParityj/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.h33+CApnSerial_NET·UÇ Parityÿÿÿÿ"Apn_SerialParity*ÿÿÿÿboolInitPortj/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.h') CApnSerial_NETi CamIdAÿÿÿÿunsigned longÿÿÿÿ CamIdBÿÿÿÿunsigned shortÿÿÿÿSerialIdÿÿÿÿunsigned shortÿÿÿÿboolReadj/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.h67!CApnSerial_NET ³€ReadBufferÿÿÿÿ char*ÿÿÿÿReadCountÿÿÿÿunsigned short*ÿÿÿÿboolSetBaudRatej/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.h..+CApnSerial_NETBaudRateÿÿÿÿunsigned longÿÿÿÿboolSetFlowControlj/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.h119CApnSerial_NET·UÇFlowControlÿÿÿÿ*Apn_SerialFlowControlÿÿÿÿboolSetParityj/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.h44*CApnSerial_NET Parityÿÿÿÿ Apn_SerialParityÿÿÿÿbool Writej/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.h9:CApnSerial_NETWriteBufferÿÿÿÿ char*ÿÿÿÿWriteCountÿÿÿÿunsigned shortÿÿÿÿbool ~ CApnSerial_NETj/home/slovin/Projects/indi/src/apogee/ApnSerial_NET.h% %CApnSerial_NETÿÿÿÿj/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.hÿÿÿÿCApnSerial_USBj/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.h ;CApnSerial CApnSerial_USBj/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.h##CApnSerial_USB.BSÿÿÿÿClosePortj/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.h**CApnSerial_USBboolGetBaudRatej/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.h,,,CApnSerial_USBµVÆBaudRateÿÿÿÿunsigned long*ÿÿÿÿboolGetFlowControlj/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.h//:CApnSerial_USBFlowControlÿÿÿÿ,Apn_SerialFlowControl*ÿÿÿÿboolGetParityj/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.h22+CApnSerial_USB Parityÿÿÿÿ"Apn_SerialParity*ÿÿÿÿboolInitPortj/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.h&( CApnSerial_USB·UÇ CamIdAÿÿÿÿunsigned longÿÿÿÿ CamIdBÿÿÿÿunsigned shortÿÿÿÿSerialIdÿÿÿÿunsigned shortÿÿÿÿboolReadj/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.h56!CApnSerial_USB ûReadBufferÿÿÿÿ char*ÿÿÿÿReadCountÿÿÿÿunsigned short*ÿÿÿÿboolSetBaudRatej/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.h--+CApnSerial_USBBaudRateÿÿÿÿunsigned longÿÿÿÿboolSetFlowControlj/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.h009CApnSerial_USBFlowControlÿÿÿÿ*Apn_SerialFlowControlÿÿÿÿboolSetParityj/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.h33*CApnSerial_USB Parityÿÿÿÿ Apn_SerialParityÿÿÿÿbool Writej/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.h89CApnSerial_USBWriteBufferÿÿÿÿ char*ÿÿÿÿWriteCountÿÿÿÿunsigned shortÿÿÿÿbool ~ CApnSerial_USBj/home/slovin/Projects/indi/src/apogee/ApnSerial_USB.h$ $CApnSerial_USB )•€ÿÿÿÿb/home/slovin/Projects/indi/src/apogee/ApnUsbSys.hÿÿÿÿ APN_USB_REQUESTb/home/slovin/Projects/indi/src/apogee/ApnUsbSys.h;; _APN_USB_REQUEST PAPN_USB_REQUESTb/home/slovin/Projects/indi/src/apogee/ApnUsbSys.h;;$"_APN_USB_REQUEST*\/home/slovin/Projects/indi/src/apogee/Apogee.hÿÿÿÿf/home/slovin/Projects/indi/src/apogee/ApogeeIoctl.hÿÿÿÿf/home/slovin/Projects/indi/src/apogee/ApogeeLinux.hÿÿÿÿapIOparamf/home/slovin/Projects/indi/src/apogee/ApogeeLinux.h48 param1f/home/slovin/Projects/indi/src/apogee/ApogeeLinux.h77unsigned long param2f/home/slovin/Projects/indi/src/apogee/ApogeeLinux.h77unsigned longregf/home/slovin/Projects/indi/src/apogee/ApogeeLinux.h66unsigned intb/home/slovin/Projects/indi/src/apogee/ApogeeUsb.hÿÿÿÿ ApnUsbCloseb/home/slovin/Projects/indi/src/apogee/ApogeeUsb.h11/iÿÿÿÿÿÿÿÿvoidÿÿÿÿunsigned shortApnUsbDiscoveryb/home/slovin/Projects/indi/src/apogee/ApogeeUsb.h45'UsbCamCountÿÿÿÿunsigned short*ÿÿÿÿUsbCamInfo[]ÿÿÿÿAPN_USB_CAMINFOÿÿÿÿunsigned shortApnUsbGetImageb/home/slovin/Projects/indi/src/apogee/ApogeeUsb.hZZBµVÆpMemÿÿÿÿunsigned short*ÿÿÿÿunsigned shortApnUsbOpenb/home/slovin/Projects/indi/src/apogee/ApogeeUsb.h..E éDeviceNumberÿÿÿÿunsigned shortÿÿÿÿunsigned shortApnUsbReadRegb/home/slovin/Projects/indi/src/apogee/ApogeeUsb.h89$FpgaRegÿÿÿÿunsigned shortÿÿÿÿFpgaDataÿÿÿÿunsigned short*ÿÿÿÿunsigned short(ApnUsbReadStatusRegsb/home/slovin/Projects/indi/src/apogee/ApogeeUsb.hJP,StatusRegÿÿÿÿunsigned short*ÿÿÿÿHeatsinkTempRegÿÿÿÿunsigned short*ÿÿÿÿCcdTempRegÿÿÿÿunsigned short*ÿÿÿÿCoolerDriveRegÿÿÿÿunsigned short*ÿÿÿÿVoltageRegÿÿÿÿunsigned short*ÿÿÿÿTdiCounterÿÿÿÿunsigned short*ÿÿÿÿSequenceCounterÿÿÿÿunsigned short*ÿÿÿÿunsigned shortApnUsbResetb/home/slovin/Projects/indi/src/apogee/ApogeeUsb.h]]) a€unsigned shortApnUsbStartExpb/home/slovin/Projects/indi/src/apogee/ApogeeUsb.hST$ImageWidthÿÿÿÿunsigned shortÿÿÿÿImageHeightÿÿÿÿunsigned shortÿÿÿÿunsigned shortApnUsbStopExpb/home/slovin/Projects/indi/src/apogee/ApogeeUsb.hWW>DigitizeDataÿÿÿÿboolÿÿÿÿunsigned shortApnUsbWriteRegb/home/slovin/Projects/indi/src/apogee/ApogeeUsb.h<=!FpgaRegÿÿÿÿunsigned shortÿÿÿÿFpgaDataÿÿÿÿunsigned shortÿÿÿÿunsigned short&ApnUsbWriteRegMultib/home/slovin/Projects/indi/src/apogee/ApogeeUsb.h@B#FpgaRegÿÿÿÿunsigned shortÿÿÿÿFpgaData[]ÿÿÿÿunsigned shortÿÿÿÿRegCountÿÿÿÿunsigned shortÿÿÿÿunsigned short.ApnUsbWriteRegMultiMRMDb/home/slovin/Projects/indi/src/apogee/ApogeeUsb.hEG$ îFpgaReg[]ÿÿÿÿunsigned shortÿÿÿÿFpgaData[]ÿÿÿÿunsigned shortÿÿÿÿRegCountÿÿÿÿunsigned shortÿÿÿÿunsigned short APN_USB_CAMINFOb/home/slovin/Projects/indi/src/apogee/ApogeeUsb.h!! _APN_USB_CAMINFOh/home/slovin/Projects/indi/src/apogee/ApogeeUsbErr.hÿÿÿÿl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÿÿÿÿCCameraIOl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h¤¯2AuxOutputl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h,,$CCameraIO valÿÿÿÿunsigned charÿÿÿÿvoidCCameraIOl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h¨¨ CCameraIOxunÿÿÿÿDigitizeLinel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hPPCCameraIO bool Exposel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hBB+CCameraIO1Durationÿÿÿÿ doubleÿÿÿÿ LightÿÿÿÿboolÿÿÿÿboolFilterHomel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h66CCameraIOtboolFilterSetl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h99CCameraIOaSlotÿÿÿÿ shortÿÿÿÿvoid Flushl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h))CCameraIO Rowsÿÿÿÿ shortÿÿÿÿvoidGetImagel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hFFPCCameraIOnpImageDataÿÿÿÿunsigned short*ÿÿÿÿ xSizeÿÿÿÿ short&ÿÿÿÿ ySizeÿÿÿÿ short&ÿÿÿÿboolGetLinel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hSS8CCameraIOlpLineDataÿÿÿÿunsigned short*ÿÿÿÿ xSizeÿÿÿÿ short&ÿÿÿÿboolInitDefaultsl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hŸŸCCameraIOyvoidInitDriverl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h­ ­.CCameraIO camnumÿÿÿÿunsigned shortÿÿÿÿbool InternalReadLinel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h¢¢ACCameraIOsÿÿÿÿÿÿÿÿboolÿÿÿÿÿÿÿÿÿÿÿÿlong intÿÿÿÿÿÿÿÿÿÿÿÿlong intÿÿÿÿÿÿÿÿÿÿÿÿunsigned short*ÿÿÿÿlong LoadColumnLayoutl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h™™WCCameraIOiaicÿÿÿÿunsigned shortÿÿÿÿbicÿÿÿÿunsigned shortÿÿÿÿ pixelsÿÿÿÿunsigned shortÿÿÿÿvoidLoadLineCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h˜˜,CCameraIO=rowsÿÿÿÿunsigned shortÿÿÿÿvoid&LoadTimerAndBinningl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hššVCCameraIO Durationÿÿÿÿ doubleÿÿÿÿHBinÿÿÿÿunsigned shortÿÿÿÿVBinÿÿÿÿunsigned shortÿÿÿÿvoidReadl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h° °<CCameraIO *Hregÿÿÿÿunsigned shortÿÿÿÿvalÿÿÿÿunsigned short&ÿÿÿÿlongReadImagel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h¡¡$CCameraIOaÿÿÿÿÿÿÿÿ&short unsigned int*ÿÿÿÿlongReadLinel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h® ®RCCameraIOSkipPixelsÿÿÿÿlongÿÿÿÿ PixelsÿÿÿÿlongÿÿÿÿpLineBufferÿÿÿÿunsigned short*ÿÿÿÿlongRegReadl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h22/CCameraIOhregÿÿÿÿ shortÿÿÿÿvalÿÿÿÿunsigned short&ÿÿÿÿvoidRegWritel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h///CCameraIOhregÿÿÿÿ shortÿÿÿÿvalÿÿÿÿunsigned shortÿÿÿÿvoid Resetl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h CCameraIO voidSnapl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h]]aCCameraIOiDurationÿÿÿÿ doubleÿÿÿÿ LightÿÿÿÿboolÿÿÿÿpImageDataÿÿÿÿunsigned short*ÿÿÿÿ xSizeÿÿÿÿ short&ÿÿÿÿ ySizeÿÿÿÿ short&ÿÿÿÿboolStartFlushingl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hœœCCameraIO voidStopFlushingl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hCCameraIOtvoid Writel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h¯ ¯<CCameraIO Àregÿÿÿÿunsigned shortÿÿÿÿvalÿÿÿÿunsigned shortÿÿÿÿlongread_CoolerModel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hõõ$CCameraION"Camera_CoolerMode&read_CoolerSetPointl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hððCCameraIOe double"read_CoolerStatusl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hóó(CCameraIO &Camera_CoolerStatus read_FastReadoutl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÔÔCCameraIO5bool*read_ForceShutterOpenl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÅÅCCameraIOboolread_LongCablel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÈÈCCameraIOtboolread_Model/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hËËCCameraIO0 shortread_Presentl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÀÀCCameraIO S€boolread_Shutterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÂÂCCameraIO Wboolread_Statusl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hµµCCameraIOCamera_Status read_Temperaturel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.høøCCameraIOs doubleread_Test2Bitsl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÑÑCCameraIOd shortread_TestBitsl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÎÎCCameraIO7 shortread_UseTriggerl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h××CCameraIO7bool write_CoolerModel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.höö/CCameraIOwvalÿÿÿÿ"Camera_CoolerModeÿÿÿÿvoid(write_CoolerSetPointl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hññ(CCameraIO,valÿÿÿÿ doubleÿÿÿÿvoid"write_FastReadoutl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÕÕ#CCameraIO1valÿÿÿÿboolÿÿÿÿvoid,write_ForceShutterOpenl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÆÆ(CCameraIO valÿÿÿÿboolÿÿÿÿvoidwrite_LongCablel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÉÉ!CCameraIOSvalÿÿÿÿboolÿÿÿÿvoidwrite_Model/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÌÌCCameraIO2valÿÿÿÿ shortÿÿÿÿvoidwrite_Shutterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÃÃCCameraIO 5valÿÿÿÿboolÿÿÿÿvoidwrite_Test2Bitsl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÒÒ"CCameraIOfvalÿÿÿÿ shortÿÿÿÿvoidwrite_TestBitsl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÏÏ!CCameraIO0valÿÿÿÿ shortÿÿÿÿvoid write_UseTriggerl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hØØ"CCameraIO<valÿÿÿÿboolÿÿÿÿvoid~ CCameraIOl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h© ©CCameraIO +‹ÿÿÿÿGfileHandlel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h¨ ¨int m_BICl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h short m_BIRl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h shortm_BaseAddressp2l/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h¦¦&unsigned short m_BinXl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h short m_BinYl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h shortm_Colorl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h boolm_Columnsl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h   shortm_CoolerStatusl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hxx#&Camera_CoolerStatusm_DataBitsl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÞÞ shortm_ExposureAICl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hŠŠunsigned shortm_ExposureAIRl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hŒŒunsigned shortm_ExposureBICl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h‰‰ shortm_ExposureBIRl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h‰‰# shortm_ExposureBinXl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hƒƒ shortm_ExposureBinYl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hƒƒ% short"m_ExposureColumnsl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h†† short m_ExposureHFlushl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hˆˆ shortm_ExposureNumXl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h…… shortm_ExposureNumYl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h……% short0m_ExposureRemainingLinesl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h‹‹(unsigned shortm_ExposureRowsl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h††( shortm_ExposureSkipCl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h‡‡ shortm_ExposureSkipRl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h‡‡' short m_ExposureStartXl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h„„ short m_ExposureStartYl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h„„) short m_ExposureVFlushl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hˆˆ) shortm_FastShutterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hààbool,m_FastShutterBits_Model/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h’’&unsigned short,m_FastShutterBits_Testl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h““&unsigned short m_FilterPositionl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hjj shortm_FilterStepPosl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hkk short m_Gainl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h doublem_GuiderRelaysl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hââboolm_HFlushl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h   shortm_HighPriorityl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÚÚboolm_IRQMaskl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hyyunsigned intm_ImgColumnsl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h   shortm_ImgRowsl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h   shortm_Interfacel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hpp Camera_Interfacem_MaxBinXl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hää shortm_MaxBinYl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hää shortm_MaxExposurel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hææ doublem_MinExposurel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hçç doublem_Noisel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h double m_NumXl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h short m_NumYl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h shortm_PPRepeatl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hÜÜ shortm_PixelXSizel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h doublem_PixelYSizel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h doublem_RegShadowl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h0unsigned short m_RegisterOffsetl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hhh short m_Rowsl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h   shortm_Sensorl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hcharm_SensorTypel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.huu"Camera_SensorTypem_Shutterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hmmboolm_SkipCl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h   shortm_SkipRl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h   shortm_StartXl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h shortm_StartYl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h shortm_Statusl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hnnCamera_Status m_TDIl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hbb bool"m_TempCalibrationl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hûû shortm_TempControll/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.húúboolm_TempScalel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hüü doublem_Timeoutl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.héé doublem_VFlushl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h   short"m_WaitingforImagel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.heebool m_WaitingforLinel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hffbool&m_WaitingforTriggerl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hddboolsaveIRQSl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h§§unsigned into(Camera_Interface_ISAl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hint(Camera_Interface_PCIl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hint(Camera_Interface_PPIl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hint*Camera_SensorType_CCDl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h##int,Camera_SensorType_CMOSl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h$$intMAXCOLUMNSl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h' 'const longMAXHBINl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h) )const longMAXROWSl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h( (const longMAXVBINl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h* *const long"NumWriteRegistersl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h- - const long*RegBitMask_AICCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hQQ2(const unsigned short*RegBitMask_BICCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hnn2(const unsigned short&RegBitMask_HBinningl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.haa.(const unsigned short(RegBitMask_ImageDatal/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.huu2(const unsigned short,RegBitMask_LineCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hgg3(const unsigned shortRegBitMask_Model/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hii*(const unsigned short.RegBitMask_PixelCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h__4(const unsigned short,RegBitMask_PortControll/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hZZ2(const unsigned short&RegBitMask_TempDatal/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hzz/(const unsigned short.RegBitMask_TempSetPointl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hXX3(const unsigned shortRegBitMask_Testl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hpp*(const unsigned short RegBitMask_Test2l/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hSS+(const unsigned short RegBitMask_Timerl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hEE.(const unsigned short"RegBitMask_Timer2l/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hJJ,(const unsigned short&RegBitMask_VBinningl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hLL/(const unsigned short,RegBitShift_AICCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hPP/(const unsigned short,RegBitShift_BICCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hmm/(const unsigned short(RegBitShift_HBinningl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h``/(const unsigned short*RegBitShift_ImageDatal/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.htt.(const unsigned short.RegBitShift_LineCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hff0(const unsigned short RegBitShift_Model/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hhh+(const unsigned short0RegBitShift_PixelCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h^^1(const unsigned short.RegBitShift_PortControll/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hYY2(const unsigned short(RegBitShift_TempDatal/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hyy-(const unsigned short0RegBitShift_TempSetPointl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hWW1(const unsigned short RegBitShift_Testl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hoo+(const unsigned short"RegBitShift_Test2l/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hRR,(const unsigned short"RegBitShift_Timerl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hDD*(const unsigned short$RegBitShift_Timer2l/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hII+(const unsigned short(RegBitShift_VBinningl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hKK/(const unsigned short$RegBit_CableLengthl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h??0(const unsigned short$RegBit_CacheReadOKl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h€€-(const unsigned short&RegBit_CoolerEnablel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h@@1(const unsigned short*RegBit_CoolerShutdownl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h992(const unsigned short$RegBit_DoneReadingl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h::/(const unsigned shortRegBit_Exposingl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h~~*(const unsigned short RegBit_FIFOCachel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h55,(const unsigned shortRegBit_Focusl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h>>*(const unsigned short RegBit_FrameDonel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h††-(const unsigned short"RegBit_GotTriggerl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h…….(const unsigned shortRegBit_LineDonel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h*(const unsigned shortRegBit_LoopLockl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hbb-(const unsigned short&RegBit_LoopbackTestl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h‡‡1(const unsigned short$RegBit_ResetSysteml/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h44-(const unsigned short.RegBit_ShutdownCompletel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hƒƒ3(const unsigned short(RegBit_ShutterEnablel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h880(const unsigned short,RegBit_ShutterOverridel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h331(const unsigned short(RegBit_StartFlushingl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h==2(const unsigned short(RegBit_StartNextLinel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h<<1(const unsigned short"RegBit_StartTimerl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h22,(const unsigned short&RegBit_StopFlushingl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h77/(const unsigned shortRegBit_TDIModel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h11)(const unsigned short RegBit_TempAtMaxl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h‚‚,(const unsigned short RegBit_TempAtMinl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h,(const unsigned short*RegBit_TempAtSetPointl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h„„1(const unsigned short RegBit_TimerLoadl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h;;-(const unsigned short(RegBit_TriggerEnablel/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h660(const unsigned short"RegISA_AICCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hN N$const long"RegISA_BICCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hk k$const longRegISA_Commandl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h/ /!const long,RegISA_CommandReadbackl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h‰ ‰)const long RegISA_ImageDatal/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hr r#const long$RegISA_LineCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hd d%const long&RegISA_PixelCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h\ \&const longRegISA_Statusl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h| | const longRegISA_TempDatal/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hw w"const long&RegISA_TempSetPointl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hU U&const longRegISA_Timerl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hB Bconst longRegISA_VBinningl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hG G"const long"RegPCI_AICCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h“ “/const long*RegPCI_AICCounterReadl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h” ”/const long"RegPCI_BICCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h› ›/const long*RegPCI_BICCounterReadl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hœ œ/const longRegPCI_Commandl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h /const long$RegPCI_CommandReadl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hŽ Ž'const long,RegPCI_CommandReadbackl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h   )const long RegPCI_ImageDatal/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h #const long$RegPCI_LineCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h™ ™/const long,RegPCI_LineCounterReadl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hš š/const long&RegPCI_PixelCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h— —/const long.RegPCI_PixelCounterReadl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h˜ ˜/const longRegPCI_Statusl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hŸ Ÿ const longRegPCI_TempDatal/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hž ž"const long&RegPCI_TempSetPointl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h• •/const long.RegPCI_TempSetPointReadl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h– –/const longRegPCI_Timerl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h /const long RegPCI_TimerReadl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h /const longRegPCI_VBinningl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h‘ ‘/const long&RegPCI_VBinningReadl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h’ ’'const longReg_AICCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hO Oconst longReg_BICCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hl lconst longReg_Commandl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h0 0const long&Reg_CommandReadbackl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hŠ Š#const longReg_ImageDatal/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hs sconst longReg_LineCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.he econst long Reg_PixelCounterl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h] ]const longReg_Statusl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.h} }const longReg_TempDatal/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hx xconst long Reg_TempSetPointl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hV Vconst longReg_Timerl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hC Cconst longReg_VBinningl/home/slovin/Projects/indi/src/apogee/CameraIO_Linux.hH Hconst longh/home/slovin/Projects/indi/src/apogee/CameraIO_PCI.hÿÿÿÿCCameraIO_PCIh/home/slovin/Projects/indi/src/apogee/CameraIO_PCI.h 2CCameraIOCCameraIO_PCIh/home/slovin/Projects/indi/src/apogee/CameraIO_PCI.h$$CCameraIO_PCIh.IÿÿÿÿCloseDriverh/home/slovin/Projects/indi/src/apogee/CameraIO_PCI.h11CCameraIO_PCIvoidInitDriverh/home/slovin/Projects/indi/src/apogee/CameraIO_PCI.h''CCameraIO_PCIboolReadh/home/slovin/Projects/indi/src/apogee/CameraIO_PCI.h**5CCameraIO_PCIiregÿÿÿÿunsigned shortÿÿÿÿvalÿÿÿÿunsigned short&ÿÿÿÿlongReadLineh/home/slovin/Projects/indi/src/apogee/CameraIO_PCI.h((KCCameraIO_PCISkipPixelsÿÿÿÿlongÿÿÿÿ PixelsÿÿÿÿlongÿÿÿÿpLineBufferÿÿÿÿunsigned short*ÿÿÿÿlong Writeh/home/slovin/Projects/indi/src/apogee/CameraIO_PCI.h))5CCameraIO_PCIregÿÿÿÿunsigned shortÿÿÿÿvalÿÿÿÿunsigned shortÿÿÿÿlong~ CCameraIO_PCIh/home/slovin/Projects/indi/src/apogee/CameraIO_PCI.h% %CCameraIO_PCIÿÿÿÿm_IsWDMh/home/slovin/Projects/indi/src/apogee/CameraIO_PCI.h. .BOOLEANm_hDriverh/home/slovin/Projects/indi/src/apogee/CameraIO_PCI.h// HANDLE`/home/slovin/Projects/indi/src/apogee/FpgaRegs.hÿÿÿÿ\/home/slovin/Projects/indi/src/apogee/stdafx.hÿÿÿÿV/home/slovin/Projects/indi/src/apogee_ppi.hÿÿÿÿApogeeCamV/home/slovin/Projects/indi/src/apogee_ppi.hC¢(apogee_ppi_0)V/home/slovin/Projects/indi/src/apogee_ppi.hT]ApogeeCambinXV/home/slovin/Projects/indi/src/apogee_ppi.h[ [intbinYV/home/slovin/Projects/indi/src/apogee_ppi.h[[int exposeV/home/slovin/Projects/indi/src/apogee_ppi.hY YintframeTypeV/home/slovin/Projects/indi/src/apogee_ppi.hX Xint heightV/home/slovin/Projects/indi/src/apogee_ppi.hW W shortimgV/home/slovin/Projects/indi/src/apogee_ppi.h\\unsigned short*temperatureV/home/slovin/Projects/indi/src/apogee_ppi.hZ Z double widthV/home/slovin/Projects/indi/src/apogee_ppi.hV V shortApogeeCamV/home/slovin/Projects/indi/src/apogee_ppi.hGGApogeeCamÿÿÿÿISGetPropertiesV/home/slovin/Projects/indi/src/apogee_ppi.hK K*ApogeeCamdevÿÿÿÿconst char*ÿÿÿÿvoidISNewNumberV/home/slovin/Projects/indi/src/apogee_ppi.hN N_ApogeeCam (#€devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchV/home/slovin/Projects/indi/src/apogee_ppi.hL L_ApogeeCamndevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextV/home/slovin/Projects/indi/src/apogee_ppi.hM M[ApogeeCamdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollV/home/slovin/Projects/indi/src/apogee_ppi.hO OApogeeCam·UÇvoidcheckPowerNV/home/slovin/Projects/indi/src/apogee_ppi.h— —/ApogeeCamnpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿintcheckPowerSV/home/slovin/Projects/indi/src/apogee_ppi.h– –/ApogeeCamspÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿintcheckPowerTV/home/slovin/Projects/indi/src/apogee_ppi.h˜ ˜-ApogeeCam ïtpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿintconnectCCDV/home/slovin/Projects/indi/src/apogee_ppi.hŽ ŽApogeeCamµVÆÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidgetBasicDataV/home/slovin/Projects/indi/src/apogee_ppi.hŒ ŒApogeeCam *TÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidgetOnSwitchV/home/slovin/Projects/indi/src/apogee_ppi.hœ œ/ApogeeCamspÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿintgrabImageV/home/slovin/Projects/indi/src/apogee_ppi.h’ ’ApogeeCam *à€ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidhandleExposureV/home/slovin/Projects/indi/src/apogee_ppi.h ApogeeCamtÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoid hextoiV/home/slovin/Projects/indi/src/apogee_ppi.hžž&ApogeeCam å€ instrÿÿÿÿ char*ÿÿÿÿunsigned shortinitCameraV/home/slovin/Projects/indi/src/apogee_ppi.h‰ ‰ApogeeCamboolinitPropertiesV/home/slovin/Projects/indi/src/apogee_ppi.h‡ ‡ApogeeCamvoidisCCDConnectedV/home/slovin/Projects/indi/src/apogee_ppi.h“ “ApogeeCamµVÆÿÿÿÿÿÿÿÿvoidÿÿÿÿintloadXMLModelV/home/slovin/Projects/indi/src/apogee_ppi.hˆ ˆApogeeCam *¿boolmanageDefaultsV/home/slovin/Projects/indi/src/apogee_ppi.h› ›&ApogeeCamerrmsg[]ÿÿÿÿcharÿÿÿÿintmaxV/home/slovin/Projects/indi/src/apogee_ppi.h   ApogeeCam doubleminV/home/slovin/Projects/indi/src/apogee_ppi.hŸ ŸApogeeCam doublesetImageAreaV/home/slovin/Projects/indi/src/apogee_ppi.h‘ ‘$ApogeeCamerrmsg[]ÿÿÿÿcharÿÿÿÿintuploadFileV/home/slovin/Projects/indi/src/apogee_ppi.h $ApogeeCamfilenameÿÿÿÿ char*ÿÿÿÿvoidwriteFITSV/home/slovin/Projects/indi/src/apogee_ppi.h 1ApogeeCam Tfilenameÿÿÿÿ char*ÿÿÿÿerrmsg[]ÿÿÿÿcharÿÿÿÿint~ ApogeeCamV/home/slovin/Projects/indi/src/apogee_ppi.hHHApogeeCamÿÿÿÿAPGFrameV/home/slovin/Projects/indi/src/apogee_ppi.h]]ÿÿÿÿApogeeModelSV/home/slovin/Projects/indi/src/apogee_ppi.hc cISwitch*ApogeeModelSPV/home/slovin/Projects/indi/src/apogee_ppi.hrr'*ISwitchVectorPropertyBIAS_FRAMEV/home/slovin/Projects/indi/src/apogee_ppi.h__#intBinningNV/home/slovin/Projects/indi/src/apogee_ppi.hh hINumberBinningNPV/home/slovin/Projects/indi/src/apogee_ppi.hww#*INumberVectorPropertyDARK_FRAMEV/home/slovin/Projects/indi/src/apogee_ppi.h_%_/intDataChannelNV/home/slovin/Projects/indi/src/apogee_ppi.hk kINumberExposeTimeNV/home/slovin/Projects/indi/src/apogee_ppi.hi iINumberExposeTimeNPV/home/slovin/Projects/indi/src/apogee_ppi.hxx&*INumberVectorPropertyFLAT_FRAMEV/home/slovin/Projects/indi/src/apogee_ppi.h_1_;int FrameNV/home/slovin/Projects/indi/src/apogee_ppi.hg gINumberFrameNPV/home/slovin/Projects/indi/src/apogee_ppi.hvv!*INumberVectorPropertyFrameTypeSV/home/slovin/Projects/indi/src/apogee_ppi.hd dISwitchFrameTypeSPV/home/slovin/Projects/indi/src/apogee_ppi.hss%*ISwitchVectorPropertyLIGHT_FRAMEV/home/slovin/Projects/indi/src/apogee_ppi.h_ _int PowerSV/home/slovin/Projects/indi/src/apogee_ppi.hb bISwitchPowerSPV/home/slovin/Projects/indi/src/apogee_ppi.hqq!*ISwitchVectorPropertyTemperatureNV/home/slovin/Projects/indi/src/apogee_ppi.hj jINumberTemperatureNPV/home/slovin/Projects/indi/src/apogee_ppi.hyy'*INumberVectorPropertycamV/home/slovin/Projects/indi/src/apogee_ppi.h‚‚CCameraIO* imageBV/home/slovin/Projects/indi/src/apogee_ppi.hn n IBLOBimageBPV/home/slovin/Projects/indi/src/apogee_ppi.h}}&IBLOBVectorPropertystreamTimerIDV/home/slovin/Projects/indi/src/apogee_ppi.h€€inttargetTempV/home/slovin/Projects/indi/src/apogee_ppi.h  doubleN/home/slovin/Projects/indi/src/base64.cÿÿÿÿfrom64tobitsN/home/slovin/Projects/indi/src/base64.cUyEoutÿÿÿÿ char*ÿÿÿÿinÿÿÿÿconst char*ÿÿÿÿintto64frombitsN/home/slovin/Projects/indi/src/base64.c3Ooutÿÿÿÿunsigned char*ÿÿÿÿinÿÿÿÿ(const unsigned char*ÿÿÿÿ inlenÿÿÿÿintÿÿÿÿintbase64digitsN/home/slovin/Projects/indi/src/base64.c Econst charbase64valN/home/slovin/Projects/indi/src/base64.c#,const char rcsidN/home/slovin/Projects/indi/src/base64.cô ô char*N/home/slovin/Projects/indi/src/base64.hÿÿÿÿ^/home/slovin/Projects/indi/src/celestrongps.cppÿÿÿÿ ISPoll^/home/slovin/Projects/indi/src/celestrongps.cpp0 0 ÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoidCelestronGPS^/home/slovin/Projects/indi/src/celestrongps.cpp€ŽCelestronGPSaÿÿÿÿISGetProperties^/home/slovin/Projects/indi/src/celestrongps.cpppq-/devÿÿÿÿconst char*ÿÿÿÿvoidISGetProperties^/home/slovin/Projects/indi/src/celestrongps.cpp©CelestronGPS devÿÿÿÿconst char*ÿÿÿÿvoid ISInit^/home/slovin/Projects/indi/src/celestrongps.cpp`nRvoidISNewBLOB^/home/slovin/Projects/indi/src/celestrongps.cppyz ÿÿÿÿÿÿÿÿconst char*ÿÿÿÿÿÿÿÿÿÿÿÿconst char*ÿÿÿÿÿÿÿÿÿÿÿÿint*ÿÿÿÿÿÿÿÿÿÿÿÿ char**ÿÿÿÿÿÿÿÿÿÿÿÿ char**ÿÿÿÿÿÿÿÿÿÿÿÿ char**ÿÿÿÿÿÿÿÿÿÿÿÿintÿÿÿÿvoidISNewNumber^/home/slovin/Projects/indi/src/celestrongps.cppvwAPdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewNumber^/home/slovin/Projects/indi/src/celestrongps.cppŠCelestronGPS;devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitch^/home/slovin/Projects/indi/src/celestrongps.cpprsAadevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitch^/home/slovin/Projects/indi/src/celestrongps.cppŒ6CelestronGPSKdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewText^/home/slovin/Projects/indi/src/celestrongps.cpptu>qdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewText^/home/slovin/Projects/indi/src/celestrongps.cpp«ÂCelestronGPS-devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPoll^/home/slovin/Projects/indi/src/celestrongps.cppxxUapÿÿÿÿ void*ÿÿÿÿvoid ISPoll^/home/slovin/Projects/indi/src/celestrongps.cppwðCelestronGPSevoidcheckPower^/home/slovin/Projects/indi/src/celestrongps.cppCRCelestronGPS spÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿintcheckPower^/home/slovin/Projects/indi/src/celestrongps.cppTbCelestronGPS npÿÿÿÿ,INumberVectorProperty*ÿÿÿÿintcheckPower^/home/slovin/Projects/indi/src/celestrongps.cppduCelestronGPS tpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿintgetBasicData^/home/slovin/Projects/indi/src/celestrongps.cppòýCelestronGPStvoidgetOnSwitch^/home/slovin/Projects/indi/src/celestrongps.cpp9@CelestronGPSgspÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿinthandleCoordSet^/home/slovin/Projects/indi/src/celestrongps.cppÄCelestronGPSeintpowerTelescope^/home/slovin/Projects/indi/src/celestrongps.cppÿCelestronGPSSvoidslewError^/home/slovin/Projects/indi/src/celestrongps.cpp3CelestronGPSPslewCodeÿÿÿÿintÿÿÿÿvoidMovementS^/home/slovin/Projects/indi/src/celestrongps.cpp88ISwitchMovementSw^/home/slovin/Projects/indi/src/celestrongps.cpp\\Ç*ISwitchVectorPropertyOnCoordSetS^/home/slovin/Projects/indi/src/celestrongps.cpp55ˆISwitchOnCoordSetSw^/home/slovin/Projects/indi/src/celestrongps.cppXXÇ*ISwitchVectorPropertyPort^/home/slovin/Projects/indi/src/celestrongps.cppUU &ITextVectorProperty PortT^/home/slovin/Projects/indi/src/celestrongps.cppT T7 IText PowerS^/home/slovin/Projects/indi/src/celestrongps.cpp33wISwitchPowerSw^/home/slovin/Projects/indi/src/celestrongps.cppSS¸*ISwitchVectorPropertySlewModeS^/home/slovin/Projects/indi/src/celestrongps.cpp44œISwitchSlewModeSw^/home/slovin/Projects/indi/src/celestrongps.cppZZ½*ISwitchVectorPropertyabortSlewS^/home/slovin/Projects/indi/src/celestrongps.cpp66FISwitchabortSlewSw^/home/slovin/Projects/indi/src/celestrongps.cppYYÏ*ISwitchVectorPropertyeq^/home/slovin/Projects/indi/src/celestrongps.cpp;>INumber eqNum^/home/slovin/Projects/indi/src/celestrongps.cpp@B*INumberVectorPropertyslewPrecisionN^/home/slovin/Projects/indi/src/celestrongps.cppLOINumberslewPrecisionNP^/home/slovin/Projects/indi/src/celestrongps.cppPP¾*INumberVectorPropertytelescope^/home/slovin/Projects/indi/src/celestrongps.cpp! !CelestronGPS*$trackingPrecisionN^/home/slovin/Projects/indi/src/celestrongps.cppEHINumber&trackingPrecisionNP^/home/slovin/Projects/indi/src/celestrongps.cppIIÎ*INumberVectorPropertyZ/home/slovin/Projects/indi/src/celestrongps.hÿÿÿÿCelestronGPSZ/home/slovin/Projects/indi/src/celestrongps.h@CelestronGPSZ/home/slovin/Projects/indi/src/celestrongps.hCelestronGPSÿÿÿÿISGetPropertiesZ/home/slovin/Projects/indi/src/celestrongps.h""/CelestronGPSæQdevÿÿÿÿconst char*ÿÿÿÿvoidISNewNumberZ/home/slovin/Projects/indi/src/celestrongps.h##dCelestronGPSµVÆdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchZ/home/slovin/Projects/indi/src/celestrongps.h%%dCelestronGPSdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextZ/home/slovin/Projects/indi/src/celestrongps.h$$`CelestronGPSdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollZ/home/slovin/Projects/indi/src/celestrongps.h&&CelestronGPS·UÇvoidcheckPowerZ/home/slovin/Projects/indi/src/celestrongps.h))*CelestronGPS í€npÿÿÿÿ,INumberVectorProperty*ÿÿÿÿintcheckPowerZ/home/slovin/Projects/indi/src/celestrongps.h***CelestronGPS·UÇspÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿintcheckPowerZ/home/slovin/Projects/indi/src/celestrongps.h++(CelestronGPStpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿintgetBasicDataZ/home/slovin/Projects/indi/src/celestrongps.h''CelestronGPSvoidgetOnSwitchZ/home/slovin/Projects/indi/src/celestrongps.h//+CelestronGPS·UÇspÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿinthandleCoordSetZ/home/slovin/Projects/indi/src/celestrongps.h..CelestronGPSintpowerTelescopeZ/home/slovin/Projects/indi/src/celestrongps.h,,CelestronGPSvoidslewErrorZ/home/slovin/Projects/indi/src/celestrongps.h--CelestronGPSslewCodeÿÿÿÿintÿÿÿÿvoid~ CelestronGPSZ/home/slovin/Projects/indi/src/celestrongps.h  CelestronGPS·UÇÿÿÿÿ~ CelestronGPSZ/home/slovin/Projects/indi/src/celestrongps.h  CelestronGPS·UÇÿÿÿÿ JDZ/home/slovin/Projects/indi/src/celestrongps.h4 4  doublecurrentDECZ/home/slovin/Projects/indi/src/celestrongps.h6 6 doublecurrentRAZ/home/slovin/Projects/indi/src/celestrongps.h5 5 doublecurrentSetZ/home/slovin/Projects/indi/src/celestrongps.h==intlastDECZ/home/slovin/Projects/indi/src/celestrongps.h: : doublelastMoveZ/home/slovin/Projects/indi/src/celestrongps.h>>int lastRAZ/home/slovin/Projects/indi/src/celestrongps.h9 9 doublelastSetZ/home/slovin/Projects/indi/src/celestrongps.h<< inttargetDECZ/home/slovin/Projects/indi/src/celestrongps.h8 8 doubletargetRAZ/home/slovin/Projects/indi/src/celestrongps.h7 7 doubletimeFormatZ/home/slovin/Projects/indi/src/celestrongps.h22intd/home/slovin/Projects/indi/src/celestronprotocol.cÿÿÿÿCheckConnectTeld/home/slovin/Projects/indi/src/celestronprotocol.c22€ÿÿÿÿÿÿÿÿvoidÿÿÿÿintCheckCoordsd/home/slovin/Projects/indi/src/celestronprotocol.c<<Ji desRAÿÿÿÿ doubleÿÿÿÿ desDecÿÿÿÿ doubleÿÿÿÿ tolRAÿÿÿÿ doubleÿÿÿÿ tolDECÿÿÿÿ doubleÿÿÿÿintConnectTeld/home/slovin/Projects/indi/src/celestronprotocol.c00dportÿÿÿÿ char*ÿÿÿÿintDerotatord/home/slovin/Projects/indi/src/celestronprotocol.cFF S rotateÿÿÿÿintÿÿÿÿvoidDisconnectTeld/home/slovin/Projects/indi/src/celestronprotocol.c11ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidFand/home/slovin/Projects/indi/src/celestronprotocol.cGGµVÆfanÿÿÿÿintÿÿÿÿvoid Focusd/home/slovin/Projects/indi/src/celestronprotocol.cEE K focusÿÿÿÿintÿÿÿÿvoid GetDecd/home/slovin/Projects/indi/src/celestronprotocol.c99aÿÿÿÿÿÿÿÿvoidÿÿÿÿ double GetRAd/home/slovin/Projects/indi/src/celestronprotocol.c88aÿÿÿÿÿÿÿÿvoidÿÿÿÿ doubleGetRAandDecd/home/slovin/Projects/indi/src/celestronprotocol.c^^€ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidReticled/home/slovin/Projects/indi/src/celestronprotocol.cDDreticleÿÿÿÿintÿÿÿÿvoidSetLimitsd/home/slovin/Projects/indi/src/celestronprotocol.c555nlimitLowerÿÿÿÿ doubleÿÿÿÿlimitHigherÿÿÿÿ doubleÿÿÿÿvoidSetRated/home/slovin/Projects/indi/src/celestronprotocol.c44newRateÿÿÿÿintÿÿÿÿvoidSetSlewRated/home/slovin/Projects/indi/src/celestronprotocol.c??ÿÿÿÿÿÿÿÿvoidÿÿÿÿintSlewToCoordsd/home/slovin/Projects/indi/src/celestronprotocol.c::.  newRAÿÿÿÿ doubleÿÿÿÿ newDecÿÿÿÿ doubleÿÿÿÿintStartSlewd/home/slovin/Projects/indi/src/celestronprotocol.c66<directionÿÿÿÿintÿÿÿÿvoidStopNSEWd/home/slovin/Projects/indi/src/celestronprotocol.c>>ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidStopSlewd/home/slovin/Projects/indi/src/celestronprotocol.c77sdirectionÿÿÿÿintÿÿÿÿvoidSyncLSTd/home/slovin/Projects/indi/src/celestronprotocol.cAAnewTimeÿÿÿÿ doubleÿÿÿÿintSyncLocalTimed/home/slovin/Projects/indi/src/celestronprotocol.cBBÿÿÿÿÿÿÿÿvoidÿÿÿÿintSyncToCoordsd/home/slovin/Projects/indi/src/celestronprotocol.c;;.R newRAÿÿÿÿ doubleÿÿÿÿ newDecÿÿÿÿ doubleÿÿÿÿintreadd/home/slovin/Projects/indi/src/celestronprotocol.có ó"·UÇÿÿÿÿÿÿÿÿfdÿÿÿÿÿÿÿÿÿÿÿÿptrÿÿÿÿÿÿÿÿÿÿÿÿ nleftÿÿÿÿÿÿÿÿ readnd/home/slovin/Projects/indi/src/celestronprotocol.cf f8fdÿÿÿÿintÿÿÿÿptrÿÿÿÿ char*ÿÿÿÿ nbytesÿÿÿÿintÿÿÿÿsecÿÿÿÿintÿÿÿÿinttelstatd/home/slovin/Projects/indi/src/celestronprotocol.ch h+fdÿÿÿÿintÿÿÿÿsecÿÿÿÿintÿÿÿÿusecÿÿÿÿintÿÿÿÿint writed/home/slovin/Projects/indi/src/celestronprotocol.cÞÞ%ÿÿÿÿÿÿÿÿfdÿÿÿÿÿÿÿÿÿÿÿÿptrÿÿÿÿÿÿÿÿÿÿÿÿ nleftÿÿÿÿÿÿÿÿ writend/home/slovin/Projects/indi/src/celestronprotocol.cg g0ofdÿÿÿÿintÿÿÿÿptrÿÿÿÿ char*ÿÿÿÿ nbytesÿÿÿÿintÿÿÿÿintCheckConnectTeld/home/slovin/Projects/indi/src/celestronprotocol.cknµVÆÿÿÿÿÿÿÿÿvoidÿÿÿÿintCheckCoordsd/home/slovin/Projects/indi/src/celestronprotocol.cFf desRAÿÿÿÿ doubleÿÿÿÿ desDecÿÿÿÿ doubleÿÿÿÿ tolRAÿÿÿÿ doubleÿÿÿÿ tolDECÿÿÿÿ doubleÿÿÿÿintConnectTeld/home/slovin/Projects/indi/src/celestronprotocol.cr©portÿÿÿÿ char*ÿÿÿÿintDerotatord/home/slovin/Projects/indi/src/celestronprotocol.cª¯·UÇ rotateÿÿÿÿintÿÿÿÿvoidDisconnectTeld/home/slovin/Projects/indi/src/celestronprotocol.c#)·UÇÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidFand/home/slovin/Projects/indi/src/celestronprotocol.c´¹€fanÿÿÿÿintÿÿÿÿvoid Focusd/home/slovin/Projects/indi/src/celestronprotocol.c ¤ focusÿÿÿÿintÿÿÿÿvoid GetDecd/home/slovin/Projects/indi/src/celestronprotocol.c@E€ÿÿÿÿÿÿÿÿvoidÿÿÿÿ double GetRAd/home/slovin/Projects/indi/src/celestronprotocol.c27ÿÿÿÿÿÿÿÿvoidÿÿÿÿ doubleGetRAandDecd/home/slovin/Projects/indi/src/celestronprotocol.cJˆ '¡€ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidReticled/home/slovin/Projects/indi/src/celestronprotocol.c—› ×€reticleÿÿÿÿintÿÿÿÿvoidSetLimitsd/home/slovin/Projects/indi/src/celestronprotocol.ckolimitLowerÿÿÿÿ doubleÿÿÿÿlimitHigherÿÿÿÿ doubleÿÿÿÿvoidSetRated/home/slovin/Projects/indi/src/celestronprotocol.c­ÀnewRateÿÿÿÿintÿÿÿÿvoidSetSlewRated/home/slovin/Projects/indi/src/celestronprotocol.ctxÿÿÿÿÿÿÿÿvoidÿÿÿÿintSlewToCoordsd/home/slovin/Projects/indi/src/celestronprotocol.cž<c newRAÿÿÿÿ doubleÿÿÿÿ newDecÿÿÿÿ doubleÿÿÿÿintStartSlewd/home/slovin/Projects/indi/src/celestronprotocol.cÆódirectionÿÿÿÿintÿÿÿÿvoidStopNSEWd/home/slovin/Projects/indi/src/celestronprotocol.c~‘ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidStopSlewd/home/slovin/Projects/indi/src/celestronprotocol.cø!directionÿÿÿÿintÿÿÿÿvoidSyncLSTd/home/slovin/Projects/indi/src/celestronprotocol.cÀÅ ÜnewTimeÿÿÿÿ doubleÿÿÿÿintSyncLocalTimed/home/slovin/Projects/indi/src/celestronprotocol.cÊÎintSyncToCoordsd/home/slovin/Projects/indi/src/celestronprotocol.c˜  newRAÿÿÿÿ doubleÿÿÿÿ newDecÿÿÿÿ doubleÿÿÿÿint FD_SETd/home/slovin/Projects/indi/src/celestronprotocol.cÿÿÿÿTelConnectFlagd/home/slovin/Projects/indi/src/celestronprotocol.cJ JintTelPortFDd/home/slovin/Projects/indi/src/celestronprotocol.cI Iintfdd/home/slovin/Projects/indi/src/celestronprotocol.c  int memsetd/home/slovin/Projects/indi/src/celestronprotocol.c,ÿÿÿÿ nbytesd/home/slovin/Projects/indi/src/celestronprotocol.céé int nleftd/home/slovin/Projects/indi/src/celestronprotocol.cíí int nreadd/home/slovin/Projects/indi/src/celestronprotocol.cí íintnwrittend/home/slovin/Projects/indi/src/celestronprotocol.cÚ ÚintoffsetDecd/home/slovin/Projects/indi/src/celestronprotocol.cYY doubleoffsetRAd/home/slovin/Projects/indi/src/celestronprotocol.cXX doubleptrd/home/slovin/Projects/indi/src/celestronprotocol.cèè char*readfdsd/home/slovin/Projects/indi/src/celestronprotocol.c  telfdsretd/home/slovin/Projects/indi/src/celestronprotocol.c  intreturnDecd/home/slovin/Projects/indi/src/celestronprotocol.cPP doublereturnRAd/home/slovin/Projects/indi/src/celestronprotocol.cOO doublesecd/home/slovin/Projects/indi/src/celestronprotocol.c  int selectd/home/slovin/Projects/indi/src/celestronprotocol.cgÿÿÿÿslewRated/home/slovin/Projects/indi/src/celestronprotocol.cS Sint statusd/home/slovin/Projects/indi/src/celestronprotocol.cìì inttelstatd/home/slovin/Projects/indi/src/celestronprotocol.cñ ñÿÿÿÿtimeoutd/home/slovin/Projects/indi/src/celestronprotocol.cstruct timevalupdateDecd/home/slovin/Projects/indi/src/celestronprotocol.cR RintupdateRAd/home/slovin/Projects/indi/src/celestronprotocol.cQ Qintusecd/home/slovin/Projects/indi/src/celestronprotocol.c  int widthd/home/slovin/Projects/indi/src/celestronprotocol.c int telfdsd/home/slovin/Projects/indi/src/celestronprotocol.cdd fd_setd/home/slovin/Projects/indi/src/celestronprotocol.hÿÿÿÿT/home/slovin/Projects/indi/src/eventloop.cÿÿÿÿcallCallbackT/home/slovin/Projects/indi/src/eventloop.cZ Z&rfdpÿÿÿÿfd_set*ÿÿÿÿvoidcheckTimerT/home/slovin/Projects/indi/src/eventloop.c[ [ '¢ˆvoidoneLoopT/home/slovin/Projects/indi/src/eventloop.c\ \ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidrunWorkProcT/home/slovin/Projects/indi/src/eventloop.cY Y ,ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoid addCallbackT/home/slovin/Projects/indi/src/eventloop.co‡ (`fdÿÿÿÿintÿÿÿÿfpÿÿÿÿCBF*ÿÿÿÿudÿÿÿÿ void*ÿÿÿÿintaddTimerT/home/slovin/Projects/indi/src/eventloop.c¡½msÿÿÿÿintÿÿÿÿfpÿÿÿÿTCF*ÿÿÿÿudÿÿÿÿ void*ÿÿÿÿintaddWorkProcT/home/slovin/Projects/indi/src/eventloop.cÙðfpÿÿÿÿWPF*ÿÿÿÿudÿÿÿÿ void*ÿÿÿÿintcallCallbackT/home/slovin/Projects/indi/src/eventloop.c-rfdpÿÿÿÿfd_set*ÿÿÿÿvoidcheckTimerT/home/slovin/Projects/indi/src/eventloop.c3EvoideventLoopT/home/slovin/Projects/indi/src/eventloop.caj voidoneLoopT/home/slovin/Projects/indi/src/eventloop.cJ‚voidrmCallbackT/home/slovin/Projects/indi/src/eventloop.cŒ›cidÿÿÿÿintÿÿÿÿvoidrmTimerT/home/slovin/Projects/indi/src/eventloop.cÂÔtimer_idÿÿÿÿintÿÿÿÿvoidrmWorkProcT/home/slovin/Projects/indi/src/eventloop.cöwidÿÿÿÿintÿÿÿÿvoidrunWorkProcT/home/slovin/Projects/indi/src/eventloop.c %–€void  cbackT/home/slovin/Projects/indi/src/eventloop.c6 6CB* epochT/home/slovin/Projects/indi/src/eventloop.cFFstruct timeval lastcbT/home/slovin/Projects/indi/src/eventloop.c9 9int lastwpT/home/slovin/Projects/indi/src/eventloop.cW Wint ncbackT/home/slovin/Projects/indi/src/eventloop.c7 7intncbinuseT/home/slovin/Projects/indi/src/eventloop.c8 8int ntimefT/home/slovin/Projects/indi/src/eventloop.cE EintnwpinuseT/home/slovin/Projects/indi/src/eventloop.cV Vint nwprocT/home/slovin/Projects/indi/src/eventloop.cU UinttidT/home/slovin/Projects/indi/src/eventloop.cG Gint timefT/home/slovin/Projects/indi/src/eventloop.cD DTF* wprocT/home/slovin/Projects/indi/src/eventloop.cT TWP* CBT/home/slovin/Projects/indi/src/eventloop.c55ÿÿÿÿ TFT/home/slovin/Projects/indi/src/eventloop.cCCÿÿÿÿ WPT/home/slovin/Projects/indi/src/eventloop.cSSÿÿÿÿT/home/slovin/Projects/indi/src/eventloop.hÿÿÿÿ CBFT/home/slovin/Projects/indi/src/eventloop.h! !#void TCFT/home/slovin/Projects/indi/src/eventloop.h+ +void WPFT/home/slovin/Projects/indi/src/eventloop.h& &void\/home/slovin/Projects/indi/src/fli/fli_ioctl.hÿÿÿÿFLI_GET_DIR_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.hajayint.FLI_GET_DMABUFFSIZE_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.haGa^int*FLI_GET_DMATHRESH_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.haa¥intFLI_GET_DTO_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.haËaÚintFLI_GET_LTL_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.haŸa®int$FLI_GET_NUMDTO_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.ha_aqint&FLI_GET_NUMREAD_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.haÜaïint$FLI_GET_NUMRTO_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.haa¯int(FLI_GET_NUMWRITE_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.haa3int$FLI_GET_NUMWTO_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.haÛaíintFLI_GET_RTO_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.haaintFLI_GET_WTO_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.ha5aDintFLI_LOCK_PORT\/home/slovin/Projects/indi/src/fli/fli_ioctl.hiÉi÷int"FLI_LOCK_PORT_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h^•^¦int*FLI_RESET_PORT_VALUES\/home/slovin/Projects/indi/src/fli/fli_ioctl.hiPiŽint2FLI_RESET_PORT_VALUES_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h^K^dintFLI_SET_DIR_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h`R`aint.FLI_SET_DMABUFFSIZE_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h_O_fint*FLI_SET_DMATHRESH_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h`C`XintFLI_SET_DTO_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h`~`intFLI_SET_LTL_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h``,int$FLI_SET_NUMDTO_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h``$int&FLI_SET_NUMREAD_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h``¢int$FLI_SET_NUMRTO_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h`P`bint(FLI_SET_NUMWRITE_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h`Ò`æint$FLI_SET_NUMWTO_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h`Ž` intFLI_SET_RTO_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h`³`ÂintFLI_SET_WTO_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h`è`÷intFLI_UNLOCK_PORT\/home/slovin/Projects/indi/src/fli/fli_ioctl.hi4ifint&FLI_UNLOCK_PORT_NUM\/home/slovin/Projects/indi/src/fli/fli_ioctl.h^Ù^ìintt/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cÿÿÿÿ*correctioportdatareadt/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cªudevÿÿÿÿflidev_tÿÿÿÿDataÿÿÿÿunsigned short*ÿÿÿÿvoid,correctioportdatawritet/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cn‹ devÿÿÿÿflidev_tÿÿÿÿDataÿÿÿÿunsigned short*ÿÿÿÿvoidFfli_camera_parport_configure_ioportt/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cÉÕgdevÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿlongÿÿÿÿlongDfli_camera_parport_control_shuttert/home/slovin/Projects/indi/src/fli/libfli-camera-parport.c×òcdevÿÿÿÿflidev_tÿÿÿÿshutterÿÿÿÿlongÿÿÿÿlong>fli_camera_parport_expose_framet/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cß02devÿÿÿÿflidev_tÿÿÿÿlong:fli_camera_parport_flush_rowst/home/slovin/Projects/indi/src/fli/libfli-camera-parport.c2X3devÿÿÿÿflidev_tÿÿÿÿrowsÿÿÿÿlongÿÿÿÿ repeatÿÿÿÿlongÿÿÿÿlongBfli_camera_parport_get_array_areat/home/slovin/Projects/indi/src/fli/libfli-camera-parport.c¿Ìodevÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿ long*ÿÿÿÿul_yÿÿÿÿ long*ÿÿÿÿlr_xÿÿÿÿ long*ÿÿÿÿlr_yÿÿÿÿ long*ÿÿÿÿlongLfli_camera_parport_get_exposure_statust/home/slovin/Projects/indi/src/fli/libfli-camera-parport.c*? devÿÿÿÿflidev_tÿÿÿÿtimeleftÿÿÿÿ long*ÿÿÿÿlongDfli_camera_parport_get_temperaturet/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cWk devÿÿÿÿflidev_tÿÿÿÿtemperatureÿÿÿÿdouble*ÿÿÿÿlongFfli_camera_parport_get_visible_areat/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cÎÛ devÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿ long*ÿÿÿÿul_yÿÿÿÿ long*ÿÿÿÿlr_xÿÿÿÿ long*ÿÿÿÿlr_yÿÿÿÿ long*ÿÿÿÿlong6fli_camera_parport_grab_rowt/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cmÝbdevÿÿÿÿflidev_tÿÿÿÿbuffÿÿÿÿ void*ÿÿÿÿ widthÿÿÿÿ size_tÿÿÿÿlong.fli_camera_parport_opent/home/slovin/Projects/indi/src/fli/libfli-camera-parport.c>½rapdevÿÿÿÿflidev_tÿÿÿÿlong<fli_camera_parport_read_ioportt/home/slovin/Projects/indi/src/fli/libfli-camera-parport.c¬¹1devÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿ long*ÿÿÿÿlong@fli_camera_parport_set_bit_deptht/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cZledevÿÿÿÿflidev_tÿÿÿÿbitdepthÿÿÿÿflibitdepth_tÿÿÿÿlongHfli_camera_parport_set_exposure_timet/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cÝùndevÿÿÿÿflidev_tÿÿÿÿexptimeÿÿÿÿlongÿÿÿÿlong6fli_camera_parport_set_hbint/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cadevÿÿÿÿflidev_tÿÿÿÿhbinÿÿÿÿlongÿÿÿÿlongBfli_camera_parport_set_image_areat/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cû-devÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿlongÿÿÿÿul_yÿÿÿÿlongÿÿÿÿlr_xÿÿÿÿlongÿÿÿÿlr_yÿÿÿÿlongÿÿÿÿlongDfli_camera_parport_set_temperaturet/home/slovin/Projects/indi/src/fli/libfli-camera-parport.cAUIdevÿÿÿÿflidev_tÿÿÿÿtemperatureÿÿÿÿ doubleÿÿÿÿlong6fli_camera_parport_set_vbint/home/slovin/Projects/indi/src/fli/libfli-camera-parport.c(edevÿÿÿÿflidev_tÿÿÿÿvbinÿÿÿÿlongÿÿÿÿlong>fli_camera_parport_write_ioportt/home/slovin/Projects/indi/src/fli/libfli-camera-parport.c»Ç devÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿlongÿÿÿÿlongt/home/slovin/Projects/indi/src/fli/libfli-camera-parport.hÿÿÿÿFfli_camera_parport_configure_ioportt/home/slovin/Projects/indi/src/fli/libfli-camera-parport.hddFdevÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿlongÿÿÿÿlongDfli_camera_parport_control_shuttert/home/slovin/Projects/indi/src/fli/libfli-camera-parport.heeC ddevÿÿÿÿflidev_tÿÿÿÿshutterÿÿÿÿlongÿÿÿÿlong>fli_camera_parport_expose_framet/home/slovin/Projects/indi/src/fli/libfli-camera-parport.h__2devÿÿÿÿflidev_tÿÿÿÿlong:fli_camera_parport_flush_rowst/home/slovin/Projects/indi/src/fli/libfli-camera-parport.h``Hdevÿÿÿÿflidev_tÿÿÿÿrowsÿÿÿÿlongÿÿÿÿ repeatÿÿÿÿlongÿÿÿÿlongBfli_camera_parport_get_array_areat/home/slovin/Projects/indi/src/fli/libfli-camera-parport.hRS"odevÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿ long*ÿÿÿÿul_yÿÿÿÿ long*ÿÿÿÿlr_xÿÿÿÿ long*ÿÿÿÿlr_yÿÿÿÿ long*ÿÿÿÿlongLfli_camera_parport_get_exposure_statust/home/slovin/Projects/indi/src/fli/libfli-camera-parport.h[[Idevÿÿÿÿflidev_tÿÿÿÿtimeleftÿÿÿÿ long*ÿÿÿÿlongDfli_camera_parport_get_temperaturet/home/slovin/Projects/indi/src/fli/libfli-camera-parport.h]]J *ãdevÿÿÿÿflidev_tÿÿÿÿtemperatureÿÿÿÿdouble*ÿÿÿÿlongFfli_camera_parport_get_visible_areat/home/slovin/Projects/indi/src/fli/libfli-camera-parport.hTU l€devÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿ long*ÿÿÿÿul_yÿÿÿÿ long*ÿÿÿÿlr_xÿÿÿÿ long*ÿÿÿÿlr_yÿÿÿÿ long*ÿÿÿÿlong6fli_camera_parport_grab_rowt/home/slovin/Projects/indi/src/fli/libfli-camera-parport.h^^G·UÇdevÿÿÿÿflidev_tÿÿÿÿbufÿÿÿÿ void*ÿÿÿÿ widthÿÿÿÿ size_tÿÿÿÿlong.fli_camera_parport_opent/home/slovin/Projects/indi/src/fli/libfli-camera-parport.hQQ*rapdevÿÿÿÿflidev_tÿÿÿÿlong<fli_camera_parport_read_ioportt/home/slovin/Projects/indi/src/fli/libfli-camera-parport.hbbB 8devÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿ long*ÿÿÿÿlong@fli_camera_parport_set_bit_deptht/home/slovin/Projects/indi/src/fli/libfli-camera-parport.haaK·UÇdevÿÿÿÿflidev_tÿÿÿÿbitdepthÿÿÿÿflibitdepth_tÿÿÿÿlongHfli_camera_parport_set_exposure_timet/home/slovin/Projects/indi/src/fli/libfli-camera-parport.hVVEdevÿÿÿÿflidev_tÿÿÿÿexptimeÿÿÿÿlongÿÿÿÿlong6fli_camera_parport_set_hbint/home/slovin/Projects/indi/src/fli/libfli-camera-parport.hYY9devÿÿÿÿflidev_tÿÿÿÿhbinÿÿÿÿlongÿÿÿÿlongBfli_camera_parport_set_image_areat/home/slovin/Projects/indi/src/fli/libfli-camera-parport.hWX devÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿlongÿÿÿÿul_yÿÿÿÿlongÿÿÿÿlr_xÿÿÿÿlongÿÿÿÿlr_yÿÿÿÿlongÿÿÿÿlongDfli_camera_parport_set_temperaturet/home/slovin/Projects/indi/src/fli/libfli-camera-parport.h\\Idevÿÿÿÿflidev_tÿÿÿÿtemperatureÿÿÿÿ doubleÿÿÿÿlong6fli_camera_parport_set_vbint/home/slovin/Projects/indi/src/fli/libfli-camera-parport.hZZ9devÿÿÿÿflidev_tÿÿÿÿvbinÿÿÿÿlongÿÿÿÿlong>fli_camera_parport_write_ioportt/home/slovin/Projects/indi/src/fli/libfli-camera-parport.hccBÿÿÿ€devÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿlongÿÿÿÿlongl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cÿÿÿÿdconvertl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.c?Nbsubufÿÿÿÿ void*ÿÿÿÿ double>fli_camera_usb_configure_ioportl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cÑß*devÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿlongÿÿÿÿlong<fli_camera_usb_control_bgflushl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cñ Sdevÿÿÿÿflidev_tÿÿÿÿbgflushÿÿÿÿlongÿÿÿÿlong<fli_camera_usb_control_shutterl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cáïfdevÿÿÿÿflidev_tÿÿÿÿshutterÿÿÿÿlongÿÿÿÿlong6fli_camera_usb_expose_framel/home/slovin/Projects/indi/src/fli/libfli-camera-usb.c2ˆudevÿÿÿÿflidev_tÿÿÿÿlong2fli_camera_usb_flush_rowsl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cЍRdevÿÿÿÿflidev_tÿÿÿÿrowsÿÿÿÿlongÿÿÿÿ repeatÿÿÿÿlongÿÿÿÿlong:fli_camera_usb_get_array_areal/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cú devÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿ long*ÿÿÿÿul_yÿÿÿÿ long*ÿÿÿÿlr_xÿÿÿÿ long*ÿÿÿÿlr_yÿÿÿÿ long*ÿÿÿÿlongDfli_camera_usb_get_exposure_statusl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.c¡¬ devÿÿÿÿflidev_tÿÿÿÿtimeleftÿÿÿÿ long*ÿÿÿÿlong<fli_camera_usb_get_temperaturel/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cÏÞPdevÿÿÿÿflidev_tÿÿÿÿtemperatureÿÿÿÿdouble*ÿÿÿÿlong>fli_camera_usb_get_visible_areal/home/slovin/Projects/indi/src/fli/libfli-camera-usb.c.edevÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿ long*ÿÿÿÿul_yÿÿÿÿ long*ÿÿÿÿlr_xÿÿÿÿ long*ÿÿÿÿlr_yÿÿÿÿ long*ÿÿÿÿlong.fli_camera_usb_grab_rowl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cà0Idevÿÿÿÿflidev_tÿÿÿÿbuffÿÿÿÿ void*ÿÿÿÿ widthÿÿÿÿ size_tÿÿÿÿlong&fli_camera_usb_openl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cPø'devÿÿÿÿflidev_tÿÿÿÿlong4fli_camera_usb_read_ioportl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.c°¾Sdevÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿ long*ÿÿÿÿlong8fli_camera_usb_set_bit_depthl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cª®fdevÿÿÿÿflidev_tÿÿÿÿbitdepthÿÿÿÿflibitdepth_tÿÿÿÿlong@fli_camera_usb_set_exposure_timel/home/slovin/Projects/indi/src/fli/libfli-camera-usb.c0Cedevÿÿÿÿflidev_tÿÿÿÿexptimeÿÿÿÿlongÿÿÿÿlong.fli_camera_usb_set_hbinl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cs‰)devÿÿÿÿflidev_tÿÿÿÿhbinÿÿÿÿlongÿÿÿÿlong:fli_camera_usb_set_image_areal/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cEq.devÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿlongÿÿÿÿul_yÿÿÿÿlongÿÿÿÿlr_xÿÿÿÿlongÿÿÿÿlr_yÿÿÿÿlongÿÿÿÿlong<fli_camera_usb_set_temperaturel/home/slovin/Projects/indi/src/fli/libfli-camera-usb.c®ÍIdevÿÿÿÿflidev_tÿÿÿÿtemperatureÿÿÿÿ doubleÿÿÿÿlong.fli_camera_usb_set_vbinl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.c‹Ÿodevÿÿÿÿflidev_tÿÿÿÿvbinÿÿÿÿlongÿÿÿÿlong6fli_camera_usb_write_ioportl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.cÀÏadevÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿlongÿÿÿÿlongl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hÿÿÿÿ>fli_camera_usb_configure_ioportl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.h__Bdevÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿlongÿÿÿÿlong<fli_camera_usb_control_bgflushl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.haa? )à€devÿÿÿÿflidev_tÿÿÿÿbgflushÿÿÿÿlongÿÿÿÿlong<fli_camera_usb_control_shutterl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.h``?devÿÿÿÿflidev_tÿÿÿÿshutterÿÿÿÿlongÿÿÿÿlong6fli_camera_usb_expose_framel/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hZZ.devÿÿÿÿflidev_tÿÿÿÿlong2fli_camera_usb_flush_rowsl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.h[[D devÿÿÿÿflidev_tÿÿÿÿrowsÿÿÿÿlongÿÿÿÿ repeatÿÿÿÿlongÿÿÿÿlong:fli_camera_usb_get_array_areal/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hMNadevÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿ long*ÿÿÿÿul_yÿÿÿÿ long*ÿÿÿÿlr_xÿÿÿÿ long*ÿÿÿÿlr_yÿÿÿÿ long*ÿÿÿÿlongDfli_camera_usb_get_exposure_statusl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hVVEdevÿÿÿÿflidev_tÿÿÿÿtimeleftÿÿÿÿ long*ÿÿÿÿlong<fli_camera_usb_get_temperaturel/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hXXFdevÿÿÿÿflidev_tÿÿÿÿtemperatureÿÿÿÿdouble*ÿÿÿÿlong>fli_camera_usb_get_visible_areal/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hOP îdevÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿ long*ÿÿÿÿul_yÿÿÿÿ long*ÿÿÿÿlr_xÿÿÿÿ long*ÿÿÿÿlr_yÿÿÿÿ long*ÿÿÿÿlong.fli_camera_usb_grab_rowl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hYYD ödevÿÿÿÿflidev_tÿÿÿÿbuffÿÿÿÿ void*ÿÿÿÿ widthÿÿÿÿ size_tÿÿÿÿlong&fli_camera_usb_openl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hLL&bsudevÿÿÿÿflidev_tÿÿÿÿlong4fli_camera_usb_read_ioportl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.h]]>devÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿ long*ÿÿÿÿlong8fli_camera_usb_set_bit_depthl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.h\\G€devÿÿÿÿflidev_tÿÿÿÿbitdepthÿÿÿÿflibitdepth_tÿÿÿÿlong@fli_camera_usb_set_exposure_timel/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hQQAdevÿÿÿÿflidev_tÿÿÿÿexptimeÿÿÿÿlongÿÿÿÿlong.fli_camera_usb_set_hbinl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hTT5·UÇdevÿÿÿÿflidev_tÿÿÿÿhbinÿÿÿÿlongÿÿÿÿlong:fli_camera_usb_set_image_areal/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hRS .devÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿlongÿÿÿÿul_yÿÿÿÿlongÿÿÿÿlr_xÿÿÿÿlongÿÿÿÿlr_yÿÿÿÿlongÿÿÿÿlong<fli_camera_usb_set_temperaturel/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hWWEý2devÿÿÿÿflidev_tÿÿÿÿtemperatureÿÿÿÿ doubleÿÿÿÿlong.fli_camera_usb_set_vbinl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.hUU5devÿÿÿÿflidev_tÿÿÿÿvbinÿÿÿÿlongÿÿÿÿlong6fli_camera_usb_write_ioportl/home/slovin/Projects/indi/src/fli/libfli-camera-usb.h^^>devÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿlongÿÿÿÿlongd/home/slovin/Projects/indi/src/fli/libfli-camera.cÿÿÿÿ2fli_camera_get_pixel_sized/home/slovin/Projects/indi/src/fli/libfli-camera.cQ R+fdevÿÿÿÿflidev_tÿÿÿÿpixel_xÿÿÿÿdouble*ÿÿÿÿpixel_yÿÿÿÿdouble*ÿÿÿÿlong,fli_camera_set_flushesd/home/slovin/Projects/indi/src/fli/libfli-camera.cZ Z?devÿÿÿÿflidev_tÿÿÿÿnflushesÿÿÿÿlongÿÿÿÿlong2fli_camera_set_frame_typed/home/slovin/Projects/indi/src/fli/libfli-camera.cV VI -Ždevÿÿÿÿflidev_tÿÿÿÿframetypeÿÿÿÿfliframe_tÿÿÿÿlong fli_camera_closed/home/slovin/Projects/indi/src/fli/libfli-camera.c~Ÿdevÿÿÿÿflidev_tÿÿÿÿlong$fli_camera_commandd/home/slovin/Projects/indi/src/fli/libfli-camera.c¡ïdevÿÿÿÿflidev_tÿÿÿÿcmdÿÿÿÿintÿÿÿÿargcÿÿÿÿintÿÿÿÿlong2fli_camera_get_pixel_sized/home/slovin/Projects/indi/src/fli/libfli-camera.cñû '€devÿÿÿÿflidev_tÿÿÿÿpixel_xÿÿÿÿdouble*ÿÿÿÿpixel_yÿÿÿÿdouble*ÿÿÿÿlongfli_camera_opend/home/slovin/Projects/indi/src/fli/libfli-camera.c^|devÿÿÿÿflidev_tÿÿÿÿlong,fli_camera_set_flushesd/home/slovin/Projects/indi/src/fli/libfli-camera.c devÿÿÿÿflidev_tÿÿÿÿnflushesÿÿÿÿlongÿÿÿÿlong2fli_camera_set_frame_typed/home/slovin/Projects/indi/src/fli/libfli-camera.cý  %Ì€devÿÿÿÿflidev_tÿÿÿÿframetypeÿÿÿÿfliframe_tÿÿÿÿlongknowndevd/home/slovin/Projects/indi/src/fli/libfli-camera.c8N$const fliccdinfo_td/home/slovin/Projects/indi/src/fli/libfli-camera.hÿÿÿÿ fli_camera_closed/home/slovin/Projects/indi/src/fli/libfli-camera.hmm#devÿÿÿÿflidev_tÿÿÿÿlong$fli_camera_commandd/home/slovin/Projects/indi/src/fli/libfli-camera.hnn=Tdevÿÿÿÿflidev_tÿÿÿÿcmdÿÿÿÿintÿÿÿÿargcÿÿÿÿintÿÿÿÿlongfli_camera_opend/home/slovin/Projects/indi/src/fli/libfli-camera.hll" 'èdevÿÿÿÿflidev_tÿÿÿÿlong area_td/home/slovin/Projects/indi/src/fli/libfli-camera.h88ÿÿÿÿ flicamdata_td/home/slovin/Projects/indi/src/fli/libfli-camera.hhhÿÿÿÿ fliccdinfo_td/home/slovin/Projects/indi/src/fli/libfli-camera.hDDÿÿÿÿ point_td/home/slovin/Projects/indi/src/fli/libfli-camera.h33 ÿÿÿÿb/home/slovin/Projects/indi/src/fli/libfli-debug.cÿÿÿÿ debugb/home/slovin/Projects/indi/src/fli/libfli-debug.cYb levelÿÿÿÿintÿÿÿÿ formatÿÿÿÿconst char*ÿÿÿÿvoiddebugcloseb/home/slovin/Projects/indi/src/fli/libfli-debug.cRWÿÿÿÿÿÿÿÿvoidÿÿÿÿintdebugopenb/home/slovin/Projects/indi/src/fli/libfli-debug.cKPhostÿÿÿÿ char*ÿÿÿÿintsetdebuglevelb/home/slovin/Projects/indi/src/fli/libfli-debug.ceyhostÿÿÿÿ char*ÿÿÿÿ levelÿÿÿÿintÿÿÿÿvoidsysloglevelb/home/slovin/Projects/indi/src/fli/libfli-debug.c2I levelÿÿÿÿintÿÿÿÿintb/home/slovin/Projects/indi/src/fli/libfli-debug.hÿÿÿÿ debugb/home/slovin/Projects/indi/src/fli/libfli-debug.h33. levelÿÿÿÿintÿÿÿÿ formatÿÿÿÿconst char*ÿÿÿÿvoiddebugcloseb/home/slovin/Projects/indi/src/fli/libfli-debug.h11 +Á€ÿÿÿÿÿÿÿÿvoidÿÿÿÿintdebugopenb/home/slovin/Projects/indi/src/fli/libfli-debug.h22ihostÿÿÿÿ char*ÿÿÿÿintsetdebuglevelb/home/slovin/Projects/indi/src/fli/libfli-debug.h44)hostÿÿÿÿ char*ÿÿÿÿ levelÿÿÿÿintÿÿÿÿvoidt/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.cÿÿÿÿfli_getsteppost/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.c[ [3pdevÿÿÿÿflidev_tÿÿÿÿposÿÿÿÿ long*ÿÿÿÿlong fli_setfilterpost/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.c\ \4odevÿÿÿÿflidev_tÿÿÿÿposÿÿÿÿlongÿÿÿÿlongfli_stepmotort/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.cZ Z3cofdevÿÿÿÿflidev_tÿÿÿÿ stepsÿÿÿÿlongÿÿÿÿlong$fli_filter_commandt/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.cA’devÿÿÿÿflidev_tÿÿÿÿcmdÿÿÿÿintÿÿÿÿargcÿÿÿÿintÿÿÿÿlong0fli_filter_focuser_closet/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.c.? devÿÿÿÿflidev_tÿÿÿÿlong.fli_filter_focuser_opent/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.c_,¶ÛQdevÿÿÿÿflidev_tÿÿÿÿlong&fli_focuser_commandt/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.c”Ädevÿÿÿÿflidev_tÿÿÿÿcmdÿÿÿÿintÿÿÿÿargcÿÿÿÿintÿÿÿÿlongfli_getsteppost/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.c )devÿÿÿÿflidev_tÿÿÿÿposÿÿÿÿ long*ÿÿÿÿlong fli_setfilterpost/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.c,rdevÿÿÿÿflidev_tÿÿÿÿposÿÿÿÿlongÿÿÿÿlongfli_stepmotort/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.cÆ devÿÿÿÿflidev_tÿÿÿÿ stepsÿÿÿÿlongÿÿÿÿlongwheeldatat/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.cEX"const wheeldata_tt/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.hÿÿÿÿ$fli_filter_commandt/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.hGG=devÿÿÿÿflidev_tÿÿÿÿcmdÿÿÿÿintÿÿÿÿargcÿÿÿÿintÿÿÿÿlong0fli_filter_focuser_closet/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.hCC+ndevÿÿÿÿflidev_tÿÿÿÿlong.fli_filter_focuser_opent/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.h??*cofdevÿÿÿÿflidev_tÿÿÿÿlong&fli_focuser_commandt/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.hHH>devÿÿÿÿflidev_tÿÿÿÿcmdÿÿÿÿintÿÿÿÿargcÿÿÿÿintÿÿÿÿlong flifilterdata_tt/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.h77ÿÿÿÿ wheeldata_tt/home/slovin/Projects/indi/src/fli/libfli-filter-focuser.h== ÿÿÿÿd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÿÿÿÿ&FLI_CANCEL_EXPOSUREd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄ/ÄBint(FLI_CONFIGURE_IOPORTd/home/slovin/Projects/indi/src/fli/libfli-libfli.hĪľint&FLI_CONTROL_BGFLUSHd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄ'Ä:int&FLI_CONTROL_SHUTTERd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄéÄüint FLI_EXPOSE_FRAMEd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄ\ÄlintFLI_FLUSH_ROWSd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄ’Ä int$FLI_GET_ARRAY_AREAd/home/slovin/Projects/indi/src/fli/libfli-libfli.hĘĪint.FLI_GET_EXPOSURE_STATUSd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄqĈint(FLI_GET_FILTER_COUNTd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄÞÄòint$FLI_GET_FILTER_POSd/home/slovin/Projects/indi/src/fli/libfli-libfli.hĠIJint$FLI_GET_PIXEL_SIZEd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄ\Änint&FLI_GET_STEPPER_POSd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄQÄdint&FLI_GET_TEMPERATUREd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄñÄint(FLI_GET_VISIBLE_AREAd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄÖÄêintFLI_GRAB_ROWd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄ(Ä4int FLI_HOME_FOCUSERd/home/slovin/Projects/indi/src/fli/libfli-libfli.hČĜintFLI_NONEd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄ*Ä2intFLI_READ_IOPORTd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄ7ÄFint"FLI_SET_BIT_DEPTHd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄÿÄint*FLI_SET_EXPOSURE_TIMEd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄÄ,int$FLI_SET_FILTER_POSd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄdÄvintFLI_SET_FLUSHESd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄÇÄÖint$FLI_SET_FRAME_TYPEd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄòÄintFLI_SET_HBINd/home/slovin/Projects/indi/src/fli/libfli-libfli.hČĘint$FLI_SET_IMAGE_AREAd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄVÄhint&FLI_SET_TEMPERATUREd/home/slovin/Projects/indi/src/fli/libfli-libfli.hijįintFLI_SET_VBINd/home/slovin/Projects/indi/src/fli/libfli-libfli.hļÄÈintFLI_STEP_MOTORd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄÄ&int FLI_WRITE_IOPORTd/home/slovin/Projects/indi/src/fli/libfli-libfli.hÄnÄ~int flidevdesc_td/home/slovin/Projects/indi/src/fli/libfli-libfli.hššÿÿÿÿ flidevinfo_td/home/slovin/Projects/indi/src/fli/libfli-libfli.hƒƒÿÿÿÿ^/home/slovin/Projects/indi/src/fli/libfli-mem.cÿÿÿÿ(libfli-mem_0)^/home/slovin/Projects/indi/src/fli/libfli-mem.c59pointers^/home/slovin/Projects/indi/src/fli/libfli-mem.c66 void** total^/home/slovin/Projects/indi/src/fli/libfli-mem.c77 intused^/home/slovin/Projects/indi/src/fli/libfli-mem.c88 intxcalloc^/home/slovin/Projects/indi/src/fli/libfli-mem.cis :€ nmembÿÿÿÿ size_tÿÿÿÿsizeÿÿÿÿ size_tÿÿÿÿ void* xfree^/home/slovin/Projects/indi/src/fli/libfli-mem.cuˆ &€ptrÿÿÿÿ void*ÿÿÿÿvoidxfree_all^/home/slovin/Projects/indi/src/fli/libfli-mem.c¢½ÿÿÿÿÿÿÿÿvoidÿÿÿÿintxmalloc^/home/slovin/Projects/indi/src/fli/libfli-mem.c;f '[€sizeÿÿÿÿ size_tÿÿÿÿ void*xrealloc^/home/slovin/Projects/indi/src/fli/libfli-mem.cŠ ptrÿÿÿÿ void*ÿÿÿÿsizeÿÿÿÿ size_tÿÿÿÿ void*xstrdup^/home/slovin/Projects/indi/src/fli/libfli-mem.c¿Ìsÿÿÿÿconst char*ÿÿÿÿ char*allocated^/home/slovin/Projects/indi/src/fli/libfli-mem.c99ÿÿÿÿ^/home/slovin/Projects/indi/src/fli/libfli-mem.hÿÿÿÿxcalloc^/home/slovin/Projects/indi/src/fli/libfli-mem.h11( nmembÿÿÿÿ size_tÿÿÿÿsizeÿÿÿÿ size_tÿÿÿÿ void* xfree^/home/slovin/Projects/indi/src/fli/libfli-mem.h22ptrÿÿÿÿ void*ÿÿÿÿvoidxfree_all^/home/slovin/Projects/indi/src/fli/libfli-mem.h44ÿÿÿÿÿÿÿÿvoidÿÿÿÿintxmalloc^/home/slovin/Projects/indi/src/fli/libfli-mem.h00sizeÿÿÿÿ size_tÿÿÿÿ void*xrealloc^/home/slovin/Projects/indi/src/fli/libfli-mem.h33&ptrÿÿÿÿ void*ÿÿÿÿsizeÿÿÿÿ size_tÿÿÿÿ void*xstrdup^/home/slovin/Projects/indi/src/fli/libfli-mem.h55sÿÿÿÿconst char*ÿÿÿÿ char*f/home/slovin/Projects/indi/src/fli/libfli-parport.hÿÿÿÿ(unix_parportio_linuxf/home/slovin/Projects/indi/src/fli/libfli-parport.h??Jdevÿÿÿÿflidev_tÿÿÿÿbufÿÿÿÿ void*ÿÿÿÿwlenÿÿÿÿ long*ÿÿÿÿrlenÿÿÿÿ long*ÿÿÿÿlongd/home/slovin/Projects/indi/src/fli/libfli-serial.cÿÿÿÿunix_serialiod/home/slovin/Projects/indi/src/fli/libfli-serial.c:¾devÿÿÿÿflidev_tÿÿÿÿbufÿÿÿÿ void*ÿÿÿÿwlenÿÿÿÿ long*ÿÿÿÿrlenÿÿÿÿ long*ÿÿÿÿlongd/home/slovin/Projects/indi/src/fli/libfli-serial.hÿÿÿÿunix_serialiod/home/slovin/Projects/indi/src/fli/libfli-serial.h22Cdevÿÿÿÿflidev_tÿÿÿÿbufÿÿÿÿ void*ÿÿÿÿwlenÿÿÿÿ long*ÿÿÿÿrlenÿÿÿÿ long*ÿÿÿÿlong^/home/slovin/Projects/indi/src/fli/libfli-sys.cÿÿÿÿ*unix_fli_list_parport^/home/slovin/Projects/indi/src/fli/libfli-sys.cH HDs domainÿÿÿÿflidomain_tÿÿÿÿ namesÿÿÿÿchar***ÿÿÿÿlong(unix_fli_list_serial^/home/slovin/Projects/indi/src/fli/libfli-sys.cJ JC domainÿÿÿÿflidomain_tÿÿÿÿ namesÿÿÿÿchar***ÿÿÿÿlong"unix_fli_list_usb^/home/slovin/Projects/indi/src/fli/libfli-sys.cI I@ domainÿÿÿÿflidomain_tÿÿÿÿ namesÿÿÿÿchar***ÿÿÿÿlong  unix_fli_connect^/home/slovin/Projects/indi/src/fli/libfli-sys.cP©devÿÿÿÿflidev_tÿÿÿÿnameÿÿÿÿ char*ÿÿÿÿ domainÿÿÿÿlongÿÿÿÿlong&unix_fli_disconnect^/home/slovin/Projects/indi/src/fli/libfli-sys.c«Êdevÿÿÿÿflidev_tÿÿÿÿlongunix_fli_list^/home/slovin/Projects/indi/src/fli/libfli-sys.cn† domainÿÿÿÿflidomain_tÿÿÿÿ namesÿÿÿÿchar***ÿÿÿÿlong$unix_fli_list_glob^/home/slovin/Projects/indi/src/fli/libfli-sys.cˆÈ !patternÿÿÿÿ char*ÿÿÿÿ domainÿÿÿÿflidomain_tÿÿÿÿ namesÿÿÿÿchar***ÿÿÿÿlong*unix_fli_list_parport^/home/slovin/Projects/indi/src/fli/libfli-sys.cÓÖ domainÿÿÿÿflidomain_tÿÿÿÿ namesÿÿÿÿchar***ÿÿÿÿlong(unix_fli_list_serial^/home/slovin/Projects/indi/src/fli/libfli-sys.cßâ domainÿÿÿÿflidomain_tÿÿÿÿ namesÿÿÿÿchar***ÿÿÿÿlong"unix_fli_list_usb^/home/slovin/Projects/indi/src/fli/libfli-sys.cÚÝi domainÿÿÿÿflidomain_tÿÿÿÿ namesÿÿÿÿchar***ÿÿÿÿlongunix_fli_lock^/home/slovin/Projects/indi/src/fli/libfli-sys.cìCdevÿÿÿÿflidev_tÿÿÿÿlongunix_fli_unlock^/home/slovin/Projects/indi/src/fli/libfli-sys.cEh *devÿÿÿÿflidev_tÿÿÿÿlong^/home/slovin/Projects/indi/src/fli/libfli-sys.hÿÿÿÿ unix_fli_connect^/home/slovin/Projects/indi/src/fli/libfli-sys.hll<devÿÿÿÿflidev_tÿÿÿÿnameÿÿÿÿ char*ÿÿÿÿ domainÿÿÿÿlongÿÿÿÿlong&unix_fli_disconnect^/home/slovin/Projects/indi/src/fli/libfli-sys.hmm&devÿÿÿÿflidev_tÿÿÿÿlongunix_fli_list^/home/slovin/Projects/indi/src/fli/libfli-sys.hpp5 *z domainÿÿÿÿflidomain_tÿÿÿÿ namesÿÿÿÿchar***ÿÿÿÿlongunix_fli_lock^/home/slovin/Projects/indi/src/fli/libfli-sys.hnn bdevÿÿÿÿflidev_tÿÿÿÿlongunix_fli_unlock^/home/slovin/Projects/indi/src/fli/libfli-sys.hoo"devÿÿÿÿflidev_tÿÿÿÿlong fli_unixio_t^/home/slovin/Projects/indi/src/fli/libfli-sys.hjjÿÿÿÿ^/home/slovin/Projects/indi/src/fli/libfli-usb.cÿÿÿÿunix_usbio^/home/slovin/Projects/indi/src/fli/libfli-usb.c4_devÿÿÿÿflidev_tÿÿÿÿbufÿÿÿÿ void*ÿÿÿÿwlenÿÿÿÿ long*ÿÿÿÿrlenÿÿÿÿ long*ÿÿÿÿlong^/home/slovin/Projects/indi/src/fli/libfli-usb.hÿÿÿÿnull_bulkread^/home/slovin/Projects/indi/src/fli/libfli-usb.hBBEdevÿÿÿÿflidev_tÿÿÿÿbufÿÿÿÿ void*ÿÿÿÿrlenÿÿÿÿ long*ÿÿÿÿlongnull_bulkwrite^/home/slovin/Projects/indi/src/fli/libfli-usb.hAAG [devÿÿÿÿflidev_tÿÿÿÿbufÿÿÿÿ void*ÿÿÿÿwlenÿÿÿÿ long*ÿÿÿÿlongunix_usbio^/home/slovin/Projects/indi/src/fli/libfli-usb.hCC@devÿÿÿÿflidev_tÿÿÿÿbufÿÿÿÿ void*ÿÿÿÿwlenÿÿÿÿ long*ÿÿÿÿrlenÿÿÿÿ long*ÿÿÿÿlong0unix_usbverifydescriptor^/home/slovin/Projects/indi/src/fli/libfli-usb.hDD=devÿÿÿÿflidev_tÿÿÿÿioÿÿÿÿfli_unixio_t*ÿÿÿÿlongV/home/slovin/Projects/indi/src/fli/libfli.cÿÿÿÿdevallocV/home/slovin/Projects/indi/src/fli/libfli.c5 5#0devÿÿÿÿflidev_t*ÿÿÿÿlongdevfreeV/home/slovin/Projects/indi/src/fli/libfli.c6 6!ndevÿÿÿÿflidev_tÿÿÿÿlongfli_closeV/home/slovin/Projects/indi/src/fli/libfli.c8 8#rdevÿÿÿÿflidev_tÿÿÿÿlongfli_freelistV/home/slovin/Projects/indi/src/fli/libfli.c9 9& & namesÿÿÿÿ char**ÿÿÿÿlongfli_openV/home/slovin/Projects/indi/src/fli/libfli.c7 7<devÿÿÿÿflidev_t*ÿÿÿÿnameÿÿÿÿ char*ÿÿÿÿ domainÿÿÿÿlongÿÿÿÿlong1"FLICancelExposureV/home/slovin/Projects/indi/src/fli/libfli.cy~ "n€devÿÿÿÿflidev_tÿÿÿÿLIBFLIAPIFLICloseV/home/slovin/Projects/indi/src/fli/libfli.c .»€devÿÿÿÿflidev_tÿÿÿÿLIBFLIAPI$FLIConfigureIOPortV/home/slovin/Projects/indi/src/fli/libfli.cƒ‰devÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿlongÿÿÿÿLIBFLIAPI2FLIControlBackgroundFlushV/home/slovin/Projects/indi/src/fli/libfli.càåfdevÿÿÿÿflidev_tÿÿÿÿbgflushÿÿÿÿflibgflush_tÿÿÿÿLIBFLIAPI"FLIControlShutterV/home/slovin/Projects/indi/src/fli/libfli.cÆË "+€devÿÿÿÿflidev_tÿÿÿÿshutterÿÿÿÿflishutter_tÿÿÿÿLIBFLIAPIFLICreateListV/home/slovin/Projects/indi/src/fli/libfli.c©ýr domainÿÿÿÿflidomain_tÿÿÿÿLIBFLIAPIFLIDeleteListV/home/slovin/Projects/indi/src/fli/libfli.c gÿÿÿÿÿÿÿÿvoidÿÿÿÿLIBFLIAPIFLIExposeFrameV/home/slovin/Projects/indi/src/fli/libfli.cöû·UÇdevÿÿÿÿflidev_tÿÿÿÿLIBFLIAPIFLIFlushRowV/home/slovin/Projects/indi/src/fli/libfli.c devÿÿÿÿflidev_tÿÿÿÿrowsÿÿÿÿlongÿÿÿÿ repeatÿÿÿÿlongÿÿÿÿLIBFLIAPIFLIFreeListV/home/slovin/Projects/indi/src/fli/libfli.cW namesÿÿÿÿ char**ÿÿÿÿLIBFLIAPIFLIGetArrayAreaV/home/slovin/Projects/indi/src/fli/libfli.c°·devÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿ long*ÿÿÿÿul_yÿÿÿÿ long*ÿÿÿÿlr_xÿÿÿÿ long*ÿÿÿÿlr_yÿÿÿÿ long*ÿÿÿÿLIBFLIAPI(FLIGetExposureStatusV/home/slovin/Projects/indi/src/fli/libfli.c•devÿÿÿÿflidev_tÿÿÿÿtimeleftÿÿÿÿ long*ÿÿÿÿLIBFLIAPI FLIGetFWRevisionV/home/slovin/Projects/indi/src/fli/libfli.c‹‘devÿÿÿÿflidev_tÿÿÿÿ fwrevÿÿÿÿ long*ÿÿÿÿLIBFLIAPI"FLIGetFilterCountV/home/slovin/Projects/indi/src/fli/libfli.cKPodevÿÿÿÿflidev_tÿÿÿÿ filterÿÿÿÿ long*ÿÿÿÿLIBFLIAPIFLIGetFilterPosV/home/slovin/Projects/indi/src/fli/libfli.c8=Idevÿÿÿÿflidev_tÿÿÿÿ filterÿÿÿÿ long*ÿÿÿÿLIBFLIAPI FLIGetHWRevisionV/home/slovin/Projects/indi/src/fli/libfli.ctz ¢€devÿÿÿÿflidev_tÿÿÿÿ hwrevÿÿÿÿ long*ÿÿÿÿLIBFLIAPI FLIGetLibVersionV/home/slovin/Projects/indi/src/fli/libfli.c"verÿÿÿÿ char*ÿÿÿÿlenÿÿÿÿ size_tÿÿÿÿLIBFLIAPIFLIGetModelV/home/slovin/Projects/indi/src/fli/libfli.c9Jodevÿÿÿÿflidev_tÿÿÿÿ modelÿÿÿÿ char*ÿÿÿÿlenÿÿÿÿ size_tÿÿÿÿLIBFLIAPIFLIGetPixelSizeV/home/slovin/Projects/indi/src/fli/libfli.c]c ¤devÿÿÿÿflidev_tÿÿÿÿpixel_xÿÿÿÿdouble*ÿÿÿÿpixel_yÿÿÿÿdouble*ÿÿÿÿLIBFLIAPI*FLIGetStepperPositionV/home/slovin/Projects/indi/src/fli/libfli.cv{=devÿÿÿÿflidev_tÿÿÿÿpositionÿÿÿÿ long*ÿÿÿÿLIBFLIAPI"FLIGetTemperatureV/home/slovin/Projects/indi/src/fli/libfli.c¼Á "R€devÿÿÿÿflidev_tÿÿÿÿtemperatureÿÿÿÿdouble*ÿÿÿÿLIBFLIAPI"FLIGetVisibleAreaV/home/slovin/Projects/indi/src/fli/libfli.c×Þ6devÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿ long*ÿÿÿÿul_yÿÿÿÿ long*ÿÿÿÿlr_xÿÿÿÿ long*ÿÿÿÿlr_yÿÿÿÿ long*ÿÿÿÿLIBFLIAPIFLIGrabFrameV/home/slovin/Projects/indi/src/fli/libfli.c¹¾devÿÿÿÿflidev_tÿÿÿÿbuffÿÿÿÿ void*ÿÿÿÿbuffsizeÿÿÿÿ size_tÿÿÿÿbytesgrabbedÿÿÿÿsize_t*ÿÿÿÿLIBFLIAPIFLIGrabRowV/home/slovin/Projects/indi/src/fli/libfli.c×Ü "+devÿÿÿÿflidev_tÿÿÿÿbuffÿÿÿÿ void*ÿÿÿÿ widthÿÿÿÿ size_tÿÿÿÿLIBFLIAPIFLIHomeFocuserV/home/slovin/Projects/indi/src/fli/libfli.c†‹)devÿÿÿÿflidev_tÿÿÿÿLIBFLIAPIFLIListV/home/slovin/Projects/indi/src/fli/libfli.cÿw domainÿÿÿÿflidomain_tÿÿÿÿ namesÿÿÿÿchar***ÿÿÿÿLIBFLIAPIFLIListFirstV/home/slovin/Projects/indi/src/fli/libfli.c7<m domainÿÿÿÿflidomain_t*ÿÿÿÿfilenameÿÿÿÿ char*ÿÿÿÿ fnlenÿÿÿÿ size_tÿÿÿÿnameÿÿÿÿ char*ÿÿÿÿnamelenÿÿÿÿ size_tÿÿÿÿLIBFLIAPIFLIListNextV/home/slovin/Projects/indi/src/fli/libfli.cUht domainÿÿÿÿflidomain_t*ÿÿÿÿfilenameÿÿÿÿ char*ÿÿÿÿ fnlenÿÿÿÿ size_tÿÿÿÿnameÿÿÿÿ char*ÿÿÿÿnamelenÿÿÿÿ size_tÿÿÿÿLIBFLIAPIFLILockDeviceV/home/slovin/Projects/indi/src/fli/libfli.c—œdevÿÿÿÿflidev_tÿÿÿÿLIBFLIAPIFLIOpenV/home/slovin/Projects/indi/src/fli/libfli.cßâ€devÿÿÿÿflidev_t*ÿÿÿÿnameÿÿÿÿ char*ÿÿÿÿ domainÿÿÿÿflidomain_tÿÿÿÿLIBFLIAPIFLIReadIOPortV/home/slovin/Projects/indi/src/fli/libfli.cSXdevÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿ long*ÿÿÿÿLIBFLIAPIFLISetBitDepthV/home/slovin/Projects/indi/src/fli/libfli.c=Bdevÿÿÿÿflidev_tÿÿÿÿbitdepthÿÿÿÿflibitdepth_tÿÿÿÿLIBFLIAPI FLISetDebugLevelV/home/slovin/Projects/indi/src/fli/libfli.cõù hostÿÿÿÿ char*ÿÿÿÿ levelÿÿÿÿflidebug_tÿÿÿÿLIBFLIAPI$FLISetExposureTimeV/home/slovin/Projects/indi/src/fli/libfli.cïôdevÿÿÿÿflidev_tÿÿÿÿexptimeÿÿÿÿlongÿÿÿÿLIBFLIAPIFLISetFilterPosV/home/slovin/Projects/indi/src/fli/libfli.c#(Edevÿÿÿÿflidev_tÿÿÿÿ filterÿÿÿÿlongÿÿÿÿLIBFLIAPIFLISetFrameTypeV/home/slovin/Projects/indi/src/fli/libfli.cejNdevÿÿÿÿflidev_tÿÿÿÿframetypeÿÿÿÿfliframe_tÿÿÿÿLIBFLIAPIFLISetHBinV/home/slovin/Projects/indi/src/fli/libfli.c6;devÿÿÿÿflidev_tÿÿÿÿhbinÿÿÿÿlongÿÿÿÿLIBFLIAPIFLISetImageAreaV/home/slovin/Projects/indi/src/fli/libfli.c$devÿÿÿÿflidev_tÿÿÿÿul_xÿÿÿÿlongÿÿÿÿul_yÿÿÿÿlongÿÿÿÿlr_xÿÿÿÿlongÿÿÿÿlr_yÿÿÿÿlongÿÿÿÿLIBFLIAPIFLISetNFlushesV/home/slovin/Projects/indi/src/fli/libfli.c$)devÿÿÿÿflidev_tÿÿÿÿnflushesÿÿÿÿlongÿÿÿÿLIBFLIAPI"FLISetTemperatureV/home/slovin/Projects/indi/src/fli/libfli.c¦¬devÿÿÿÿflidev_tÿÿÿÿtemperatureÿÿÿÿ doubleÿÿÿÿLIBFLIAPIFLISetVBinV/home/slovin/Projects/indi/src/fli/libfli.cMRNdevÿÿÿÿflidev_tÿÿÿÿvbinÿÿÿÿlongÿÿÿÿLIBFLIAPIFLIStepMotorV/home/slovin/Projects/indi/src/fli/libfli.c`emdevÿÿÿÿflidev_tÿÿÿÿ stepsÿÿÿÿlongÿÿÿÿLIBFLIAPIFLIUnlockDeviceV/home/slovin/Projects/indi/src/fli/libfli.cª¯wdevÿÿÿÿflidev_tÿÿÿÿLIBFLIAPIFLIWriteIOPortV/home/slovin/Projects/indi/src/fli/libfli.chm·UÇdevÿÿÿÿflidev_tÿÿÿÿioportsetÿÿÿÿlongÿÿÿÿLIBFLIAPIdevallocV/home/slovin/Projects/indi/src/fli/libfli.c@Udevÿÿÿÿflidev_t*ÿÿÿÿlongdevfreeV/home/slovin/Projects/indi/src/fli/libfli.cWxdevÿÿÿÿflidev_tÿÿÿÿlongfli_closeV/home/slovin/Projects/indi/src/fli/libfli.cŸ©devÿÿÿÿflidev_tÿÿÿÿlongfli_freelistV/home/slovin/Projects/indi/src/fli/libfli.c«· /? namesÿÿÿÿ char**ÿÿÿÿlongfli_openV/home/slovin/Projects/indi/src/fli/libfli.cz /=devÿÿÿÿflidev_t*ÿÿÿÿnameÿÿÿÿ char*ÿÿÿÿ domainÿÿÿÿlongÿÿÿÿlongcurrentdeviceV/home/slovin/Projects/indi/src/fli/libfli.c——#list_t*devicesV/home/slovin/Projects/indi/src/fli/libfli.c; ;1flidevdesc_t*firstdeviceV/home/slovin/Projects/indi/src/fli/libfli.c––!list_t* list_tV/home/slovin/Projects/indi/src/fli/libfli.c””listV/home/slovin/Projects/indi/src/fli/libfli.hÿÿÿÿ flibgflush_tV/home/slovin/Projects/indi/src/fli/libfli.h long flibitdepth_tV/home/slovin/Projects/indi/src/fli/libfli.ha along flidebug_tV/home/slovin/Projects/indi/src/fli/libfli.h‹ ‹long flidev_tV/home/slovin/Projects/indi/src/fli/libfli.h6 6long flidomain_tV/home/slovin/Projects/indi/src/fli/libfli.hC Clong fliframe_tV/home/slovin/Projects/indi/src/fli/libfli.hV Vlong flishutter_tV/home/slovin/Projects/indi/src/fli/libfli.hp plongF/home/slovin/Projects/indi/src/fq.cÿÿÿÿ_FQF/home/slovin/Projects/indi/src/fq.c$*growF/home/slovin/Projects/indi/src/fq.c)) intheadF/home/slovin/Projects/indi/src/fq.c'' intnmemF/home/slovin/Projects/indi/src/fq.c(( intnqF/home/slovin/Projects/indi/src/fq.c&& intqF/home/slovin/Projects/indi/src/fq.c% % void** chkFQF/home/slovin/Projects/indi/src/fq.c1 1qÿÿÿÿFQ*ÿÿÿÿvoid chkFQF/home/slovin/Projects/indi/src/fq.cu†rqÿÿÿÿFQ*ÿÿÿÿvoid delFQF/home/slovin/Projects/indi/src/fq.cBGqÿÿÿÿFQ*ÿÿÿÿvoidnFQF/home/slovin/Projects/indi/src/fq.cae€qÿÿÿÿFQ*ÿÿÿÿint newFQF/home/slovin/Projects/indi/src/fq.c7?growÿÿÿÿintÿÿÿÿFQ* peekFQF/home/slovin/Projects/indi/src/fq.cZ^ qÿÿÿÿFQ*ÿÿÿÿ void* popFQF/home/slovin/Projects/indi/src/fq.cSWqÿÿÿÿFQ*ÿÿÿÿ void* pushFQF/home/slovin/Projects/indi/src/fq.cJPqÿÿÿÿFQ*ÿÿÿÿeÿÿÿÿ void*ÿÿÿÿvoidsetMemFuncsFQF/home/slovin/Projects/indi/src/fq.cjr8(* newmalloc)( size_t size )ÿÿÿÿ void*ÿÿÿÿR(* newrealloc)( void * ptr, size_t size )ÿÿÿÿ void*ÿÿÿÿ2(* newfree)( void * ptr )ÿÿÿÿvoidÿÿÿÿvoid myfreeF/home/slovin/Projects/indi/src/fq.c/ /'voidmymallocF/home/slovin/Projects/indi/src/fq.c- -. void*myreallocF/home/slovin/Projects/indi/src/fq.c. .; void*F/home/slovin/Projects/indi/src/fq.hÿÿÿÿ FQF/home/slovin/Projects/indi/src/fq.hstruct _FQP/home/slovin/Projects/indi/src/indiapi.hÿÿÿÿ IBLOBP/home/slovin/Projects/indi/src/indiapi.hOOÿÿÿÿ &IBLOBVectorPropertyP/home/slovin/Projects/indi/src/indiapi.hll(_IBLOBVectorProperty ILightP/home/slovin/Projects/indi/src/indiapi.h!!ÿÿÿÿ (ILightVectorPropertyP/home/slovin/Projects/indi/src/indiapi.h99*_ILightVectorProperty INumberP/home/slovin/Projects/indi/src/indiapi.hÃà ÿÿÿÿ *INumberVectorPropertyP/home/slovin/Projects/indi/src/indiapi.híí,_INumberVectorProperty IPStateP/home/slovin/Projects/indi/src/indiapi.hYY ÿÿÿÿ IPermP/home/slovin/Projects/indi/src/indiapi.hggÿÿÿÿ ISRuleP/home/slovin/Projects/indi/src/indiapi.h``ÿÿÿÿ ISStateP/home/slovin/Projects/indi/src/indiapi.hRR ÿÿÿÿ ISwitchP/home/slovin/Projects/indi/src/indiapi.høø ÿÿÿÿ *ISwitchVectorPropertyP/home/slovin/Projects/indi/src/indiapi.h,_ISwitchVectorProperty ITextP/home/slovin/Projects/indi/src/indiapi.h™™ÿÿÿÿ &ITextVectorPropertyP/home/slovin/Projects/indi/src/indiapi.hµµ(_ITextVectorPropertyP/home/slovin/Projects/indi/src/indicom.cÿÿÿÿDegToRadP/home/slovin/Projects/indi/src/indicom.c11numÿÿÿÿ doubleÿÿÿÿ doubleRadToDegP/home/slovin/Projects/indi/src/indicom.c22numÿÿÿÿ doubleÿÿÿÿ double SinCosP/home/slovin/Projects/indi/src/indicom.c339Degreesÿÿÿÿ doubleÿÿÿÿsinaÿÿÿÿdouble*ÿÿÿÿcosaÿÿÿÿdouble*ÿÿÿÿvoidaberrateP/home/slovin/Projects/indi/src/indicom.cDD&RAÿÿÿÿdouble*ÿÿÿÿDecÿÿÿÿdouble*ÿÿÿÿvoidapparentCoordP/home/slovin/Projects/indi/src/indicom.cFFCjd0ÿÿÿÿ doubleÿÿÿÿjdfÿÿÿÿ doubleÿÿÿÿRAÿÿÿÿdouble*ÿÿÿÿDecÿÿÿÿdouble*ÿÿÿÿvoidconstAberrP/home/slovin/Projects/indi/src/indicom.c66ÿÿÿÿÿÿÿÿvoidÿÿÿÿ doubledEcLongP/home/slovin/Projects/indi/src/indicom.c>>ÿÿÿÿÿÿÿÿvoidÿÿÿÿ double dObliqP/home/slovin/Projects/indi/src/indicom.c==ÿÿÿÿÿÿÿÿvoidÿÿÿÿ double"earthEccentricityP/home/slovin/Projects/indi/src/indicom.c<<ÿÿÿÿÿÿÿÿvoidÿÿÿÿ double0earthPerihelionLongitudeP/home/slovin/Projects/indi/src/indicom.c;;%ÿÿÿÿÿÿÿÿvoidÿÿÿÿ double getSexComponentsP/home/slovin/Projects/indi/src/indicom.cGG; valueÿÿÿÿ doubleÿÿÿÿdÿÿÿÿint*ÿÿÿÿmÿÿÿÿint*ÿÿÿÿsÿÿÿÿint*ÿÿÿÿvoidjulianCenturiesP/home/slovin/Projects/indi/src/indicom.c??ÿÿÿÿÿÿÿÿvoidÿÿÿÿ double nutateP/home/slovin/Projects/indi/src/indicom.cCC$RAÿÿÿÿdouble*ÿÿÿÿDecÿÿÿÿdouble*ÿÿÿÿvoidobliquityP/home/slovin/Projects/indi/src/indicom.c55ÿÿÿÿÿÿÿÿvoidÿÿÿÿ doublep1P/home/slovin/Projects/indi/src/indicom.c@@i1ÿÿÿÿintÿÿÿÿi2ÿÿÿÿintÿÿÿÿ doublep2P/home/slovin/Projects/indi/src/indicom.cAAi1ÿÿÿÿintÿÿÿÿi2ÿÿÿÿintÿÿÿÿ double&precessFromAnyEpochP/home/slovin/Projects/indi/src/indicom.cEEIjd0ÿÿÿÿ doubleÿÿÿÿjdfÿÿÿÿ doubleÿÿÿÿRAÿÿÿÿdouble*ÿÿÿÿDecÿÿÿÿdouble*ÿÿÿÿvoidsunMeanAnomalyP/home/slovin/Projects/indi/src/indicom.c77ÿÿÿÿÿÿÿÿvoidÿÿÿÿ double sunMeanLongitudeP/home/slovin/Projects/indi/src/indicom.c88ÿÿÿÿÿÿÿÿvoidÿÿÿÿ doublesunTrueAnomalyP/home/slovin/Projects/indi/src/indicom.c99ÿÿÿÿÿÿÿÿvoidÿÿÿÿ double sunTrueLongitudeP/home/slovin/Projects/indi/src/indicom.c::ÿÿÿÿÿÿÿÿvoidÿÿÿÿ double"updateAstroValuesP/home/slovin/Projects/indi/src/indicom.cBB#jdÿÿÿÿ doubleÿÿÿÿvoid(DegToRadP/home/slovin/Projects/indi/src/indicom.cÄÈnumÿÿÿÿ doubleÿÿÿÿ doubleJDtoGMSTP/home/slovin/Projects/indi/src/indicom.c½Ìjdÿÿÿÿ doubleÿÿÿÿ doubleRadToDegP/home/slovin/Projects/indi/src/indicom.cÊÍnumÿÿÿÿ doubleÿÿÿÿ double SinCosP/home/slovin/Projects/indi/src/indicom.cÏôDegreesÿÿÿÿ doubleÿÿÿÿsinaÿÿÿÿdouble*ÿÿÿÿcosaÿÿÿÿdouble*ÿÿÿÿvoid UTtoJDP/home/slovin/Projects/indi/src/indicom.c‡»utmÿÿÿÿstruct tm*ÿÿÿÿ doubleaberrateP/home/slovin/Projects/indi/src/indicom.c!=RAÿÿÿÿdouble*ÿÿÿÿDecÿÿÿÿdouble*ÿÿÿÿvoidangularDistanceP/home/slovin/Projects/indi/src/indicom.cds fromRAÿÿÿÿ doubleÿÿÿÿfromDECÿÿÿÿ doubleÿÿÿÿtoRAÿÿÿÿ doubleÿÿÿÿ toDECÿÿÿÿ doubleÿÿÿÿ doubleapparentCoordP/home/slovin/Projects/indi/src/indicom.cy…jd0ÿÿÿÿ doubleÿÿÿÿjdfÿÿÿÿ doubleÿÿÿÿRAÿÿÿÿdouble*ÿÿÿÿDecÿÿÿÿdouble*ÿÿÿÿvoidcalculateDecP/home/slovin/Projects/indi/src/indicom.cöülatitudeÿÿÿÿ doubleÿÿÿÿ SDTimeÿÿÿÿ doubleÿÿÿÿ doublecalculateRAP/home/slovin/Projects/indi/src/indicom.cþ SDTimeÿÿÿÿ doubleÿÿÿÿ doubleconstAberrP/home/slovin/Projects/indi/src/indicom.cRR! doubledEcLongP/home/slovin/Projects/indi/src/indicom.cZZ( double dObliqP/home/slovin/Projects/indi/src/indicom.cYY* double"earthEccentricityP/home/slovin/Projects/indi/src/indicom.cXX( double0earthPerihelionLongitudeP/home/slovin/Projects/indi/src/indicom.cWW/ doubleextractISOTimeP/home/slovin/Projects/indi/src/indicom.cÎÜtimestrÿÿÿÿ char*ÿÿÿÿutmÿÿÿÿstruct tm*ÿÿÿÿintf_scansexaP/home/slovin/Projects/indi/src/indicom.c(@str0ÿÿÿÿconst char*ÿÿÿÿdpÿÿÿÿdouble*ÿÿÿÿintfs_sexaP/home/slovin/Projects/indi/src/indicom.cè!outÿÿÿÿ char*ÿÿÿÿaÿÿÿÿ doubleÿÿÿÿwÿÿÿÿintÿÿÿÿfracbaseÿÿÿÿintÿÿÿÿint getSexComponentsP/home/slovin/Projects/indi/src/indicom.cBK valueÿÿÿÿ doubleÿÿÿÿdÿÿÿÿint*ÿÿÿÿmÿÿÿÿint*ÿÿÿÿsÿÿÿÿint*ÿÿÿÿvoidjulianCenturiesP/home/slovin/Projects/indi/src/indicom.c[[& doublenumberFormatP/home/slovin/Projects/indi/src/indicom.cNbbufÿÿÿÿ char*ÿÿÿÿ formatÿÿÿÿconst char*ÿÿÿÿ valueÿÿÿÿ doubleÿÿÿÿint nutateP/home/slovin/Projects/indi/src/indicom.c RAÿÿÿÿdouble*ÿÿÿÿDecÿÿÿÿdouble*ÿÿÿÿvoidobliquityP/home/slovin/Projects/indi/src/indicom.cQQ( doublep1P/home/slovin/Projects/indi/src/indicom.c\\2i1ÿÿÿÿintÿÿÿÿi2ÿÿÿÿintÿÿÿÿ doublep2P/home/slovin/Projects/indi/src/indicom.c]]2i1ÿÿÿÿintÿÿÿÿi2ÿÿÿÿintÿÿÿÿ double&precessFromAnyEpochP/home/slovin/Projects/indi/src/indicom.c?wjd0ÿÿÿÿ doubleÿÿÿÿjdfÿÿÿÿ doubleÿÿÿÿRAÿÿÿÿdouble*ÿÿÿÿDecÿÿÿÿdouble*ÿÿÿÿvoidsunMeanAnomalyP/home/slovin/Projects/indi/src/indicom.cSS% double sunMeanLongitudeP/home/slovin/Projects/indi/src/indicom.cTT' doublesunTrueAnomalyP/home/slovin/Projects/indi/src/indicom.cUU& double sunTrueLongitudeP/home/slovin/Projects/indi/src/indicom.cVV( doubletimestampP/home/slovin/Projects/indi/src/indicom.cvconst char*tty_connectP/home/slovin/Projects/indi/src/indicom.c: deviceÿÿÿÿconst char*ÿÿÿÿttyOptionsÿÿÿÿstruct termios*ÿÿÿÿfdÿÿÿÿint*ÿÿÿÿinttty_disconnectP/home/slovin/Projects/indi/src/indicom.c<Ffdÿÿÿÿintÿÿÿÿinttty_error_msgP/home/slovin/Projects/indi/src/indicom.cHyerr_codeÿÿÿÿintÿÿÿÿerr_msgÿÿÿÿ char*ÿÿÿÿerr_msg_lenÿÿÿÿintÿÿÿÿvoidtty_readP/home/slovin/Projects/indi/src/indicom.cÌæfdÿÿÿÿintÿÿÿÿbufÿÿÿÿ char*ÿÿÿÿ nbytesÿÿÿÿintÿÿÿÿtimeoutÿÿÿÿintÿÿÿÿnbytes_readÿÿÿÿint*ÿÿÿÿint tty_read_sectionP/home/slovin/Projects/indi/src/indicom.cèfdÿÿÿÿintÿÿÿÿbufÿÿÿÿ char*ÿÿÿÿstop_charÿÿÿÿcharÿÿÿÿtimeoutÿÿÿÿintÿÿÿÿnbytes_readÿÿÿÿint*ÿÿÿÿinttty_timeoutP/home/slovin/Projects/indi/src/indicom.cƒfdÿÿÿÿintÿÿÿÿtimeoutÿÿÿÿintÿÿÿÿinttty_writeP/home/slovin/Projects/indi/src/indicom.cŸ²fdÿÿÿÿintÿÿÿÿbufÿÿÿÿconst char*ÿÿÿÿ nbytesÿÿÿÿintÿÿÿÿnbytes_writtenÿÿÿÿint*ÿÿÿÿint tty_write_stringP/home/slovin/Projects/indi/src/indicom.c´Êfdÿÿÿÿintÿÿÿÿbufÿÿÿÿconst char*ÿÿÿÿnbytes_writtenÿÿÿÿint*ÿÿÿÿint"updateAstroValuesP/home/slovin/Projects/indi/src/indicom.c_Âjdÿÿÿÿ doubleÿÿÿÿvoidCXP/home/slovin/Projects/indi/src/indicom.cLL doubleCYP/home/slovin/Projects/indi/src/indicom.cLL doubleCZP/home/slovin/Projects/indi/src/indicom.cLL doubleDirectionP/home/slovin/Projects/indi/src/indicom.c( (Econst char*KP/home/slovin/Projects/indi/src/indicom.cJJ doubleLP/home/slovin/Projects/indi/src/indicom.cJJ doubleL0P/home/slovin/Projects/indi/src/indicom.cJJ doubleLMP/home/slovin/Projects/indi/src/indicom.cJJ doubleMP/home/slovin/Projects/indi/src/indicom.cJ J! doubleM0P/home/slovin/Projects/indi/src/indicom.cJ#J% doubleOP/home/slovin/Projects/indi/src/indicom.cJ'J( doubleObliquityP/home/slovin/Projects/indi/src/indicom.cJJ doublePP/home/slovin/Projects/indi/src/indicom.cJ*J+ doubleP1P/home/slovin/Projects/indi/src/indicom.cMM doubleP2P/home/slovin/Projects/indi/src/indicom.cMM doubleSXP/home/slovin/Projects/indi/src/indicom.cL L doubleSYP/home/slovin/Projects/indi/src/indicom.cLL doubleSZP/home/slovin/Projects/indi/src/indicom.cLL doubleSolarSystemP/home/slovin/Projects/indi/src/indicom.c) )uconst char*TP/home/slovin/Projects/indi/src/indicom.cO O doubleXPP/home/slovin/Projects/indi/src/indicom.cKK doubleYPP/home/slovin/Projects/indi/src/indicom.cK K doubleZPP/home/slovin/Projects/indi/src/indicom.cKK doubledeltaEcLongP/home/slovin/Projects/indi/src/indicom.cNN" doubledeltaObliquityP/home/slovin/Projects/indi/src/indicom.cNN doubleeP/home/slovin/Projects/indi/src/indicom.cOO doubleP/home/slovin/Projects/indi/src/indicom.hÿÿÿÿTTY_ERRNOP/home/slovin/Projects/indi/src/indicom.h<‘<Ÿint TTY_OKP/home/slovin/Projects/indi/src/indicom.h<<intTTY_PARAM_ERRORP/home/slovin/Projects/indi/src/indicom.h<}<int TTY_PORT_FAILUREP/home/slovin/Projects/indi/src/indicom.h<h<{intTTY_READ_ERRORP/home/slovin/Projects/indi/src/indicom.h<<,int TTY_SELECT_ERRORP/home/slovin/Projects/indi/src/indicom.h<B<UintTTY_TIME_OUTP/home/slovin/Projects/indi/src/indicom.h<W<fintTTY_WRITE_ERRORP/home/slovin/Projects/indi/src/indicom.h<.<@intV/home/slovin/Projects/indi/src/indidevapi.hÿÿÿÿ IE_CBFV/home/slovin/Projects/indi/src/indidevapi.h :void IE_TCFV/home/slovin/Projects/indi/src/indidevapi.h )void IE_WPFV/home/slovin/Projects/indi/src/indidevapi.h! !)void^/home/slovin/Projects/indi/src/indidrivermain.cÿÿÿÿ clientMsgCB^/home/slovin/Projects/indi/src/indidrivermain.c1 1*fdÿÿÿÿintÿÿÿÿargÿÿÿÿ void*ÿÿÿÿvoidcrackDN^/home/slovin/Projects/indi/src/indidrivermain.c3 3FrootÿÿÿÿXMLEle*ÿÿÿÿdevÿÿÿÿ char**ÿÿÿÿnameÿÿÿÿ char**ÿÿÿÿ msg[]ÿÿÿÿcharÿÿÿÿintdispatch^/home/slovin/Projects/indi/src/indidrivermain.c2 2.rootÿÿÿÿXMLEle*ÿÿÿÿ msg[]ÿÿÿÿcharÿÿÿÿintmain^/home/slovin/Projects/indi/src/indidrivermain.cGqacÿÿÿÿintÿÿÿÿav[]ÿÿÿÿ char*ÿÿÿÿintpermStr^/home/slovin/Projects/indi/src/indidrivermain.c7 7pÿÿÿÿ IPermÿÿÿÿconst char*pstateStr^/home/slovin/Projects/indi/src/indidrivermain.c4 4 sÿÿÿÿIPStateÿÿÿÿconst char*ruleStr^/home/slovin/Projects/indi/src/indidrivermain.c6 6rÿÿÿÿ ISRuleÿÿÿÿconst char*sstateStr^/home/slovin/Projects/indi/src/indidrivermain.c5 5 sÿÿÿÿISStateÿÿÿÿconst char* usage^/home/slovin/Projects/indi/src/indidrivermain.c0 0bÿÿÿÿÿÿÿÿvoidÿÿÿÿvoid,IDDefBLOB^/home/slovin/Projects/indi/src/indidrivermain.c0Rbÿÿÿÿ4const IBLOBVectorProperty*ÿÿÿÿfmtÿÿÿÿconst char*ÿÿÿÿvoidIDDefLight^/home/slovin/Projects/indi/src/indidrivermain.c -lvpÿÿÿÿ6const ILightVectorProperty*ÿÿÿÿfmtÿÿÿÿconst char*ÿÿÿÿvoidIDDefNumber^/home/slovin/Projects/indi/src/indidrivermain.c¦×nÿÿÿÿ8const INumberVectorProperty*ÿÿÿÿfmtÿÿÿÿconst char*ÿÿÿÿvoidIDDefSwitch^/home/slovin/Projects/indi/src/indidrivermain.cÚ sÿÿÿÿ8const ISwitchVectorProperty*ÿÿÿÿfmtÿÿÿÿconst char*ÿÿÿÿvoidIDDefText^/home/slovin/Projects/indi/src/indidrivermain.cv£tvpÿÿÿÿ4const ITextVectorProperty*ÿÿÿÿfmtÿÿÿÿconst char*ÿÿÿÿvoidIDDelete^/home/slovin/Projects/indi/src/indidrivermain.c7Hdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿfmtÿÿÿÿconst char*ÿÿÿÿvoid IDLog^/home/slovin/Projects/indi/src/indidrivermain.cMUfmtÿÿÿÿconst char*ÿÿÿÿvoidIDMessage^/home/slovin/Projects/indi/src/indidrivermain.c!2devÿÿÿÿconst char*ÿÿÿÿfmtÿÿÿÿconst char*ÿÿÿÿvoidIDSetBLOB^/home/slovin/Projects/indi/src/indidrivermain.cØbvpÿÿÿÿ4const IBLOBVectorProperty*ÿÿÿÿfmtÿÿÿÿconst char*ÿÿÿÿvoidIDSetLight^/home/slovin/Projects/indi/src/indidrivermain.c¸Õlvpÿÿÿÿ6const ILightVectorProperty*ÿÿÿÿfmtÿÿÿÿconst char*ÿÿÿÿvoidIDSetNumber^/home/slovin/Projects/indi/src/indidrivermain.cv”nvpÿÿÿÿ8const INumberVectorProperty*ÿÿÿÿfmtÿÿÿÿconst char*ÿÿÿÿvoidIDSetSwitch^/home/slovin/Projects/indi/src/indidrivermain.c—µsvpÿÿÿÿ8const ISwitchVectorProperty*ÿÿÿÿfmtÿÿÿÿconst char*ÿÿÿÿvoidIDSetText^/home/slovin/Projects/indi/src/indidrivermain.cUstvpÿÿÿÿ4const ITextVectorProperty*ÿÿÿÿfmtÿÿÿÿconst char*ÿÿÿÿvoidIEAddCallback^/home/slovin/Projects/indi/src/indidrivermain.cY]readfiledesÿÿÿÿintÿÿÿÿfpÿÿÿÿIE_CBF*ÿÿÿÿpÿÿÿÿ void*ÿÿÿÿintIEAddTimer^/home/slovin/Projects/indi/src/indidrivermain.ceimillisecsÿÿÿÿintÿÿÿÿfpÿÿÿÿIE_TCF*ÿÿÿÿpÿÿÿÿ void*ÿÿÿÿintIEAddWorkProc^/home/slovin/Projects/indi/src/indidrivermain.cqufpÿÿÿÿIE_WPF*ÿÿÿÿpÿÿÿÿ void*ÿÿÿÿintIERmCallback^/home/slovin/Projects/indi/src/indidrivermain.c_ccallbackidÿÿÿÿintÿÿÿÿvoidIERmTimer^/home/slovin/Projects/indi/src/indidrivermain.ckotimeridÿÿÿÿintÿÿÿÿvoidIERmWorkProc^/home/slovin/Projects/indi/src/indidrivermain.cw{workprocidÿÿÿÿintÿÿÿÿvoidIUFillNumber^/home/slovin/Projects/indi/src/indidrivermain.cKYnpÿÿÿÿINumber*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ labelÿÿÿÿconst char*ÿÿÿÿ formatÿÿÿÿconst char*ÿÿÿÿminÿÿÿÿ doubleÿÿÿÿmaxÿÿÿÿ doubleÿÿÿÿstepÿÿÿÿ doubleÿÿÿÿ valueÿÿÿÿ doubleÿÿÿÿvoid$IUFillNumberVector^/home/slovin/Projects/indi/src/indidrivermain.cyˆ nvpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿnpÿÿÿÿINumber*ÿÿÿÿnnpÿÿÿÿintÿÿÿÿdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ labelÿÿÿÿconst char*ÿÿÿÿ groupÿÿÿÿconst char*ÿÿÿÿpÿÿÿÿ IPermÿÿÿÿtimeoutÿÿÿÿ doubleÿÿÿÿsÿÿÿÿIPStateÿÿÿÿvoidIUFillSwitch^/home/slovin/Projects/indi/src/indidrivermain.cBIspÿÿÿÿISwitch*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ labelÿÿÿÿconst char*ÿÿÿÿsÿÿÿÿISStateÿÿÿÿvoid$IUFillSwitchVector^/home/slovin/Projects/indi/src/indidrivermain.ciw svpÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿspÿÿÿÿISwitch*ÿÿÿÿnspÿÿÿÿintÿÿÿÿdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ labelÿÿÿÿconst char*ÿÿÿÿ groupÿÿÿÿconst char*ÿÿÿÿpÿÿÿÿ IPermÿÿÿÿrÿÿÿÿ ISRuleÿÿÿÿtimeoutÿÿÿÿ doubleÿÿÿÿsÿÿÿÿIPStateÿÿÿÿvoidIUFillText^/home/slovin/Projects/indi/src/indidrivermain.c[gtpÿÿÿÿ IText*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ labelÿÿÿÿconst char*ÿÿÿÿinitialTextÿÿÿÿconst char*ÿÿÿÿvoid IUFillTextVector^/home/slovin/Projects/indi/src/indidrivermain.cŠ˜ tvpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿtpÿÿÿÿ IText*ÿÿÿÿntpÿÿÿÿintÿÿÿÿdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ labelÿÿÿÿconst char*ÿÿÿÿ groupÿÿÿÿconst char*ÿÿÿÿpÿÿÿÿ IPermÿÿÿÿtimeoutÿÿÿÿ doubleÿÿÿÿsÿÿÿÿIPStateÿÿÿÿvoidIUFindNumber^/home/slovin/Projects/indi/src/indidrivermain.c‹•nvpÿÿÿÿ8const INumberVectorProperty*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿINumber*IUFindOnSwitch^/home/slovin/Projects/indi/src/indidrivermain.c§±svpÿÿÿÿ8const ISwitchVectorProperty*ÿÿÿÿISwitch*IUFindSwitch^/home/slovin/Projects/indi/src/indidrivermain.c˜¢svpÿÿÿÿ8const ISwitchVectorProperty*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿISwitch*IUFindText^/home/slovin/Projects/indi/src/indidrivermain.c~ˆtvpÿÿÿÿ4const ITextVectorProperty*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ IText*IUResetSwitches^/home/slovin/Projects/indi/src/indidrivermain.c´»svpÿÿÿÿ8const ISwitchVectorProperty*ÿÿÿÿvoidIUSaveText^/home/slovin/Projects/indi/src/indidrivermain.c7@tpÿÿÿÿ IText*ÿÿÿÿnewtextÿÿÿÿconst char*ÿÿÿÿvoidIUUpdateMinMax^/home/slovin/Projects/indi/src/indidrivermain.cnvpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿvoidIUUpdateNumbers^/home/slovin/Projects/indi/src/indidrivermain.cõnvpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿint IUUpdateSwitches^/home/slovin/Projects/indi/src/indidrivermain.c¾òsvpÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿintIUUpdateTexts^/home/slovin/Projects/indi/src/indidrivermain.c4tvpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿintclientMsgCB^/home/slovin/Projects/indi/src/indidrivermain.c«Çfdÿÿÿÿintÿÿÿÿargÿÿÿÿ void*ÿÿÿÿvoidcrackDN^/home/slovin/Projects/indi/src/indidrivermain.cÑårootÿÿÿÿXMLEle*ÿÿÿÿdevÿÿÿÿ char**ÿÿÿÿnameÿÿÿÿ char**ÿÿÿÿ msg[]ÿÿÿÿcharÿÿÿÿintdispatch^/home/slovin/Projects/indi/src/indidrivermain.cÎÌrootÿÿÿÿXMLEle*ÿÿÿÿ msg[]ÿÿÿÿcharÿÿÿÿintmain^/home/slovin/Projects/indi/src/indidrivermain.cGqacÿÿÿÿintÿÿÿÿav[]ÿÿÿÿ char*ÿÿÿÿintpermStr^/home/slovin/Projects/indi/src/indidrivermain.cpÿÿÿÿ IPermÿÿÿÿconst char*pstateStr^/home/slovin/Projects/indi/src/indidrivermain.cèôsÿÿÿÿIPStateÿÿÿÿconst char*ruleStr^/home/slovin/Projects/indi/src/indidrivermain.crÿÿÿÿ ISRuleÿÿÿÿconst char*sstateStr^/home/slovin/Projects/indi/src/indidrivermain.c÷sÿÿÿÿISStateÿÿÿÿconst char* usage^/home/slovin/Projects/indi/src/indidrivermain.c›¤ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoid clixml^/home/slovin/Projects/indi/src/indidrivermain.c<<LilXML*me^/home/slovin/Projects/indi/src/indidrivermain.c;; char*nroCheck^/home/slovin/Projects/indi/src/indidrivermain.c9 9introCheck^/home/slovin/Projects/indi/src/indidrivermain.cE E ROSC*verbose^/home/slovin/Projects/indi/src/indidrivermain.c: :int ROSC^/home/slovin/Projects/indi/src/indidrivermain.cCCÿÿÿÿV/home/slovin/Projects/indi/src/indiserver.cÿÿÿÿaddClDeviceV/home/slovin/Projects/indi/src/indiserver.c{ {/cpÿÿÿÿClInfo*ÿÿÿÿdevÿÿÿÿ char*ÿÿÿÿvoidcrackBLOBV/home/slovin/Projects/indi/src/indiserver.c1enableBLOB[]ÿÿÿÿcharÿÿÿÿBLOBHandlingfindClDeviceV/home/slovin/Projects/indi/src/indiserver.c| |/cpÿÿÿÿClInfo*ÿÿÿÿdevÿÿÿÿ char*ÿÿÿÿintfreeMsgV/home/slovin/Projects/indi/src/indiserver.c~ ~mpÿÿÿÿMsg*ÿÿÿÿvoidindiListenV/home/slovin/Projects/indi/src/indiserver.co oÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidindiRunV/home/slovin/Projects/indi/src/indiserver.cn nÿÿÿÿÿÿÿÿvoidÿÿÿÿvoid logMsgV/home/slovin/Projects/indi/src/indiserver.c‚ ‚!rootÿÿÿÿXMLEle*ÿÿÿÿvoidmainV/home/slovin/Projects/indi/src/indiserver.cŠËacÿÿÿÿintÿÿÿÿav[]ÿÿÿÿ char*ÿÿÿÿintnewClSocketV/home/slovin/Projects/indi/src/indiserver.cq qÿÿÿÿÿÿÿÿvoidÿÿÿÿintnewClientV/home/slovin/Projects/indi/src/indiserver.cp pÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidnoSIGPIPEV/home/slovin/Projects/indi/src/indiserver.cm mÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidnoZombiesV/home/slovin/Projects/indi/src/indiserver.cl lÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidopenINDIServerV/home/slovin/Projects/indi/src/indiserver.cw w6 host[]ÿÿÿÿcharÿÿÿÿindi_portÿÿÿÿintÿÿÿÿintq2ClientsV/home/slovin/Projects/indi/src/indiserver.cz zH notmeÿÿÿÿClInfo*ÿÿÿÿrootÿÿÿÿXMLEle*ÿÿÿÿdevÿÿÿÿ char*ÿÿÿÿmpÿÿÿÿMsg*ÿÿÿÿMsg*q2DriversV/home/slovin/Projects/indi/src/indiserver.cy y8rootÿÿÿÿXMLEle*ÿÿÿÿdevÿÿÿÿ char*ÿÿÿÿmpÿÿÿÿMsg*ÿÿÿÿMsg*readFromClientV/home/slovin/Projects/indi/src/indiserver.cs s'cpÿÿÿÿClInfo*ÿÿÿÿvoidreadFromDriverV/home/slovin/Projects/indi/src/indiserver.c} }(dpÿÿÿÿDvrInfo*ÿÿÿÿvoidrestartDvrV/home/slovin/Projects/indi/src/indiserver.cx x$dpÿÿÿÿDvrInfo*ÿÿÿÿvoidsendClientMsgV/home/slovin/Projects/indi/src/indiserver.c &cpÿÿÿÿClInfo*ÿÿÿÿvoidsendDriverMsgV/home/slovin/Projects/indi/src/indiserver.c€ €'cpÿÿÿÿDvrInfo*ÿÿÿÿvoidshutdownClientV/home/slovin/Projects/indi/src/indiserver.cr r'cpÿÿÿÿClInfo*ÿÿÿÿvoidstartDvrV/home/slovin/Projects/indi/src/indiserver.ct t"dpÿÿÿÿDvrInfo*ÿÿÿÿvoidstartLocalDvrV/home/slovin/Projects/indi/src/indiserver.cu u'dpÿÿÿÿDvrInfo*ÿÿÿÿvoidstartRemoteDvrV/home/slovin/Projects/indi/src/indiserver.cv v(dpÿÿÿÿDvrInfo*ÿÿÿÿvoid usageV/home/slovin/Projects/indi/src/indiserver.ck kÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidaddClDeviceV/home/slovin/Projects/indi/src/indiserver.c¸ÃcpÿÿÿÿClInfo*ÿÿÿÿdevÿÿÿÿ char*ÿÿÿÿvoidcrackBLOBV/home/slovin/Projects/indi/src/indiserver.cÝåenableBLOB[]ÿÿÿÿcharÿÿÿÿBLOBHandlingfindClDeviceV/home/slovin/Projects/indi/src/indiserver.c§´cpÿÿÿÿClInfo*ÿÿÿÿdevÿÿÿÿ char*ÿÿÿÿintfreeMsgV/home/slovin/Projects/indi/src/indiserver.cJOmpÿÿÿÿMsg*ÿÿÿÿvoidindiListenV/home/slovin/Projects/indi/src/indiserver.c‹´voidindiRunV/home/slovin/Projects/indi/src/indiserver.c· ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoid logMsgV/home/slovin/Projects/indi/src/indiserver.cé rootÿÿÿÿXMLEle*ÿÿÿÿvoidmainV/home/slovin/Projects/indi/src/indiserver.cŠËacÿÿÿÿintÿÿÿÿav[]ÿÿÿÿ char*ÿÿÿÿintnewClSocketV/home/slovin/Projects/indi/src/indiserver.cÉÚintnewClientV/home/slovin/Projects/indi/src/indiserver.c0voidnoSIGPIPEV/home/slovin/Projects/indi/src/indiserver.cïövoidnoZombiesV/home/slovin/Projects/indi/src/indiserver.càìvoidopenINDIServerV/home/slovin/Projects/indi/src/indiserver.ce† host[]ÿÿÿÿcharÿÿÿÿindi_portÿÿÿÿintÿÿÿÿintq2ClientsV/home/slovin/Projects/indi/src/indiserver.cG notmeÿÿÿÿClInfo*ÿÿÿÿrootÿÿÿÿXMLEle*ÿÿÿÿdevÿÿÿÿ char*ÿÿÿÿmpÿÿÿÿMsg*ÿÿÿÿMsg*q2DriversV/home/slovin/Projects/indi/src/indiserver.cÝrootÿÿÿÿXMLEle*ÿÿÿÿdevÿÿÿÿ char*ÿÿÿÿmpÿÿÿÿMsg*ÿÿÿÿMsg*readFromClientV/home/slovin/Projects/indi/src/indiserver.c6kcpÿÿÿÿClInfo*ÿÿÿÿvoidreadFromDriverV/home/slovin/Projects/indi/src/indiserver.cpœdpÿÿÿÿDvrInfo*ÿÿÿÿvoidrestartDvrV/home/slovin/Projects/indi/src/indiserver.c¼ÕdpÿÿÿÿDvrInfo*ÿÿÿÿvoidsendClientMsgV/home/slovin/Projects/indi/src/indiserver.cUzcpÿÿÿÿClInfo*ÿÿÿÿvoidsendDriverMsgV/home/slovin/Projects/indi/src/indiserver.c€¢dpÿÿÿÿDvrInfo*ÿÿÿÿvoidshutdownClientV/home/slovin/Projects/indi/src/indiserver.cŸ¹cpÿÿÿÿClInfo*ÿÿÿÿvoidstartDvrV/home/slovin/Projects/indi/src/indiserver.cûdpÿÿÿÿDvrInfo*ÿÿÿÿvoidstartLocalDvrV/home/slovin/Projects/indi/src/indiserver.c<dpÿÿÿÿDvrInfo*ÿÿÿÿvoidstartRemoteDvrV/home/slovin/Projects/indi/src/indiserver.cA`dpÿÿÿÿDvrInfo*ÿÿÿÿvoid usageV/home/slovin/Projects/indi/src/indiserver.cÎÝÿÿÿÿÿÿÿÿvoidÿÿÿÿvoid  clinfoV/home/slovin/Projects/indi/src/indiserver.cYYClInfo*dvrinfoV/home/slovin/Projects/indi/src/indiserver.chhDvrInfo*lsocketV/home/slovin/Projects/indi/src/indiserver.cˆ ˆint maxdrsV/home/slovin/Projects/indi/src/indiserver.c† †intmeV/home/slovin/Projects/indi/src/indiserver.c„ „ char*nclinfoV/home/slovin/Projects/indi/src/indiserver.cZ ZintndvrinfoV/home/slovin/Projects/indi/src/indiserver.ci iintportV/home/slovin/Projects/indi/src/indiserver.c… …intverboseV/home/slovin/Projects/indi/src/indiserver.c‡ ‡int BLOBHandlingV/home/slovin/Projects/indi/src/indiserver.cE)E5ÿÿÿÿ ClInfoV/home/slovin/Projects/indi/src/indiserver.cXXÿÿÿÿ DvrInfoV/home/slovin/Projects/indi/src/indiserver.cgg ÿÿÿÿ IDevV/home/slovin/Projects/indi/src/indiserver.cB B char MsgV/home/slovin/Projects/indi/src/indiserver.cKKÿÿÿÿZ/home/slovin/Projects/indi/src/intelliscope.cÿÿÿÿ ISInitZ/home/slovin/Projects/indi/src/intelliscope.c+ + :üÿÿÿÿÿÿÿÿvoidÿÿÿÿvoid ISPollZ/home/slovin/Projects/indi/src/intelliscope.c* * ÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoid connectTelescopeZ/home/slovin/Projects/indi/src/intelliscope.c, ," :üÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidISGetPropertiesZ/home/slovin/Projects/indi/src/intelliscope.cMW &€devÿÿÿÿconst char*ÿÿÿÿvoid ISInitZ/home/slovin/Projects/indi/src/intelliscope.c@K úÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidISNewBLOBZ/home/slovin/Projects/indi/src/intelliscope.c}€ ”devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿsizes[]ÿÿÿÿintÿÿÿÿblobs[]ÿÿÿÿ char*ÿÿÿÿformats[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewNumberZ/home/slovin/Projects/indi/src/intelliscope.cx{devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchZ/home/slovin/Projects/indi/src/intelliscope.cYfdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextZ/home/slovin/Projects/indi/src/intelliscope.chwdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollZ/home/slovin/Projects/indi/src/intelliscope.c‚žpÿÿÿÿ void*ÿÿÿÿvoid connectTelescopeZ/home/slovin/Projects/indi/src/intelliscope.c ½ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoid PortTZ/home/slovin/Projects/indi/src/intelliscope.c3 37 IText PortTPZ/home/slovin/Projects/indi/src/intelliscope.c44¡&ITextVectorProperty PowerSZ/home/slovin/Projects/indi/src/intelliscope.c00wISwitchPowerSPZ/home/slovin/Projects/indi/src/intelliscope.c11±*ISwitchVectorPropertyeqZ/home/slovin/Projects/indi/src/intelliscope.c7:INumber eqNumZ/home/slovin/Projects/indi/src/intelliscope.c;=*INumberVectorPropertyfdZ/home/slovin/Projects/indi/src/intelliscope.c..intN/home/slovin/Projects/indi/src/lilxml.cÿÿÿÿ_LilXMLN/home/slovin/Projects/indi/src/lilxml.cIQceN/home/slovin/Projects/indi/src/lilxml.cL LXMLEle*csN/home/slovin/Projects/indi/src/lilxml.cJ J State delimN/home/slovin/Projects/indi/src/lilxml.cNN int endtagN/home/slovin/Projects/indi/src/lilxml.cM M String lastcN/home/slovin/Projects/indi/src/lilxml.cOO intlnN/home/slovin/Projects/indi/src/lilxml.cKK intskippingN/home/slovin/Projects/indi/src/lilxml.cPPint_xml_attN/home/slovin/Projects/indi/src/lilxml.caeceN/home/slovin/Projects/indi/src/lilxml.cdd struct _xml_ele*nameN/home/slovin/Projects/indi/src/lilxml.cb b StringvaluN/home/slovin/Projects/indi/src/lilxml.cc c String_xml_eleN/home/slovin/Projects/indi/src/lilxml.cT^ aitN/home/slovin/Projects/indi/src/lilxml.cYY intatN/home/slovin/Projects/indi/src/lilxml.cW WXMLAtt**eitN/home/slovin/Projects/indi/src/lilxml.c\\ intelN/home/slovin/Projects/indi/src/lilxml.cZZ"struct _xml_ele**natN/home/slovin/Projects/indi/src/lilxml.cXX intnelN/home/slovin/Projects/indi/src/lilxml.c[[ int pcdataN/home/slovin/Projects/indi/src/lilxml.c] ] StringpeN/home/slovin/Projects/indi/src/lilxml.cVV struct _xml_ele*tagN/home/slovin/Projects/indi/src/lilxml.cU U String appendStringN/home/slovin/Projects/indi/src/lilxml.c3 30spÿÿÿÿString*ÿÿÿÿstrÿÿÿÿ char*ÿÿÿÿvoidfreeAttN/home/slovin/Projects/indi/src/lilxml.c0 0aÿÿÿÿXMLAtt*ÿÿÿÿvoidfreeStringN/home/slovin/Projects/indi/src/lilxml.c4 4#spÿÿÿÿString*ÿÿÿÿvoidgrowAttN/home/slovin/Projects/indi/src/lilxml.c//!eÿÿÿÿXMLEle*ÿÿÿÿXMLAtt*growStringN/home/slovin/Projects/indi/src/lilxml.c2 2* 4ëˆspÿÿÿÿString*ÿÿÿÿcÿÿÿÿintÿÿÿÿvoidinitParserN/home/slovin/Projects/indi/src/lilxml.c+ +"lpÿÿÿÿLilXML*ÿÿÿÿvoidisTokenCharN/home/slovin/Projects/indi/src/lilxml.c1 1) startÿÿÿÿintÿÿÿÿcÿÿÿÿintÿÿÿÿintmorememN/home/slovin/Projects/indi/src/lilxml.c6 6' 2Uoldÿÿÿÿ void*ÿÿÿÿnÿÿÿÿintÿÿÿÿ void*newStringN/home/slovin/Projects/indi/src/lilxml.c5 5"spÿÿÿÿString*ÿÿÿÿvoidoneXMLcharN/home/slovin/Projects/indi/src/lilxml.c* *8%lpÿÿÿÿLilXML*ÿÿÿÿcÿÿÿÿintÿÿÿÿerrmsg[]ÿÿÿÿcharÿÿÿÿintpopXMLEleN/home/slovin/Projects/indi/src/lilxml.c- -! "!lpÿÿÿÿLilXML*ÿÿÿÿvoidpushXMLEleN/home/slovin/Projects/indi/src/lilxml.c, ,"·UÇlpÿÿÿÿLilXML*ÿÿÿÿvoidresetEndTagN/home/slovin/Projects/indi/src/lilxml.c. .#lpÿÿÿÿLilXML*ÿÿÿÿvoid$addXMLAttN/home/slovin/Projects/indi/src/lilxml.c• €epÿÿÿÿXMLEle*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvaluÿÿÿÿ char*ÿÿÿÿvoidappendStringN/home/slovin/Projects/indi/src/lilxml.cãñ 3§€spÿÿÿÿString*ÿÿÿÿstrÿÿÿÿ char*ÿÿÿÿvoiddelLilXMLN/home/slovin/Projects/indi/src/lilxml.c„ˆlpÿÿÿÿLilXML*ÿÿÿÿvoiddelXMLEleN/home/slovin/Projects/indi/src/lilxml.c‹¤epÿÿÿÿXMLEle*ÿÿÿÿvoidfindXMLAttN/home/slovin/Projects/indi/src/lilxml.cñúepÿÿÿÿXMLEle*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿXMLAtt*findXMLAttValuN/home/slovin/Projects/indi/src/lilxml.cv{ 5vepÿÿÿÿXMLEle*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ char*findXMLEleN/home/slovin/Projects/indi/src/lilxml.cÿ  2{epÿÿÿÿXMLEle*ÿÿÿÿtagÿÿÿÿconst char*ÿÿÿÿXMLEle*freeAttN/home/slovin/Projects/indi/src/lilxml.c¶¾·UÇaÿÿÿÿXMLAtt*ÿÿÿÿvoidfreeStringN/home/slovin/Projects/indi/src/lilxml.cþspÿÿÿÿString*ÿÿÿÿvoidgrowAttN/home/slovin/Projects/indi/src/lilxml.c¥³epÿÿÿÿXMLEle*ÿÿÿÿXMLAtt*growStringN/home/slovin/Projects/indi/src/lilxml.cÒàspÿÿÿÿString*ÿÿÿÿcÿÿÿÿintÿÿÿÿvoidindi_xmlMallocN/home/slovin/Projects/indi/src/lilxml.cow·UÇ8(* newmalloc)( size_t size )ÿÿÿÿ void*ÿÿÿÿR(* newrealloc)( void * ptr, size_t size )ÿÿÿÿ void*ÿÿÿÿ2(* newfree)( void * ptr )ÿÿÿÿvoidÿÿÿÿvoidinitParserN/home/slovin/Projects/indi/src/lilxml.cvlpÿÿÿÿLilXML*ÿÿÿÿvoidisTokenCharN/home/slovin/Projects/indi/src/lilxml.cËÏ startÿÿÿÿintÿÿÿÿcÿÿÿÿintÿÿÿÿintmorememN/home/slovin/Projects/indi/src/lilxml.c  oldÿÿÿÿ void*ÿÿÿÿnÿÿÿÿintÿÿÿÿ void*nXMLAttN/home/slovin/Projects/indi/src/lilxml.clpepÿÿÿÿXMLEle*ÿÿÿÿintnXMLEleN/home/slovin/Projects/indi/src/lilxml.cei 3†epÿÿÿÿXMLEle*ÿÿÿÿintnameXMLAttN/home/slovin/Projects/indi/src/lilxml.cW[apÿÿÿÿXMLAtt*ÿÿÿÿ char*newLilXMLN/home/slovin/Projects/indi/src/lilxml.czLilXML*newStringN/home/slovin/Projects/indi/src/lilxml.côûspÿÿÿÿString*ÿÿÿÿvoidnextXMLAttN/home/slovin/Projects/indi/src/lilxml.c#/epÿÿÿÿXMLEle*ÿÿÿÿinitÿÿÿÿintÿÿÿÿXMLAtt*nextXMLEleN/home/slovin/Projects/indi/src/lilxml.c 2q€epÿÿÿÿXMLEle*ÿÿÿÿinitÿÿÿÿintÿÿÿÿXMLEle*oneXMLcharN/home/slovin/Projects/indi/src/lilxml.cÑslpÿÿÿÿLilXML*ÿÿÿÿcÿÿÿÿintÿÿÿÿerrmsg[]ÿÿÿÿcharÿÿÿÿintparentXMLAttN/home/slovin/Projects/indi/src/lilxml.c9=apÿÿÿÿXMLAtt*ÿÿÿÿXMLEle*parentXMLEleN/home/slovin/Projects/indi/src/lilxml.c26epÿÿÿÿXMLEle*ÿÿÿÿXMLEle*pcdataXMLEleN/home/slovin/Projects/indi/src/lilxml.cIMepÿÿÿÿXMLEle*ÿÿÿÿ char*pcdatalenXMLEleN/home/slovin/Projects/indi/src/lilxml.cPT 3z€epÿÿÿÿXMLEle*ÿÿÿÿintpopXMLEleN/home/slovin/Projects/indi/src/lilxml.c¢lpÿÿÿÿLilXML*ÿÿÿÿvoidprXMLEleN/home/slovin/Projects/indi/src/lilxml.cªÈfpÿÿÿÿ FILE*ÿÿÿÿepÿÿÿÿXMLEle*ÿÿÿÿ levelÿÿÿÿintÿÿÿÿvoidpushXMLEleN/home/slovin/Projects/indi/src/lilxml.c†˜ ÷lpÿÿÿÿLilXML*ÿÿÿÿvoidreadXMLEleN/home/slovin/Projects/indi/src/lilxml.c¬ìlpÿÿÿÿLilXML*ÿÿÿÿnewcÿÿÿÿintÿÿÿÿerrmsg[]ÿÿÿÿcharÿÿÿÿXMLEle*readXMLFileN/home/slovin/Projects/indi/src/lilxml.c€Œ·UÇfpÿÿÿÿ FILE*ÿÿÿÿlpÿÿÿÿLilXML*ÿÿÿÿerrmsg[]ÿÿÿÿcharÿÿÿÿXMLEle*resetEndTagN/home/slovin/Projects/indi/src/lilxml.cÁÆ 3§€lpÿÿÿÿLilXML*ÿÿÿÿvoidrmXMLAttN/home/slovin/Projects/indi/src/lilxml.c˜¤epÿÿÿÿXMLEle*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvoidtagXMLEleN/home/slovin/Projects/indi/src/lilxml.cBFepÿÿÿÿXMLEle*ÿÿÿÿ char*valuXMLAttN/home/slovin/Projects/indi/src/lilxml.c^bapÿÿÿÿXMLAtt*ÿÿÿÿ char* myfreeN/home/slovin/Projects/indi/src/lilxml.cj j'voidmymallocN/home/slovin/Projects/indi/src/lilxml.ch h. void*myreallocN/home/slovin/Projects/indi/src/lilxml.ci i; void* StateN/home/slovin/Projects/indi/src/lilxml.cFFÿÿÿÿ StringN/home/slovin/Projects/indi/src/lilxml.c''ÿÿÿÿN/home/slovin/Projects/indi/src/lilxml.hÿÿÿÿ LilXMLN/home/slovin/Projects/indi/src/lilxml.hGGstruct _LilXML XMLAttN/home/slovin/Projects/indi/src/lilxml.hEEstruct _xml_att XMLEleN/home/slovin/Projects/indi/src/lilxml.hFFstruct _xml_eleV/home/slovin/Projects/indi/src/lx200_16.cppÿÿÿÿ ISGetPropertiesV/home/slovin/Projects/indi/src/lx200_16.cppapLX200_16devÿÿÿÿconst char*ÿÿÿÿvoidISNewNumberV/home/slovin/Projects/indi/src/lx200_16.cpp}¹LX200_16devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchV/home/slovin/Projects/indi/src/lx200_16.cpp¾LX200_16devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextV/home/slovin/Projects/indi/src/lx200_16.cppr{LX200_16devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollV/home/slovin/Projects/indi/src/lx200_16.cpp#|LX200_16voidLX200_16V/home/slovin/Projects/indi/src/lx200_16.cpp\_LX200_16ÿÿÿÿ0changeLX200_16DeviceNameV/home/slovin/Projects/indi/src/lx200_16.cppTZ.newNameÿÿÿÿconst char*ÿÿÿÿvoidgetBasicDataV/home/slovin/Projects/indi/src/lx200_16.cpp~‹LX200_16voidhandleAltAzSlewV/home/slovin/Projects/indi/src/lx200_16.cpp!LX200_16voidFanStatusSV/home/slovin/Projects/indi/src/lx200_16.cpp88WISwitchFanStatusSwV/home/slovin/Projects/indi/src/lx200_16.cppCC¨*ISwitchVectorPropertyFieldDeRotatorSV/home/slovin/Projects/indi/src/lx200_16.cpp::ZISwitch FieldDeRotatorSwV/home/slovin/Projects/indi/src/lx200_16.cppGGÄ*ISwitchVectorPropertyHomeSearchSV/home/slovin/Projects/indi/src/lx200_16.cpp99eISwitchHomeSearchSwV/home/slovin/Projects/indi/src/lx200_16.cppEE¬*ISwitchVectorPropertyhorV/home/slovin/Projects/indi/src/lx200_16.cppLN<INumber horNumV/home/slovin/Projects/indi/src/lx200_16.cppPR*INumberVectorPropertyR/home/slovin/Projects/indi/src/lx200_16.hÿÿÿÿLX200_16R/home/slovin/Projects/indi/src/lx200_16.h.LX200Autostar ISGetPropertiesR/home/slovin/Projects/indi/src/lx200_16.h'LX200_16devÿÿÿÿconst char*ÿÿÿÿvoidISNewNumberR/home/slovin/Projects/indi/src/lx200_16.h  \LX200_16devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchR/home/slovin/Projects/indi/src/lx200_16.h""\LX200_16devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextR/home/slovin/Projects/indi/src/lx200_16.h!!XLX200_16·UÇdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollR/home/slovin/Projects/indi/src/lx200_16.h##LX200_16 .€voidLX200_16R/home/slovin/Projects/indi/src/lx200_16.h LX200_16ÿÿÿÿgetBasicDataR/home/slovin/Projects/indi/src/lx200_16.h$$LX200_16voidhandleAltAzSlewR/home/slovin/Projects/indi/src/lx200_16.h%%LX200_16€void~ LX200_16R/home/slovin/Projects/indi/src/lx200_16.hLX200_16ÿÿÿÿ~ LX200_16R/home/slovin/Projects/indi/src/lx200_16.hLX200_16ÿÿÿÿcurrentAltR/home/slovin/Projects/indi/src/lx200_16.h)) doublecurrentAzR/home/slovin/Projects/indi/src/lx200_16.h** doubletargetAltR/home/slovin/Projects/indi/src/lx200_16.h++ doubletargetAzR/home/slovin/Projects/indi/src/lx200_16.h,, double0changeLX200_16DeviceNameR/home/slovin/Projects/indi/src/lx200_16.h003newNameÿÿÿÿconst char*ÿÿÿÿvoid`/home/slovin/Projects/indi/src/lx200autostar.cppÿÿÿÿISGetProperties`/home/slovin/Projects/indi/src/lx200autostar.cppBQLX200Autostardevÿÿÿÿconst char*ÿÿÿÿvoidISNewNumber`/home/slovin/Projects/indi/src/lx200autostar.cppawLX200Autostar 'F€devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitch`/home/slovin/Projects/indi/src/lx200autostar.cppyÃLX200Autostar¶ÛQdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewText`/home/slovin/Projects/indi/src/lx200autostar.cppS^LX200Autostardevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPoll`/home/slovin/Projects/indi/src/lx200autostar.cppÅÊLX200Autostar úvoidLX200Autostar`/home/slovin/Projects/indi/src/lx200autostar.cpp<?LX200Autostarÿÿÿÿ:changeLX200AutostarDeviceName`/home/slovin/Projects/indi/src/lx200autostar.cpp6:NnewNameÿÿÿÿconst char*ÿÿÿÿvoidgetBasicData`/home/slovin/Projects/indi/src/lx200autostar.cppÌßLX200Autostar]voidFocusSpeedN`/home/slovin/Projects/indi/src/lx200autostar.cpp33YINumberFocusSpeedNP`/home/slovin/Projects/indi/src/lx200autostar.cpp44¦*INumberVectorPropertyVersionInfo`/home/slovin/Projects/indi/src/lx200autostar.cpp00›&ITextVectorPropertyVersionT`/home/slovin/Projects/indi/src/lx200autostar.cpp*.  IText\/home/slovin/Projects/indi/src/lx200autostar.hÿÿÿÿLX200Autostar\/home/slovin/Projects/indi/src/lx200autostar.h'LX200GenericISGetProperties\/home/slovin/Projects/indi/src/lx200autostar.h'LX200Autostardevÿÿÿÿconst char*ÿÿÿÿvoidISNewNumber\/home/slovin/Projects/indi/src/lx200autostar.h  \LX200Autostar cdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitch\/home/slovin/Projects/indi/src/lx200autostar.h""\LX200Autostardevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewText\/home/slovin/Projects/indi/src/lx200autostar.h!!XLX200Autostardevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPoll\/home/slovin/Projects/indi/src/lx200autostar.h##LX200AutostarvoidLX200Autostar\/home/slovin/Projects/indi/src/lx200autostar.hLX200AutostarNÿÿÿÿgetBasicData\/home/slovin/Projects/indi/src/lx200autostar.h$$LX200Autostarvoid~ LX200Autostar\/home/slovin/Projects/indi/src/lx200autostar.hLX200Autostar (6ÿÿÿÿ~ LX200Autostar\/home/slovin/Projects/indi/src/lx200autostar.hLX200Autostar (6ÿÿÿÿ:changeLX200AutostarDeviceName\/home/slovin/Projects/indi/src/lx200autostar.h))7newNameÿÿÿÿconst char*ÿÿÿÿvoidZ/home/slovin/Projects/indi/src/lx200basic.cppÿÿÿÿ ISPollZ/home/slovin/Projects/indi/src/lx200basic.cpp9 9nÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoidretryConnectionZ/home/slovin/Projects/indi/src/lx200basic.cpp: :# 3§ÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoidISGetPropertiesZ/home/slovin/Projects/indi/src/lx200basic.cppMQsdevÿÿÿÿconst char*ÿÿÿÿvoidISGetPropertiesZ/home/slovin/Projects/indi/src/lx200basic.cpp´ÄLX200Basicdevÿÿÿÿconst char*ÿÿÿÿvoid ISInitZ/home/slovin/Projects/indi/src/lx200basic.cpp@K :žvoidISNewBLOBZ/home/slovin/Projects/indi/src/lx200basic.cppklÿÿÿÿÿÿÿÿconst char*ÿÿÿÿÿÿÿÿÿÿÿÿconst char*ÿÿÿÿÿÿÿÿÿÿÿÿint*ÿÿÿÿÿÿÿÿÿÿÿÿ char**ÿÿÿÿÿÿÿÿÿÿÿÿ char**ÿÿÿÿÿÿÿÿÿÿÿÿ char**ÿÿÿÿÿÿÿÿÿÿÿÿintÿÿÿÿvoidISNewNumberZ/home/slovin/Projects/indi/src/lx200basic.cpp_cdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewNumberZ/home/slovin/Projects/indi/src/lx200basic.cppéKLX200Basicdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchZ/home/slovin/Projects/indi/src/lx200basic.cppSWdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchZ/home/slovin/Projects/indi/src/lx200basic.cppMLX200Basic .E€devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextZ/home/slovin/Projects/indi/src/lx200basic.cppY]Idevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextZ/home/slovin/Projects/indi/src/lx200basic.cppÆæLX200Basicdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿÿÿÿÿÿÿÿÿintÿÿÿÿvoid ISPollZ/home/slovin/Projects/indi/src/lx200basic.cppeiÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoid ISPollZ/home/slovin/Projects/indi/src/lx200basic.cppýSLX200Basic·UÇvoidLX200BasicZ/home/slovin/Projects/indi/src/lx200basic.cpprLX200Basic @€ÿÿÿÿcheckPowerZ/home/slovin/Projects/indi/src/lx200basic.cppÖçLX200Basic "€spÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿintcheckPowerZ/home/slovin/Projects/indi/src/lx200basic.cppéüLX200Basicnpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿintcheckPowerZ/home/slovin/Projects/indi/src/lx200basic.cppþLX200Basictpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿintconnectionLostZ/home/slovin/Projects/indi/src/lx200basic.cppciLX200Basic·UÇvoid"connectionResumedZ/home/slovin/Projects/indi/src/lx200basic.cppkrLX200Basic 2‹voidcorrectFaultZ/home/slovin/Projects/indi/src/lx200basic.cppäêLX200Basic 4ú€void enableSimulationZ/home/slovin/Projects/indi/src/lx200basic.cppYaLX200Basic € enableÿÿÿÿboolÿÿÿÿvoidgetBasicDataZ/home/slovin/Projects/indi/src/lx200basic.cppUaLX200BasicvoidgetOnSwitchZ/home/slovin/Projects/indi/src/lx200basic.cppÌÓLX200Basicspÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿinthandleCoordSetZ/home/slovin/Projects/indi/src/lx200basic.cppcÊLX200BasicinthandleErrorZ/home/slovin/Projects/indi/src/lx200basic.cppƒ¡LX200Basic .I€svpÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoidhandleErrorZ/home/slovin/Projects/indi/src/lx200basic.cpp£ÁLX200Basic¶ÛQnvpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoidhandleErrorZ/home/slovin/Projects/indi/src/lx200basic.cppÃâLX200Basictvpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoidinitPropertiesZ/home/slovin/Projects/indi/src/lx200basic.cpp²LX200Basic·UÇvoidisTelescopeOnZ/home/slovin/Projects/indi/src/lx200basic.cppìñLX200Basic !þÿÿÿÿÿÿÿÿvoidÿÿÿÿboolpowerTelescopeZ/home/slovin/Projects/indi/src/lx200basic.cppILX200Basic " voidretryConnectionZ/home/slovin/Projects/indi/src/lx200basic.cppóûpÿÿÿÿ void*ÿÿÿÿvoidslewErrorZ/home/slovin/Projects/indi/src/lx200basic.cppKWLX200Basic "€slewCodeÿÿÿÿintÿÿÿÿvoidtelescopeZ/home/slovin/Projects/indi/src/lx200basic.cpp) )LX200Basic*V/home/slovin/Projects/indi/src/lx200basic.hÿÿÿÿLX200BasicV/home/slovin/Projects/indi/src/lx200basic.hlISGetPropertiesV/home/slovin/Projects/indi/src/lx200basic.h%%'LX200Basicdevÿÿÿÿconst char*ÿÿÿÿvoidISNewNumberV/home/slovin/Projects/indi/src/lx200basic.h&&\LX200BasicæKdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchV/home/slovin/Projects/indi/src/lx200basic.h((\LX200Basicdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextV/home/slovin/Projects/indi/src/lx200basic.h''XLX200Basic *i€devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollV/home/slovin/Projects/indi/src/lx200basic.h))LX200BasicµVÆvoidLX200BasicV/home/slovin/Projects/indi/src/lx200basic.h"" LX200BasicÿÿÿÿcheckPowerV/home/slovin/Projects/indi/src/lx200basic.hOO*LX200Basicnpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿintcheckPowerV/home/slovin/Projects/indi/src/lx200basic.hPP*LX200Basic )èspÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿintcheckPowerV/home/slovin/Projects/indi/src/lx200basic.hQQ(LX200Basic á€tpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿintconnectionLostV/home/slovin/Projects/indi/src/lx200basic.h++LX200Basic (void"connectionResumedV/home/slovin/Projects/indi/src/lx200basic.h,,LX200Basic (N€voidcorrectFaultV/home/slovin/Projects/indi/src/lx200basic.hZZLX200Basic )ævoid enableSimulationV/home/slovin/Projects/indi/src/lx200basic.h[[#LX200Basic enableÿÿÿÿboolÿÿÿÿvoidgetBasicDataV/home/slovin/Projects/indi/src/lx200basic.hNNLX200Basic·UÇvoidgetOnSwitchV/home/slovin/Projects/indi/src/lx200basic.hYY+LX200Basicspÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿinthandleCoordSetV/home/slovin/Projects/indi/src/lx200basic.hXXLX200BasicinthandleErrorV/home/slovin/Projects/indi/src/lx200basic.hRRGLX200Basic æsvpÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoidhandleErrorV/home/slovin/Projects/indi/src/lx200basic.hSSGLX200Basicnvpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoidhandleErrorV/home/slovin/Projects/indi/src/lx200basic.hTTELX200Basic *rtvpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoidinitPropertiesV/home/slovin/Projects/indi/src/lx200basic.h00LX200BasicvoidisTelescopeOnV/home/slovin/Projects/indi/src/lx200basic.hUULX200Basic (V€ÿÿÿÿÿÿÿÿvoidÿÿÿÿboolpowerTelescopeV/home/slovin/Projects/indi/src/lx200basic.hVVLX200BasicvoidslewErrorV/home/slovin/Projects/indi/src/lx200basic.hWWLX200BasicslewCodeÿÿÿÿintÿÿÿÿvoid~ LX200BasicV/home/slovin/Projects/indi/src/lx200basic.h##LX200BasicÿÿÿÿAbortSlewSV/home/slovin/Projects/indi/src/lx200basic.h5 5ISwitchAbortSlewSPV/home/slovin/Projects/indi/src/lx200basic.hCC#*ISwitchVectorPropertyEqNV/home/slovin/Projects/indi/src/lx200basic.h< <INumberEqNPV/home/slovin/Projects/indi/src/lx200basic.hFF*INumberVectorPropertyJDV/home/slovin/Projects/indi/src/lx200basic.h` `  doubleObjectTV/home/slovin/Projects/indi/src/lx200basic.h99 ITextObjectTPV/home/slovin/Projects/indi/src/lx200basic.hLL&ITextVectorPropertyOnCoordSetSV/home/slovin/Projects/indi/src/lx200basic.h4 4ISwitchOnCoordSetSPV/home/slovin/Projects/indi/src/lx200basic.hBB$*ISwitchVectorProperty PortTV/home/slovin/Projects/indi/src/lx200basic.h88 IText PortTPV/home/slovin/Projects/indi/src/lx200basic.hKK&ITextVectorProperty PowerSV/home/slovin/Projects/indi/src/lx200basic.h3 3ISwitchPowerSPV/home/slovin/Projects/indi/src/lx200basic.hAA*ISwitchVectorPropertySlewPrecisionNV/home/slovin/Projects/indi/src/lx200basic.h= =INumberSlewPrecisionNPV/home/slovin/Projects/indi/src/lx200basic.hGG'*INumberVectorPropertyTrackPrecisionNV/home/slovin/Projects/indi/src/lx200basic.h> >INumber TrackPrecisionNPV/home/slovin/Projects/indi/src/lx200basic.hHH(*INumberVectorPropertycurrentSetV/home/slovin/Projects/indi/src/lx200basic.hiiint faultV/home/slovin/Projects/indi/src/lx200basic.hf fboolfdV/home/slovin/Projects/indi/src/lx200basic.hg g intlastDECV/home/slovin/Projects/indi/src/lx200basic.hd d double lastRAV/home/slovin/Projects/indi/src/lx200basic.hc c doublelastSetV/home/slovin/Projects/indi/src/lx200basic.hjj intsimulationV/home/slovin/Projects/indi/src/lx200basic.he ebooltargetDECV/home/slovin/Projects/indi/src/lx200basic.hb b doubletargetRAV/home/slovin/Projects/indi/src/lx200basic.ha a double^/home/slovin/Projects/indi/src/lx200classic.cppÿÿÿÿISGetProperties^/home/slovin/Projects/indi/src/lx200classic.cppQaLX200Classic¶ÛQdevÿÿÿÿconst char*ÿÿÿÿvoidISNewNumber^/home/slovin/Projects/indi/src/lx200classic.cppmÌLX200Classicdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitch^/home/slovin/Projects/indi/src/lx200classic.cppÎ=LX200Classicdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewText^/home/slovin/Projects/indi/src/lx200classic.cppcjLX200Classicdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPoll^/home/slovin/Projects/indi/src/lx200classic.cpp?DLX200Classic &¾€voidLX200Classic^/home/slovin/Projects/indi/src/lx200classic.cppFNLX200Classicÿÿÿÿ8changeLX200ClassicDeviceName^/home/slovin/Projects/indi/src/lx200classic.cpp;DnewNameÿÿÿÿconst char*ÿÿÿÿvoidgetBasicData^/home/slovin/Projects/indi/src/lx200classic.cppFLLX200Classic 3‡€voidDeepSkyCatalogS^/home/slovin/Projects/indi/src/lx200classic.cpp))ðISwitch DeepSkyCatalogSw^/home/slovin/Projects/indi/src/lx200classic.cpp--»*ISwitchVectorPropertyMaxSlew^/home/slovin/Projects/indi/src/lx200classic.cpp33RINumberMaxSlewRate^/home/slovin/Projects/indi/src/lx200classic.cpp44œ*INumberVectorPropertyObjectInfo^/home/slovin/Projects/indi/src/lx200classic.cpp%%™&ITextVectorPropertyObjectN^/home/slovin/Projects/indi/src/lx200classic.cpp00TINumberObjectNo^/home/slovin/Projects/indi/src/lx200classic.cpp11“*INumberVectorPropertyObjectText^/home/slovin/Projects/indi/src/lx200classic.cpp$$B IText SolarS^/home/slovin/Projects/indi/src/lx200classic.cpp**mISwitchSolarSw^/home/slovin/Projects/indi/src/lx200classic.cpp..°*ISwitchVectorPropertyStarCatalogS^/home/slovin/Projects/indi/src/lx200classic.cpp((xISwitchStarCatalogSw^/home/slovin/Projects/indi/src/lx200classic.cpp,,±*ISwitchVectorPropertyaltLimit^/home/slovin/Projects/indi/src/lx200classic.cpp68BINumberelevationLimit^/home/slovin/Projects/indi/src/lx200classic.cpp99­*INumberVectorPropertyZ/home/slovin/Projects/indi/src/lx200classic.hÿÿÿÿLX200ClassicZ/home/slovin/Projects/indi/src/lx200classic.h+LX200GenericISGetPropertiesZ/home/slovin/Projects/indi/src/lx200classic.h'LX200Classicdevÿÿÿÿconst char*ÿÿÿÿvoidISNewNumberZ/home/slovin/Projects/indi/src/lx200classic.h  \LX200Classicdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchZ/home/slovin/Projects/indi/src/lx200classic.h""\LX200ClassicµVÆdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextZ/home/slovin/Projects/indi/src/lx200classic.h!!XLX200Classicdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollZ/home/slovin/Projects/indi/src/lx200classic.h##LX200ClassicvoidLX200ClassicZ/home/slovin/Projects/indi/src/lx200classic.hLX200ClassicaÿÿÿÿgetBasicDataZ/home/slovin/Projects/indi/src/lx200classic.h$$LX200Classicvoid~ LX200ClassicZ/home/slovin/Projects/indi/src/lx200classic.hLX200Classicÿÿÿÿ~ LX200ClassicZ/home/slovin/Projects/indi/src/lx200classic.hLX200ClassicÿÿÿÿcurrentCatalogZ/home/slovin/Projects/indi/src/lx200classic.h''int"currentSubCatalogZ/home/slovin/Projects/indi/src/lx200classic.h((int8changeLX200ClassicDeviceNameZ/home/slovin/Projects/indi/src/lx200classic.h--6newNameÿÿÿÿconst char*ÿÿÿÿvoidX/home/slovin/Projects/indi/src/lx200driver.cÿÿÿÿ-ACKX/home/slovin/Projects/indi/src/lx200driver.c44fdÿÿÿÿintÿÿÿÿcharHaltMovementX/home/slovin/Projects/indi/src/lx200driver.c'fdÿÿÿÿintÿÿÿÿdirectionÿÿÿÿintÿÿÿÿint MoveToX/home/slovin/Projects/indi/src/lx200driver.cŽŽ!fdÿÿÿÿintÿÿÿÿdirectionÿÿÿÿintÿÿÿÿintSlewX/home/slovin/Projects/indi/src/lx200driver.cˆˆfdÿÿÿÿintÿÿÿÿintSyncX/home/slovin/Projects/indi/src/lx200driver.cŠŠ%fdÿÿÿÿintÿÿÿÿmatchedObjectÿÿÿÿ char*ÿÿÿÿintabortSlewX/home/slovin/Projects/indi/src/lx200driver.cŒŒfdÿÿÿÿintÿÿÿÿint checkLX200FormatX/home/slovin/Projects/indi/src/lx200driver.cššfdÿÿÿÿintÿÿÿÿint,check_lx200_connectionX/home/slovin/Projects/indi/src/lx200driver.c77"fdÿÿÿÿintÿÿÿÿintgetCalenderDateX/home/slovin/Projects/indi/src/lx200driver.cJJ'fdÿÿÿÿintÿÿÿÿdateÿÿÿÿ char*ÿÿÿÿintgetCommandIntX/home/slovin/Projects/indi/src/lx200driver.cBB6fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿint*ÿÿÿÿcmdÿÿÿÿconst char*ÿÿÿÿintgetCommandSexaX/home/slovin/Projects/indi/src/lx200driver.c>>:fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿcmdÿÿÿÿconst char*ÿÿÿÿint getCommandStringX/home/slovin/Projects/indi/src/lx200driver.c@@9fdÿÿÿÿintÿÿÿÿdataÿÿÿÿ char*ÿÿÿÿcmdÿÿÿÿconst char*ÿÿÿÿint&getHomeSearchStatusX/home/slovin/Projects/indi/src/lx200driver.cPP,fdÿÿÿÿintÿÿÿÿ statusÿÿÿÿint*ÿÿÿÿintgetNumberOfBarsX/home/slovin/Projects/indi/src/lx200driver.cNN'fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿint*ÿÿÿÿintgetOTATempX/home/slovin/Projects/indi/src/lx200driver.cRR&fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿintgetSiteLatitudeX/home/slovin/Projects/indi/src/lx200driver.cFF-fdÿÿÿÿintÿÿÿÿddÿÿÿÿint*ÿÿÿÿmmÿÿÿÿint*ÿÿÿÿint getSiteLongitudeX/home/slovin/Projects/indi/src/lx200driver.cHH/fdÿÿÿÿintÿÿÿÿdddÿÿÿÿint*ÿÿÿÿmmÿÿÿÿint*ÿÿÿÿintgetSiteNameX/home/slovin/Projects/indi/src/lx200driver.cLL4fdÿÿÿÿintÿÿÿÿsiteNameÿÿÿÿ char*ÿÿÿÿsiteNumÿÿÿÿintÿÿÿÿintgetTimeFormatX/home/slovin/Projects/indi/src/lx200driver.cTT&fdÿÿÿÿintÿÿÿÿ formatÿÿÿÿint*ÿÿÿÿintgetTrackFreqX/home/slovin/Projects/indi/src/lx200driver.cDD(fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint(selectAPTrackingModeX/home/slovin/Projects/indi/src/lx200driver.c””/fdÿÿÿÿintÿÿÿÿtrackModeÿÿÿÿintÿÿÿÿint&selectCatalogObjectX/home/slovin/Projects/indi/src/lx200driver.cžž6fdÿÿÿÿintÿÿÿÿcatalogÿÿÿÿintÿÿÿÿNNNNÿÿÿÿintÿÿÿÿintselectSiteX/home/slovin/Projects/indi/src/lx200driver.cœœ#fdÿÿÿÿintÿÿÿÿsiteNumÿÿÿÿintÿÿÿÿint selectSubCatalogX/home/slovin/Projects/indi/src/lx200driver.c  9fdÿÿÿÿintÿÿÿÿcatalogÿÿÿÿintÿÿÿÿsubCatalogÿÿÿÿintÿÿÿÿint$selectTrackingModeX/home/slovin/Projects/indi/src/lx200driver.c’’-fdÿÿÿÿintÿÿÿÿtrackModeÿÿÿÿintÿÿÿÿint setAlignmentModeX/home/slovin/Projects/indi/src/lx200driver.cdd4fdÿÿÿÿintÿÿÿÿalignModeÿÿÿÿunsigned intÿÿÿÿintsetCalenderDateX/home/slovin/Projects/indi/src/lx200driver.cjj3fdÿÿÿÿintÿÿÿÿddÿÿÿÿintÿÿÿÿmmÿÿÿÿintÿÿÿÿyyÿÿÿÿintÿÿÿÿintsetCommandIntX/home/slovin/Projects/indi/src/lx200driver.c\\4fdÿÿÿÿintÿÿÿÿdataÿÿÿÿintÿÿÿÿcmdÿÿÿÿconst char*ÿÿÿÿintsetCommandXYZX/home/slovin/Projects/indi/src/lx200driver.c^^?fdÿÿÿÿintÿÿÿÿxÿÿÿÿintÿÿÿÿyÿÿÿÿintÿÿÿÿzÿÿÿÿintÿÿÿÿcmdÿÿÿÿconst char*ÿÿÿÿint setFocuserMotionX/home/slovin/Projects/indi/src/lx200driver.c||,fdÿÿÿÿintÿÿÿÿmotionTypeÿÿÿÿintÿÿÿÿint&setFocuserSpeedModeX/home/slovin/Projects/indi/src/lx200driver.c~~/fdÿÿÿÿintÿÿÿÿspeedModeÿÿÿÿintÿÿÿÿint(setMaxElevationLimitX/home/slovin/Projects/indi/src/lx200driver.c‚‚)fdÿÿÿÿintÿÿÿÿmaxÿÿÿÿintÿÿÿÿintsetMaxSlewRateX/home/slovin/Projects/indi/src/lx200driver.czz(fdÿÿÿÿintÿÿÿÿslewRateÿÿÿÿintÿÿÿÿint(setMinElevationLimitX/home/slovin/Projects/indi/src/lx200driver.c€€)fdÿÿÿÿintÿÿÿÿminÿÿÿÿintÿÿÿÿintsetObjAltX/home/slovin/Projects/indi/src/lx200driver.cvv!fdÿÿÿÿintÿÿÿÿaltÿÿÿÿ doubleÿÿÿÿintsetObjAzX/home/slovin/Projects/indi/src/lx200driver.cttfdÿÿÿÿintÿÿÿÿazÿÿÿÿ doubleÿÿÿÿintsetObjectDECX/home/slovin/Projects/indi/src/lx200driver.chh$fdÿÿÿÿintÿÿÿÿdecÿÿÿÿ doubleÿÿÿÿintsetObjectRAX/home/slovin/Projects/indi/src/lx200driver.cff"fdÿÿÿÿintÿÿÿÿraÿÿÿÿ doubleÿÿÿÿintsetSiteLatitudeX/home/slovin/Projects/indi/src/lx200driver.crr'fdÿÿÿÿintÿÿÿÿLatÿÿÿÿ doubleÿÿÿÿint setSiteLongitudeX/home/slovin/Projects/indi/src/lx200driver.cpp)fdÿÿÿÿintÿÿÿÿLongÿÿÿÿ doubleÿÿÿÿintsetSiteNameX/home/slovin/Projects/indi/src/lx200driver.cxx5fdÿÿÿÿintÿÿÿÿsiteNameÿÿÿÿ char*ÿÿÿÿsiteNumÿÿÿÿintÿÿÿÿintsetSlewModeX/home/slovin/Projects/indi/src/lx200driver.cbb%fdÿÿÿÿintÿÿÿÿslewModeÿÿÿÿintÿÿÿÿint(setStandardProcedureX/home/slovin/Projects/indi/src/lx200driver.c``2fdÿÿÿÿintÿÿÿÿwriteDataÿÿÿÿ char*ÿÿÿÿintsetTrackFreqX/home/slovin/Projects/indi/src/lx200driver.cnn'fdÿÿÿÿintÿÿÿÿ trackFÿÿÿÿ doubleÿÿÿÿintsetUTCOffsetX/home/slovin/Projects/indi/src/lx200driver.cll&fdÿÿÿÿintÿÿÿÿ hoursÿÿÿÿ doubleÿÿÿÿint.ACKX/home/slovin/Projects/indi/src/lx200driver.cèúfdÿÿÿÿintÿÿÿÿcharHaltMovementX/home/slovin/Projects/indi/src/lx200driver.cÅòfdÿÿÿÿintÿÿÿÿdirectionÿÿÿÿintÿÿÿÿint MoveToX/home/slovin/Projects/indi/src/lx200driver.c§ÃfdÿÿÿÿintÿÿÿÿdirectionÿÿÿÿintÿÿÿÿintSlewX/home/slovin/Projects/indi/src/lx200driver.cƒ¥fdÿÿÿÿintÿÿÿÿintSyncX/home/slovin/Projects/indi/src/lx200driver.cfdÿÿÿÿintÿÿÿÿmatchedObjectÿÿÿÿ char*ÿÿÿÿintabortSlewX/home/slovin/Projects/indi/src/lx200driver.côfdÿÿÿÿintÿÿÿÿint checkLX200FormatX/home/slovin/Projects/indi/src/lx200driver.cx•fdÿÿÿÿintÿÿÿÿint,check_lx200_connectionX/home/slovin/Projects/indi/src/lx200driver.cÉá in_fdÿÿÿÿintÿÿÿÿintgetCalenderDateX/home/slovin/Projects/indi/src/lx200driver.c9Ofdÿÿÿÿintÿÿÿÿdateÿÿÿÿ char*ÿÿÿÿintgetCommandSexaX/home/slovin/Projects/indi/src/lx200driver.cüfdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿcmdÿÿÿÿconst char*ÿÿÿÿint getCommandStringX/home/slovin/Projects/indi/src/lx200driver.c7fdÿÿÿÿintÿÿÿÿdataÿÿÿÿ char*ÿÿÿÿcmdÿÿÿÿconst char*ÿÿÿÿint&getHomeSearchStatusX/home/slovin/Projects/indi/src/lx200driver.c)Efdÿÿÿÿintÿÿÿÿ statusÿÿÿÿint*ÿÿÿÿintgetNumberOfBarsX/home/slovin/Projects/indi/src/lx200driver.c'fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿint*ÿÿÿÿintgetOTATempX/home/slovin/Projects/indi/src/lx200driver.cGefdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿintgetSiteLatitudeX/home/slovin/Projects/indi/src/lx200driver.c°Ífdÿÿÿÿintÿÿÿÿddÿÿÿÿint*ÿÿÿÿmmÿÿÿÿint*ÿÿÿÿint getSiteLongitudeX/home/slovin/Projects/indi/src/lx200driver.cÏífdÿÿÿÿintÿÿÿÿdddÿÿÿÿint*ÿÿÿÿmmÿÿÿÿint*ÿÿÿÿintgetSiteNameX/home/slovin/Projects/indi/src/lx200driver.ct®fdÿÿÿÿintÿÿÿÿsiteNameÿÿÿÿ char*ÿÿÿÿsiteNumÿÿÿÿintÿÿÿÿintgetTimeFormatX/home/slovin/Projects/indi/src/lx200driver.cQrfdÿÿÿÿintÿÿÿÿ formatÿÿÿÿint*ÿÿÿÿintgetTrackFreqX/home/slovin/Projects/indi/src/lx200driver.cïfdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint&selectCatalogObjectX/home/slovin/Projects/indi/src/lx200driver.cFbfdÿÿÿÿintÿÿÿÿcatalogÿÿÿÿintÿÿÿÿNNNNÿÿÿÿintÿÿÿÿintselectSiteX/home/slovin/Projects/indi/src/lx200driver.cDfdÿÿÿÿintÿÿÿÿsiteNumÿÿÿÿintÿÿÿÿint selectSubCatalogX/home/slovin/Projects/indi/src/lx200driver.cdvfdÿÿÿÿintÿÿÿÿcatalogÿÿÿÿintÿÿÿÿsubCatalogÿÿÿÿintÿÿÿÿint$selectTrackingModeX/home/slovin/Projects/indi/src/lx200driver.c—ÁfdÿÿÿÿintÿÿÿÿtrackModeÿÿÿÿintÿÿÿÿint setAlignmentModeX/home/slovin/Projects/indi/src/lx200driver.cHffdÿÿÿÿintÿÿÿÿalignModeÿÿÿÿunsigned intÿÿÿÿintsetCalenderDateX/home/slovin/Projects/indi/src/lx200driver.chŠfdÿÿÿÿintÿÿÿÿddÿÿÿÿintÿÿÿÿmmÿÿÿÿintÿÿÿÿyyÿÿÿÿintÿÿÿÿintsetCommandIntX/home/slovin/Projects/indi/src/lx200driver.cØçfdÿÿÿÿintÿÿÿÿdataÿÿÿÿintÿÿÿÿcmdÿÿÿÿconst char*ÿÿÿÿintsetCommandXYZX/home/slovin/Projects/indi/src/lx200driver.c?Ffdÿÿÿÿintÿÿÿÿxÿÿÿÿintÿÿÿÿyÿÿÿÿintÿÿÿÿzÿÿÿÿintÿÿÿÿcmdÿÿÿÿconst char*ÿÿÿÿint setFocuserMotionX/home/slovin/Projects/indi/src/lx200driver.c )fdÿÿÿÿintÿÿÿÿmotionTypeÿÿÿÿintÿÿÿÿint&setFocuserSpeedModeX/home/slovin/Projects/indi/src/lx200driver.c+QfdÿÿÿÿintÿÿÿÿspeedModeÿÿÿÿintÿÿÿÿint$setGPSFocuserSpeedX/home/slovin/Projects/indi/src/lx200driver.cSsfdÿÿÿÿintÿÿÿÿ speedÿÿÿÿintÿÿÿÿint(setMaxElevationLimitX/home/slovin/Projects/indi/src/lx200driver.còúfdÿÿÿÿintÿÿÿÿmaxÿÿÿÿintÿÿÿÿintsetMaxSlewRateX/home/slovin/Projects/indi/src/lx200driver.cüfdÿÿÿÿintÿÿÿÿslewRateÿÿÿÿintÿÿÿÿint(setMinElevationLimitX/home/slovin/Projects/indi/src/lx200driver.céðfdÿÿÿÿintÿÿÿÿminÿÿÿÿintÿÿÿÿintsetObjAltX/home/slovin/Projects/indi/src/lx200driver.c½Çfdÿÿÿÿintÿÿÿÿaltÿÿÿÿ doubleÿÿÿÿintsetObjAzX/home/slovin/Projects/indi/src/lx200driver.c°»fdÿÿÿÿintÿÿÿÿazÿÿÿÿ doubleÿÿÿÿintsetObjectDECX/home/slovin/Projects/indi/src/lx200driver.c=fdÿÿÿÿintÿÿÿÿdecÿÿÿÿ doubleÿÿÿÿintsetObjectRAX/home/slovin/Projects/indi/src/lx200driver.c fdÿÿÿÿintÿÿÿÿraÿÿÿÿ doubleÿÿÿÿintsetSiteLatitudeX/home/slovin/Projects/indi/src/lx200driver.c¤®fdÿÿÿÿintÿÿÿÿLatÿÿÿÿ doubleÿÿÿÿint setSiteLongitudeX/home/slovin/Projects/indi/src/lx200driver.c˜¢fdÿÿÿÿintÿÿÿÿLongÿÿÿÿ doubleÿÿÿÿintsetSiteNameX/home/slovin/Projects/indi/src/lx200driver.cÊâfdÿÿÿÿintÿÿÿÿsiteNameÿÿÿÿ char*ÿÿÿÿsiteNumÿÿÿÿintÿÿÿÿintsetSlewModeX/home/slovin/Projects/indi/src/lx200driver.cä fdÿÿÿÿintÿÿÿÿslewModeÿÿÿÿintÿÿÿÿint(setStandardProcedureX/home/slovin/Projects/indi/src/lx200driver.c·Öfdÿÿÿÿintÿÿÿÿdataÿÿÿÿ char*ÿÿÿÿintsetTrackFreqX/home/slovin/Projects/indi/src/lx200driver.cu}fdÿÿÿÿintÿÿÿÿ trackFÿÿÿÿ doubleÿÿÿÿintsetUTCOffsetX/home/slovin/Projects/indi/src/lx200driver.cŒ–fdÿÿÿÿintÿÿÿÿ hoursÿÿÿÿ doubleÿÿÿÿint.updateIntelliscopeCoordX/home/slovin/Projects/indi/src/lx200driver.c†°fdÿÿÿÿintÿÿÿÿraÿÿÿÿdouble*ÿÿÿÿdecÿÿÿÿdouble*ÿÿÿÿint.updateSkyCommanderCoordX/home/slovin/Projects/indi/src/lx200driver.cg„fdÿÿÿÿintÿÿÿÿraÿÿÿÿdouble*ÿÿÿÿdecÿÿÿÿdouble*ÿÿÿÿint"controller_formatX/home/slovin/Projects/indi/src/lx200driver.c%%intX/home/slovin/Projects/indi/src/lx200driver.hÿÿÿÿ%LX200_24X/home/slovin/Projects/indi/src/lx200driver.h  intLX200_ABELLX/home/slovin/Projects/indi/src/lx200driver.h)Q)\int"LX200_ALIGN_ALTAZX/home/slovin/Projects/indi/src/lx200driver.h"3int LX200_ALIGN_LANDX/home/slovin/Projects/indi/src/lx200driver.h5Eint"LX200_ALIGN_POLARX/home/slovin/Projects/indi/src/lx200driver.h intLX200_ALLX/home/slovin/Projects/indi/src/lx200driver.hDMintLX200_AMX/home/slovin/Projects/indi/src/lx200driver.h  %intLX200_ARPX/home/slovin/Projects/indi/src/lx200driver.h)F)OintLX200_CALDWELLX/home/slovin/Projects/indi/src/lx200driver.h)6)DintLX200_DEEPSKY_CX/home/slovin/Projects/indi/src/lx200driver.h%%-intLX200_EASTX/home/slovin/Projects/indi/src/lx200driver.h+5intLX200_FOCUSFASTX/home/slovin/Projects/indi/src/lx200driver.h#:#IintLX200_FOCUSINX/home/slovin/Projects/indi/src/lx200driver.h""!intLX200_FOCUSOUTX/home/slovin/Projects/indi/src/lx200driver.h"#"1intLX200_FOCUSSLOWX/home/slovin/Projects/indi/src/lx200driver.h#)#8intLX200_GCVSX/home/slovin/Projects/indi/src/lx200driver.h'*'4intLX200_HALTFOCUSX/home/slovin/Projects/indi/src/lx200driver.h##'intLX200_ICX/home/slovin/Projects/indi/src/lx200driver.h)!))int"LX200_LONG_FORMATX/home/slovin/Projects/indi/src/lx200driver.h#4intLX200_MESSIER_CX/home/slovin/Projects/indi/src/lx200driver.h)^)mintLX200_NGCX/home/slovin/Projects/indi/src/lx200driver.h))intLX200_NORTHX/home/slovin/Projects/indi/src/lx200driver.hintLX200_PMX/home/slovin/Projects/indi/src/lx200driver.h ' /intLX200_SAOX/home/slovin/Projects/indi/src/lx200driver.h''(int$LX200_SHORT_FORMATX/home/slovin/Projects/indi/src/lx200driver.h!int"LX200_SLEW_CENTERX/home/slovin/Projects/indi/src/lx200driver.h.?intLX200_SLEW_FINDX/home/slovin/Projects/indi/src/lx200driver.h,int LX200_SLEW_GUIDEX/home/slovin/Projects/indi/src/lx200driver.hAQintLX200_SLEW_MAXX/home/slovin/Projects/indi/src/lx200driver.h intLX200_SOUTHX/home/slovin/Projects/indi/src/lx200driver.h7BintLX200_STARX/home/slovin/Projects/indi/src/lx200driver.h''intLX200_STAR_CX/home/slovin/Projects/indi/src/lx200driver.h%%int&LX200_TRACK_DEFAULTX/home/slovin/Projects/indi/src/lx200driver.h+ + int"LX200_TRACK_LUNARX/home/slovin/Projects/indi/src/lx200driver.h+"+3int$LX200_TRACK_MANUALX/home/slovin/Projects/indi/src/lx200driver.h+5+GintLX200_UGCX/home/slovin/Projects/indi/src/lx200driver.h)+)4intLX200_WESTX/home/slovin/Projects/indi/src/lx200driver.h)int^/home/slovin/Projects/indi/src/lx200generic.cppÿÿÿÿ ISPoll^/home/slovin/Projects/indi/src/lx200generic.cppg gÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoidretryConnection^/home/slovin/Projects/indi/src/lx200generic.cpph h#ÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoid&ISGetProperties^/home/slovin/Projects/indi/src/lx200generic.cpp9:Pdevÿÿÿÿconst char*ÿÿÿÿvoidISGetProperties^/home/slovin/Projects/indi/src/lx200generic.cppw¢LX200Genericdevÿÿÿÿconst char*ÿÿÿÿvoid ISInit^/home/slovin/Projects/indi/src/lx200generic.cppô7voidISNewBLOB^/home/slovin/Projects/indi/src/lx200generic.cppBCÿÿÿÿÿÿÿÿconst char*ÿÿÿÿÿÿÿÿÿÿÿÿconst char*ÿÿÿÿÿÿÿÿÿÿÿÿint*ÿÿÿÿÿÿÿÿÿÿÿÿ char**ÿÿÿÿÿÿÿÿÿÿÿÿ char**ÿÿÿÿÿÿÿÿÿÿÿÿ char**ÿÿÿÿÿÿÿÿÿÿÿÿintÿÿÿÿvoidISNewNumber^/home/slovin/Projects/indi/src/lx200generic.cpp?@Adevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewNumber^/home/slovin/Projects/indi/src/lx200generic.cpp1#LX200Genericdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitch^/home/slovin/Projects/indi/src/lx200generic.cpp;<Adevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitch^/home/slovin/Projects/indi/src/lx200generic.cpp%·LX200Genericdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewText^/home/slovin/Projects/indi/src/lx200generic.cpp=>>devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewText^/home/slovin/Projects/indi/src/lx200generic.cpp¤.LX200Genericdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPoll^/home/slovin/Projects/indi/src/lx200generic.cppAAUpÿÿÿÿ void*ÿÿÿÿvoid ISPoll^/home/slovin/Projects/indi/src/lx200generic.cpppÿLX200GenericvoidLX200Generic^/home/slovin/Projects/indi/src/lx200generic.cppIkLX200Genericÿÿÿÿ(changeAllDeviceNames^/home/slovin/Projects/indi/src/lx200generic.cppéðnewNameÿÿÿÿconst char*ÿÿÿÿvoid8changeLX200GenericDeviceName^/home/slovin/Projects/indi/src/lx200generic.cppÅçnewNameÿÿÿÿconst char*ÿÿÿÿvoidcheckPower^/home/slovin/Projects/indi/src/lx200generic.cpp,LX200Genericspÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿintcheckPower^/home/slovin/Projects/indi/src/lx200generic.cpp.ALX200Genericnpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿintcheckPower^/home/slovin/Projects/indi/src/lx200generic.cppCVLX200Generictpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿintcorrectFault^/home/slovin/Projects/indi/src/lx200generic.cpp LX200Genericvoid enableSimulation^/home/slovin/Projects/indi/src/lx200generic.cpp¹ÁLX200Generic enableÿÿÿÿboolÿÿÿÿvoidgetAlignment^/home/slovin/Projects/indi/src/lx200generic.cpp™·LX200GenericvoidgetBasicData^/home/slovin/Projects/indi/src/lx200generic.cppV‡LX200GenericvoidgetOnSwitch^/home/slovin/Projects/indi/src/lx200generic.cppLX200Genericspÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿinthandleCoordSet^/home/slovin/Projects/indi/src/lx200generic.cpp‰LX200GenericinthandleError^/home/slovin/Projects/indi/src/lx200generic.cpp¹×LX200Genericsvpÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoidhandleError^/home/slovin/Projects/indi/src/lx200generic.cppÙ÷LX200Genericnvpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoidhandleError^/home/slovin/Projects/indi/src/lx200generic.cppùLX200Generictvpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoidisTelescopeOn^/home/slovin/Projects/indi/src/lx200generic.cpp"'LX200GenericÿÿÿÿÿÿÿÿvoidÿÿÿÿboolmountSim^/home/slovin/Projects/indi/src/lx200generic.cppTLX200GenericvoidpowerTelescope^/home/slovin/Projects/indi/src/lx200generic.cppX‡LX200GenericvoidretryConnection^/home/slovin/Projects/indi/src/lx200generic.cpp):pÿÿÿÿ void*ÿÿÿÿvoid(setCurrentDeviceName^/home/slovin/Projects/indi/src/lx200generic.cppruLX200GenericdevNameÿÿÿÿconst char*ÿÿÿÿvoidslewError^/home/slovin/Projects/indi/src/lx200generic.cpp‰—LX200GenericslewCodeÿÿÿÿintÿÿÿÿvoidtimezoneOffset^/home/slovin/Projects/indi/src/lx200generic.cpp9J double updateFocusTimer^/home/slovin/Projects/indi/src/lx200generic.cpp<nLX200Genericpÿÿÿÿ void*ÿÿÿÿvoidupdateLocation^/home/slovin/Projects/indi/src/lx200generic.cpp€ŸLX200GenericvoidupdateTime^/home/slovin/Projects/indi/src/lx200generic.cppÃ~LX200Genericvoid~ LX200Generic^/home/slovin/Projects/indi/src/lx200generic.cppmpLX200Genericÿÿÿÿ-AlignmentS^/home/slovin/Projects/indi/src/lx200generic.cppll{ISwitchAlignmentSw^/home/slovin/Projects/indi/src/lx200generic.cppŒŒ¨*ISwitchVectorPropertyFocusModeS^/home/slovin/Projects/indi/src/lx200generic.cppŸ¡/ISwitchFocusModeSP^/home/slovin/Projects/indi/src/lx200generic.cpp¢¢­*ISwitchVectorPropertyFocusMotionS^/home/slovin/Projects/indi/src/lx200generic.cppv vdISwitchFocusMotionSw^/home/slovin/Projects/indi/src/lx200generic.cppww°*ISwitchVectorPropertyFocusTimerN^/home/slovin/Projects/indi/src/lx200generic.cppy ybINumberFocusTimerNP^/home/slovin/Projects/indi/src/lx200generic.cppzz¥*INumberVectorProperty&MaxReticleFlashRate^/home/slovin/Projects/indi/src/lx200generic.cppMMintMovementS^/home/slovin/Projects/indi/src/lx200generic.cppttISwitchMovementSw^/home/slovin/Projects/indi/src/lx200generic.cpp·*ISwitchVectorPropertyOnCoordSetS^/home/slovin/Projects/indi/src/lx200generic.cppoo‰ISwitchOnCoordSetSw^/home/slovin/Projects/indi/src/lx200generic.cpp·*ISwitchVectorProperty ParkS^/home/slovin/Projects/indi/src/lx200generic.cpprr>ISwitch ParkSP^/home/slovin/Projects/indi/src/lx200generic.cpp““—*ISwitchVectorPropertyPort^/home/slovin/Projects/indi/src/lx200generic.cpp‰‰&ITextVectorProperty PortT^/home/slovin/Projects/indi/src/lx200generic.cppˆ ˆ7 IText PowerS^/home/slovin/Projects/indi/src/lx200generic.cppkkwISwitchPowerSP^/home/slovin/Projects/indi/src/lx200generic.cpp‡‡¢*ISwitchVectorProperty SDTime^/home/slovin/Projects/indi/src/lx200generic.cpp¨¨*INumberVectorProperty STime^/home/slovin/Projects/indi/src/lx200generic.cpp§§UINumberSiteName^/home/slovin/Projects/indi/src/lx200generic.cppÃ×&ITextVectorPropertySiteNameT^/home/slovin/Projects/indi/src/lx200generic.cppÂÂ; IText SitesS^/home/slovin/Projects/indi/src/lx200generic.cppmm ISwitchSitesSw^/home/slovin/Projects/indi/src/lx200generic.cpp¹¹›*ISwitchVectorPropertySlewModeS^/home/slovin/Projects/indi/src/lx200generic.cppnnœISwitchSlewModeSw^/home/slovin/Projects/indi/src/lx200generic.cpp••­*ISwitchVectorPropertyTime^/home/slovin/Projects/indi/src/lx200generic.cpp¦¦€&ITextVectorPropertyTrackFreq^/home/slovin/Projects/indi/src/lx200generic.cpp™™\INumberTrackModeS^/home/slovin/Projects/indi/src/lx200generic.cpppp‚ISwitchTrackModeSw^/home/slovin/Projects/indi/src/lx200generic.cpp——°*ISwitchVectorPropertyTrackingFreq^/home/slovin/Projects/indi/src/lx200generic.cpp››¥*INumberVectorPropertyUTC^/home/slovin/Projects/indi/src/lx200generic.cpp¥ ¥1 ITextabortSlewS^/home/slovin/Projects/indi/src/lx200generic.cppqqGISwitchabortSlewSw^/home/slovin/Projects/indi/src/lx200generic.cpp‘‘¿*ISwitchVectorPropertyeq^/home/slovin/Projects/indi/src/lx200generic.cpp}€INumber eqNum^/home/slovin/Projects/indi/src/lx200generic.cpp‚„*INumberVectorPropertygeo^/home/slovin/Projects/indi/src/lx200generic.cpp»¾INumber geoNum^/home/slovin/Projects/indi/src/lx200generic.cpp¿Á*INumberVectorPropertyindi_daylight^/home/slovin/Projects/indi/src/lx200generic.cpp6 6intslewPrecisionN^/home/slovin/Projects/indi/src/lx200generic.cpp²µINumberslewPrecisionNP^/home/slovin/Projects/indi/src/lx200generic.cpp¶¶®*INumberVectorPropertytelescope^/home/slovin/Projects/indi/src/lx200generic.cppL LLX200Generic*$trackingPrecisionN^/home/slovin/Projects/indi/src/lx200generic.cpp«®INumber&trackingPrecisionNP^/home/slovin/Projects/indi/src/lx200generic.cpp¯¯¾*INumberVectorPropertyZ/home/slovin/Projects/indi/src/lx200generic.hÿÿÿÿLX200GenericZ/home/slovin/Projects/indi/src/lx200generic.hXISGetPropertiesZ/home/slovin/Projects/indi/src/lx200generic.h##/LX200Genericdevÿÿÿÿconst char*ÿÿÿÿvoidISNewNumberZ/home/slovin/Projects/indi/src/lx200generic.h$$dLX200Generic …devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchZ/home/slovin/Projects/indi/src/lx200generic.h&&dLX200Generic ,devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextZ/home/slovin/Projects/indi/src/lx200generic.h%%`LX200Generic·UÇdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollZ/home/slovin/Projects/indi/src/lx200generic.h''LX200GenericvoidLX200GenericZ/home/slovin/Projects/indi/src/lx200generic.h  LX200GenericaÿÿÿÿcheckPowerZ/home/slovin/Projects/indi/src/lx200generic.h***LX200Genericnpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿintcheckPowerZ/home/slovin/Projects/indi/src/lx200generic.h++*LX200Generic ±spÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿintcheckPowerZ/home/slovin/Projects/indi/src/lx200generic.h,,(LX200Generic ¾tpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿintcorrectFaultZ/home/slovin/Projects/indi/src/lx200generic.h77LX200Generic (z€void enableSimulationZ/home/slovin/Projects/indi/src/lx200generic.h88#LX200Generic enableÿÿÿÿboolÿÿÿÿvoidgetAlignmentZ/home/slovin/Projects/indi/src/lx200generic.h33LX200GenericfvoidgetBasicDataZ/home/slovin/Projects/indi/src/lx200generic.h((LX200GenericvoidgetOnSwitchZ/home/slovin/Projects/indi/src/lx200generic.h55+LX200Genericispÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿinthandleCoordSetZ/home/slovin/Projects/indi/src/lx200generic.h44LX200GenericointhandleErrorZ/home/slovin/Projects/indi/src/lx200generic.h--GLX200Genericsvpÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoidhandleErrorZ/home/slovin/Projects/indi/src/lx200generic.h..GLX200Genericnvpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoidhandleErrorZ/home/slovin/Projects/indi/src/lx200generic.h//ELX200Generictvpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoidisTelescopeOnZ/home/slovin/Projects/indi/src/lx200generic.h00LX200GenericrÿÿÿÿÿÿÿÿvoidÿÿÿÿboolmountSimZ/home/slovin/Projects/indi/src/lx200generic.h;;LX200GenericµVÆvoidpowerTelescopeZ/home/slovin/Projects/indi/src/lx200generic.h11LX200Generictvoid(setCurrentDeviceNameZ/home/slovin/Projects/indi/src/lx200generic.h660LX200GenericdevNameÿÿÿÿconst char*ÿÿÿÿvoidslewErrorZ/home/slovin/Projects/indi/src/lx200generic.h22LX200GenericsslewCodeÿÿÿÿintÿÿÿÿvoid updateFocusTimerZ/home/slovin/Projects/indi/src/lx200generic.h= =&LX200Genericpÿÿÿÿ void*ÿÿÿÿvoidupdateLocationZ/home/slovin/Projects/indi/src/lx200generic.h::LX200GenericvoidupdateTimeZ/home/slovin/Projects/indi/src/lx200generic.h99LX200Genericvoid~ LX200GenericZ/home/slovin/Projects/indi/src/lx200generic.h! !LX200GenericÿÿÿÿJDZ/home/slovin/Projects/indi/src/lx200generic.hE E  doubleUTCOffsetZ/home/slovin/Projects/indi/src/lx200generic.hL L doublecurrentDECZ/home/slovin/Projects/indi/src/lx200generic.hG G doublecurrentRAZ/home/slovin/Projects/indi/src/lx200generic.hF F doublecurrentSetZ/home/slovin/Projects/indi/src/lx200generic.hTTintcurrentSiteNumZ/home/slovin/Projects/indi/src/lx200generic.hBBint faultZ/home/slovin/Projects/indi/src/lx200generic.hM MboolfdZ/home/slovin/Projects/indi/src/lx200generic.h>> intlastDECZ/home/slovin/Projects/indi/src/lx200generic.hK K doublelastMoveZ/home/slovin/Projects/indi/src/lx200generic.hVVint lastRAZ/home/slovin/Projects/indi/src/lx200generic.hJ J doublelastSetZ/home/slovin/Projects/indi/src/lx200generic.hUU intlast_local_timeZ/home/slovin/Projects/indi/src/lx200generic.hP Pstruct tm*simulationZ/home/slovin/Projects/indi/src/lx200generic.hN NbooltargetDECZ/home/slovin/Projects/indi/src/lx200generic.hI I doubletargetRAZ/home/slovin/Projects/indi/src/lx200generic.hH H doublethisDeviceZ/home/slovin/Projects/indi/src/lx200generic.hRRchartimeFormatZ/home/slovin/Projects/indi/src/lx200generic.hAAinttrackingModeZ/home/slovin/Projects/indi/src/lx200generic.hCCint(changeAllDeviceNamesZ/home/slovin/Projects/indi/src/lx200generic.h[[.newNameÿÿÿÿconst char*ÿÿÿÿvoid8changeLX200GenericDeviceNameZ/home/slovin/Projects/indi/src/lx200generic.hZZ7newNameÿÿÿÿconst char*ÿÿÿÿvoidV/home/slovin/Projects/indi/src/lx200gps.cppÿÿÿÿupdateTempV/home/slovin/Projects/indi/src/lx200gps.cpp88bpÿÿÿÿ void*ÿÿÿÿvoid ISGetPropertiesV/home/slovin/Projects/indi/src/lx200gps.cppOcLX200GPS .#devÿÿÿÿconst char*ÿÿÿÿvoidISNewNumberV/home/slovin/Projects/indi/src/lx200gps.cppnsLX200GPSdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchV/home/slovin/Projects/indi/src/lx200gps.cppv*LX200GPS :¾€devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextV/home/slovin/Projects/indi/src/lx200gps.cppelLX200GPSdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollV/home/slovin/Projects/indi/src/lx200gps.cpp,2LX200GPSvoidLX200GPSV/home/slovin/Projects/indi/src/lx200gps.cppIMLX200GPSÿÿÿÿ0changeLX200GPSDeviceNameV/home/slovin/Projects/indi/src/lx200gps.cpp:GsnewNameÿÿÿÿconst char*ÿÿÿÿvoidgetBasicDataV/home/slovin/Projects/indi/src/lx200gps.cppLTLX200GPSvoidupdateTempV/home/slovin/Projects/indi/src/lx200gps.cpp4J €pÿÿÿÿ void*ÿÿÿÿvoid AltDecBackSlashSV/home/slovin/Projects/indi/src/lx200gps.cpp''FISwitch"AltDecBackSlashSwV/home/slovin/Projects/indi/src/lx200gps.cpp11Í*ISwitchVectorPropertyAltDecPecSV/home/slovin/Projects/indi/src/lx200gps.cpp$$_ISwitchAltDecPecSwV/home/slovin/Projects/indi/src/lx200gps.cpp..²*ISwitchVectorPropertyAzRaBackSlashSV/home/slovin/Projects/indi/src/lx200gps.cpp((EISwitchAzRaBackSlashSwV/home/slovin/Projects/indi/src/lx200gps.cpp22Å*ISwitchVectorPropertyAzRaPecSV/home/slovin/Projects/indi/src/lx200gps.cpp%%]ISwitchAzRaPecSwV/home/slovin/Projects/indi/src/lx200gps.cpp//«*ISwitchVectorPropertyGPSPowerSV/home/slovin/Projects/indi/src/lx200gps.cpp!!UISwitchGPSPowerSwV/home/slovin/Projects/indi/src/lx200gps.cpp++¯*ISwitchVectorPropertyGPSStatusSV/home/slovin/Projects/indi/src/lx200gps.cpp""€ISwitchGPSStatusSwV/home/slovin/Projects/indi/src/lx200gps.cpp,,±*ISwitchVectorPropertyGPSUpdateSV/home/slovin/Projects/indi/src/lx200gps.cpp##AISwitchGPSUpdateSwV/home/slovin/Projects/indi/src/lx200gps.cpp--±*ISwitchVectorPropertyOTATempV/home/slovin/Projects/indi/src/lx200gps.cpp66*INumberVectorPropertyOTAUpdateSV/home/slovin/Projects/indi/src/lx200gps.cpp))?ISwitchOTAUpdateSwV/home/slovin/Projects/indi/src/lx200gps.cpp33¯*ISwitchVectorPropertySelenSyncSV/home/slovin/Projects/indi/src/lx200gps.cpp&&>ISwitchSelenSyncSwV/home/slovin/Projects/indi/src/lx200gps.cpp00¹*ISwitchVectorPropertyTempV/home/slovin/Projects/indi/src/lx200gps.cpp55NINumberR/home/slovin/Projects/indi/src/lx200gps.hÿÿÿÿLX200GPSR/home/slovin/Projects/indi/src/lx200gps.h&LX200_16ISGetPropertiesR/home/slovin/Projects/indi/src/lx200gps.h'LX200GPSdevÿÿÿÿconst char*ÿÿÿÿvoidISNewNumberR/home/slovin/Projects/indi/src/lx200gps.h  \LX200GPSidevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchR/home/slovin/Projects/indi/src/lx200gps.h""\LX200GPSdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextR/home/slovin/Projects/indi/src/lx200gps.h!!XLX200GPS ¯devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollR/home/slovin/Projects/indi/src/lx200gps.h##LX200GPS/voidLX200GPSR/home/slovin/Projects/indi/src/lx200gps.h LX200GPS )±ÿÿÿÿgetBasicDataR/home/slovin/Projects/indi/src/lx200gps.h$$LX200GPSivoid~ LX200GPSR/home/slovin/Projects/indi/src/lx200gps.hLX200GPSÿÿÿÿ~ LX200GPSR/home/slovin/Projects/indi/src/lx200gps.hLX200GPSÿÿÿÿ0changeLX200GPSDeviceNameR/home/slovin/Projects/indi/src/lx200gps.h((2newNameÿÿÿÿconst char*ÿÿÿÿvoidZ/home/slovin/Projects/indi/src/orionatlas.cppÿÿÿÿ ISPollZ/home/slovin/Projects/indi/src/orionatlas.cppA A\ÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoidCheckConnectTelZ/home/slovin/Projects/indi/src/orionatlas.cpp¿ÂOrionAtlasÿÿÿÿÿÿÿÿvoidÿÿÿÿintConnectTelZ/home/slovin/Projects/indi/src/orionatlas.cppÄüOrionAtlas$€portÿÿÿÿ char*ÿÿÿÿintDisconnectTelZ/home/slovin/Projects/indi/src/orionatlas.cppþOrionAtlas€ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidGetCoordsZ/home/slovin/Projects/indi/src/orionatlas.cppU—OrionAtlas SystemÿÿÿÿintÿÿÿÿintISGetPropertiesZ/home/slovin/Projects/indi/src/orionatlas.cppˆ‰- $æ€devÿÿÿÿconst char*ÿÿÿÿvoidISGetPropertiesZ/home/slovin/Projects/indi/src/orionatlas.cpp¡½OrionAtlasµVÆdevÿÿÿÿconst char*ÿÿÿÿvoid ISInitZ/home/slovin/Projects/indi/src/orionatlas.cppu†voidISNewBLOBZ/home/slovin/Projects/indi/src/orionatlas.cpp‘’rÿÿÿÿÿÿÿÿconst char*ÿÿÿÿÿÿÿÿÿÿÿÿconst char*ÿÿÿÿÿÿÿÿÿÿÿÿint*ÿÿÿÿÿÿÿÿÿÿÿÿ char**ÿÿÿÿÿÿÿÿÿÿÿÿ char**ÿÿÿÿÿÿÿÿÿÿÿÿ char**ÿÿÿÿÿÿÿÿÿÿÿÿintÿÿÿÿvoidISNewNumberZ/home/slovin/Projects/indi/src/orionatlas.cppŽA0devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewNumberZ/home/slovin/Projects/indi/src/orionatlas.cppÚOrionAtlas·UÇdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchZ/home/slovin/Projects/indi/src/orionatlas.cppŠ‹Adevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchZ/home/slovin/Projects/indi/src/orionatlas.cppwOrionAtlasdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextZ/home/slovin/Projects/indi/src/orionatlas.cppŒ>devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextZ/home/slovin/Projects/indi/src/orionatlas.cpp¿ØOrionAtlassdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollZ/home/slovin/Projects/indi/src/orionatlas.cpp]pÿÿÿÿ void*ÿÿÿÿvoid ISPollZ/home/slovin/Projects/indi/src/orionatlas.cppçùOrionAtlas ?ä€voidMoveScopeZ/home/slovin/Projects/indi/src/orionatlas.cppROrionAtlas·UÇ Systemÿÿÿÿintÿÿÿÿc1ÿÿÿÿ doubleÿÿÿÿc2ÿÿÿÿ doubleÿÿÿÿintOrionAtlasZ/home/slovin/Projects/indi/src/orionatlas.cpp”ŸOrionAtlasÿÿÿÿUpdateCoordsZ/home/slovin/Projects/indi/src/orionatlas.cppš¨OrionAtlas SystemÿÿÿÿintÿÿÿÿvoidcheckPowerZ/home/slovin/Projects/indi/src/orionatlas.cppy…OrionAtlas)spÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿintcheckPowerZ/home/slovin/Projects/indi/src/orionatlas.cpp‡“OrionAtlas ønpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿintcheckPowerZ/home/slovin/Projects/indi/src/orionatlas.cpp•¡OrionAtlas % €tpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿintgetBasicDataZ/home/slovin/Projects/indi/src/orionatlas.cpp£§OrionAtlas{voidlogZ/home/slovin/Projects/indi/src/orionatlas.cppûOrionAtlasfmtÿÿÿÿconst char*ÿÿÿÿvoidpowerTelescopeZ/home/slovin/Projects/indi/src/orionatlas.cpp©½OrionAtlasvoid readnZ/home/slovin/Projects/indi/src/orionatlas.cpp·ÊOrionAtlasnfdÿÿÿÿintÿÿÿÿptrÿÿÿÿunsigned char*ÿÿÿÿ nbytesÿÿÿÿintÿÿÿÿsecÿÿÿÿintÿÿÿÿinttelstatZ/home/slovin/Projects/indi/src/orionatlas.cpp×åOrionAtlas·UÇfdÿÿÿÿintÿÿÿÿsecÿÿÿÿintÿÿÿÿusecÿÿÿÿintÿÿÿÿint writenZ/home/slovin/Projects/indi/src/orionatlas.cppªµOrionAtlasfdÿÿÿÿintÿÿÿÿptrÿÿÿÿunsigned char*ÿÿÿÿ nbytesÿÿÿÿintÿÿÿÿintMovementAzAltSZ/home/slovin/Projects/indi/src/orionatlas.cpp__¿ISwitchMovementAzAltSwZ/home/slovin/Projects/indi/src/orionatlas.cppaaÕ*ISwitchVectorPropertyMovementRADecSZ/home/slovin/Projects/indi/src/orionatlas.cpp^^¿ISwitchMovementRADecSwZ/home/slovin/Projects/indi/src/orionatlas.cpp``Õ*ISwitchVectorPropertyOnCoordSetSZ/home/slovin/Projects/indi/src/orionatlas.cppZZAISwitchOnCoordSetSwZ/home/slovin/Projects/indi/src/orionatlas.cpp[\•*ISwitchVectorPropertyPortZ/home/slovin/Projects/indi/src/orionatlas.cppIIš&ITextVectorProperty PortTZ/home/slovin/Projects/indi/src/orionatlas.cppH H5 IText PowerSZ/home/slovin/Projects/indi/src/orionatlas.cppFFŠISwitchPowerSwZ/home/slovin/Projects/indi/src/orionatlas.cppGG³*ISwitchVectorPropertyUpdateSZ/home/slovin/Projects/indi/src/orionatlas.cpp]][ISwitchUpdateSwZ/home/slovin/Projects/indi/src/orionatlas.cppbbµ*ISwitchVectorPropertyaaZ/home/slovin/Projects/indi/src/orionatlas.cppQSfINumber aaNumZ/home/slovin/Projects/indi/src/orionatlas.cppWX†*INumberVectorPropertyeqZ/home/slovin/Projects/indi/src/orionatlas.cppMOcINumber eqNumZ/home/slovin/Projects/indi/src/orionatlas.cppTU‡*INumberVectorPropertygeoZ/home/slovin/Projects/indi/src/orionatlas.cpplnLINumber geoNumZ/home/slovin/Projects/indi/src/orionatlas.cppop}*INumberVectorPropertystepNumZ/home/slovin/Projects/indi/src/orionatlas.cppqrt*INumberVectorProperty stepsZ/home/slovin/Projects/indi/src/orionatlas.cppfjEINumbertelescopeZ/home/slovin/Projects/indi/src/orionatlas.cpp( (OrionAtlas*V/home/slovin/Projects/indi/src/orionatlas.hÿÿÿÿOrionAtlasV/home/slovin/Projects/indi/src/orionatlas.hMCheckConnectTelV/home/slovin/Projects/indi/src/orionatlas.h88OrionAtlasÿÿÿÿÿÿÿÿvoidÿÿÿÿintConnectTelV/home/slovin/Projects/indi/src/orionatlas.h99OrionAtlasportÿÿÿÿ char*ÿÿÿÿintDisconnectTelV/home/slovin/Projects/indi/src/orionatlas.h::OrionAtlas (d€ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidGetCoordsV/home/slovin/Projects/indi/src/orionatlas.h;;+OrionAtlas SystemÿÿÿÿintÿÿÿÿintISGetPropertiesV/home/slovin/Projects/indi/src/orionatlas.h%%/OrionAtlasddevÿÿÿÿconst char*ÿÿÿÿvoidISNewNumberV/home/slovin/Projects/indi/src/orionatlas.h&&dOrionAtlasdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchV/home/slovin/Projects/indi/src/orionatlas.h((dOrionAtlas devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextV/home/slovin/Projects/indi/src/orionatlas.h''`OrionAtlasµVÆdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollV/home/slovin/Projects/indi/src/orionatlas.h))OrionAtlasvoidMoveScopeV/home/slovin/Projects/indi/src/orionatlas.h==9OrionAtlas Systemÿÿÿÿintÿÿÿÿ Coord1ÿÿÿÿ doubleÿÿÿÿ Coord2ÿÿÿÿ doubleÿÿÿÿintOrionAtlasV/home/slovin/Projects/indi/src/orionatlas.h"" OrionAtlas(epÿÿÿÿUpdateCoordsV/home/slovin/Projects/indi/src/orionatlas.h<</OrionAtlas·UÇ SystemÿÿÿÿintÿÿÿÿvoidcheckPowerV/home/slovin/Projects/indi/src/orionatlas.h,,*OrionAtlas ®npÿÿÿÿ,INumberVectorProperty*ÿÿÿÿintcheckPowerV/home/slovin/Projects/indi/src/orionatlas.h--*OrionAtlasspÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿintcheckPowerV/home/slovin/Projects/indi/src/orionatlas.h..(OrionAtlas Ntpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿintgetBasicDataV/home/slovin/Projects/indi/src/orionatlas.h**OrionAtlas·UÇvoidlogV/home/slovin/Projects/indi/src/orionatlas.h00OrionAtlasfmtÿÿÿÿconst char*ÿÿÿÿvoidpowerTelescopeV/home/slovin/Projects/indi/src/orionatlas.h//OrionAtlas void readnV/home/slovin/Projects/indi/src/orionatlas.hHH<OrionAtlasfdÿÿÿÿintÿÿÿÿptrÿÿÿÿunsigned char*ÿÿÿÿ nbytesÿÿÿÿintÿÿÿÿsecÿÿÿÿintÿÿÿÿinttelstatV/home/slovin/Projects/indi/src/orionatlas.hJJ&OrionAtlas 3€fdÿÿÿÿintÿÿÿÿsecÿÿÿÿintÿÿÿÿusecÿÿÿÿintÿÿÿÿint writenV/home/slovin/Projects/indi/src/orionatlas.hII4OrionAtlasæ~fdÿÿÿÿintÿÿÿÿptrÿÿÿÿunsigned char*ÿÿÿÿ nbytesÿÿÿÿintÿÿÿÿint~ OrionAtlasV/home/slovin/Projects/indi/src/orionatlas.h##OrionAtlasÿÿÿÿ~ OrionAtlasV/home/slovin/Projects/indi/src/orionatlas.h##OrionAtlasÿÿÿÿTelConnectFlagV/home/slovin/Projects/indi/src/orionatlas.h@@intTelPortFDV/home/slovin/Projects/indi/src/orionatlas.h??intUpdatingV/home/slovin/Projects/indi/src/orionatlas.hLLboolreturnAltV/home/slovin/Projects/indi/src/orionatlas.hE E doublereturnAzV/home/slovin/Projects/indi/src/orionatlas.hD D doublereturnDecV/home/slovin/Projects/indi/src/orionatlas.hC C doublereturnRAV/home/slovin/Projects/indi/src/orionatlas.hB B doubletimeFormatV/home/slovin/Projects/indi/src/orionatlas.h66int telfdsV/home/slovin/Projects/indi/src/orionatlas.h fd_setT/home/slovin/Projects/indi/src/robofocus.cÿÿÿÿ ISInitT/home/slovin/Projects/indi/src/robofocus.cO Oã:ˆvoid ISPollT/home/slovin/Projects/indi/src/robofocus.cPPpÿÿÿÿ void*ÿÿÿÿvoid connectRobofocusT/home/slovin/Projects/indi/src/robofocus.cMMÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidhandleErrorT/home/slovin/Projects/indi/src/robofocus.c]]F -£svpÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoid updateRFBacklashT/home/slovin/Projects/indi/src/robofocus.cSS+fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint updateRFFirmwareT/home/slovin/Projects/indi/src/robofocus.cTT* @h€fdÿÿÿÿintÿÿÿÿ rf_cmdÿÿÿÿ char*ÿÿÿÿint&updateRFMaxPositionT/home/slovin/Projects/indi/src/robofocus.cZZ. *€fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint*updateRFMotorSettingsT/home/slovin/Projects/indi/src/robofocus.cUUM zfdÿÿÿÿintÿÿÿÿdutyÿÿÿÿdouble*ÿÿÿÿ delayÿÿÿÿdouble*ÿÿÿÿ ticksÿÿÿÿdouble*ÿÿÿÿint updateRFPositionT/home/slovin/Projects/indi/src/robofocus.cQQ+nfdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint0updateRFPositionAbsoluteT/home/slovin/Projects/indi/src/robofocus.cXX3 &€fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint<updateRFPositionRelativeInwardT/home/slovin/Projects/indi/src/robofocus.cVV9 ("€fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint>updateRFPositionRelativeOutwardT/home/slovin/Projects/indi/src/robofocus.cWW: &fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint*updateRFPowerSwitchesT/home/slovin/Projects/indi/src/robofocus.cYYl €fdÿÿÿÿintÿÿÿÿsÿÿÿÿintÿÿÿÿiÿÿÿÿintÿÿÿÿcur_s1LLÿÿÿÿint*ÿÿÿÿcur_s2LRÿÿÿÿint*ÿÿÿÿcur_s3RLÿÿÿÿint*ÿÿÿÿcur_s4RRÿÿÿÿint*ÿÿÿÿint&updateRFSetPositionT/home/slovin/Projects/indi/src/robofocus.c[[.ã2€fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint&updateRFTemperatureT/home/slovin/Projects/indi/src/robofocus.cRR.fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint ISGetPropertiesT/home/slovin/Projects/indi/src/robofocus.c3OµVÆdevÿÿÿÿconst char*ÿÿÿÿvoid ISInitT/home/slovin/Projects/indi/src/robofocus.c’©·UÇvoidISNewBLOBT/home/slovin/Projects/indi/src/robofocus.c¿¿wdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿsizes[]ÿÿÿÿintÿÿÿÿblobs[]ÿÿÿÿ char*ÿÿÿÿformats[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewNumberT/home/slovin/Projects/indi/src/robofocus.cÿ½devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchT/home/slovin/Projects/indi/src/robofocus.cZÐ ( €devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextT/home/slovin/Projects/indi/src/robofocus.cÝódevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollT/home/slovin/Projects/indi/src/robofocus.c¬(·UÇpÿÿÿÿ void*ÿÿÿÿvoid connectRobofocusT/home/slovin/Projects/indi/src/robofocus.cÅúÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidhandleErrorT/home/slovin/Projects/indi/src/robofocus.c*. €svpÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿerrÿÿÿÿintÿÿÿÿmsgÿÿÿÿconst char*ÿÿÿÿvoidAbsMovementNT/home/slovin/Projects/indi/src/robofocus.c}€INumberAbsMovementNPT/home/slovin/Projects/indi/src/robofocus.c‚Ž*INumberVectorPropertyDirectionST/home/slovin/Projects/indi/src/robofocus.cÐÕISwitchDirectionSPT/home/slovin/Projects/indi/src/robofocus.c×å*ISwitchVectorPropertyMinMaxPositionNT/home/slovin/Projects/indi/src/robofocus.cêîINumber MinMaxPositionNPT/home/slovin/Projects/indi/src/robofocus.cðü*INumberVectorProperty PortTT/home/slovin/Projects/indi/src/robofocus.cz z4 IText PortTPT/home/slovin/Projects/indi/src/robofocus.c|ˆ&ITextVectorPropertyPositionNT/home/slovin/Projects/indi/src/robofocus.cSVINumberPositionNPT/home/slovin/Projects/indi/src/robofocus.cXd*INumberVectorProperty PowerST/home/slovin/Projects/indi/src/robofocus.cehISwitchPowerSPT/home/slovin/Projects/indi/src/robofocus.cjv*ISwitchVectorPropertyPowerSwitchesST/home/slovin/Projects/indi/src/robofocus.c·½ISwitchPowerSwitchesSPT/home/slovin/Projects/indi/src/robofocus.c¿Ì*ISwitchVectorPropertyRelMovementNT/home/slovin/Projects/indi/src/robofocus.cgkINumberRelMovementNPT/home/slovin/Projects/indi/src/robofocus.cmz*INumberVectorPropertySetBacklashNT/home/slovin/Projects/indi/src/robofocus.cINumberSetBacklashNPT/home/slovin/Projects/indi/src/robofocus.c%*INumberVectorProperty(SetRegisterPositionNT/home/slovin/Projects/indi/src/robofocus.cÿINumber*SetRegisterPositionNPT/home/slovin/Projects/indi/src/robofocus.c*INumberVectorPropertySettingsNT/home/slovin/Projects/indi/src/robofocus.c¡¦INumberSettingsNPT/home/slovin/Projects/indi/src/robofocus.c¨´*INumberVectorProperty SpeedNT/home/slovin/Projects/indi/src/robofocus.c(+INumberSpeedNPT/home/slovin/Projects/indi/src/robofocus.c-9*INumberVectorPropertyTemperatureNT/home/slovin/Projects/indi/src/robofocus.cŒINumberTemperatureNPT/home/slovin/Projects/indi/src/robofocus.c‘*INumberVectorProperty TimerNT/home/slovin/Projects/indi/src/robofocus.c=@INumberTimerNPT/home/slovin/Projects/indi/src/robofocus.cBO*INumberVectorPropertyfdT/home/slovin/Projects/indi/src/robofocus.cHHint`/home/slovin/Projects/indi/src/robofocusdriver.cÿÿÿÿ  calsum`/home/slovin/Projects/indi/src/robofocusdriver.c))#n rf_cmdÿÿÿÿ char*ÿÿÿÿunsigned char chksum`/home/slovin/Projects/indi/src/robofocusdriver.c**" rf_cmdÿÿÿÿ char*ÿÿÿÿunsigned charportRFRead`/home/slovin/Projects/indi/src/robofocusdriver.c44:gfdÿÿÿÿintÿÿÿÿbufÿÿÿÿ char*ÿÿÿÿ nbytesÿÿÿÿintÿÿÿÿtimeoutÿÿÿÿintÿÿÿÿint updateRFBacklash`/home/slovin/Projects/indi/src/robofocusdriver.c00+·UÇfdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint updateRFFirmware`/home/slovin/Projects/indi/src/robofocusdriver.c,,* 5ufdÿÿÿÿintÿÿÿÿ rf_cmdÿÿÿÿ char*ÿÿÿÿint&updateRFMaxPosition`/home/slovin/Projects/indi/src/robofocusdriver.c22.fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint*updateRFMotorSettings`/home/slovin/Projects/indi/src/robofocusdriver.c--M %Ѐfdÿÿÿÿintÿÿÿÿdutyÿÿÿÿdouble*ÿÿÿÿ delayÿÿÿÿdouble*ÿÿÿÿ ticksÿÿÿÿdouble*ÿÿÿÿint updateRFPosition`/home/slovin/Projects/indi/src/robofocusdriver.c+++fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint0updateRFPositionAbsolute`/home/slovin/Projects/indi/src/robofocusdriver.c//3 fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint<updateRFPositionRelativeInward`/home/slovin/Projects/indi/src/robofocusdriver.c..9fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint*updateRFPowerSwitches`/home/slovin/Projects/indi/src/robofocusdriver.c11lµVÆfdÿÿÿÿintÿÿÿÿsÿÿÿÿintÿÿÿÿiÿÿÿÿintÿÿÿÿcur_s1LLÿÿÿÿint*ÿÿÿÿcur_s2LRÿÿÿÿint*ÿÿÿÿcur_s3RLÿÿÿÿint*ÿÿÿÿcur_s4RRÿÿÿÿint*ÿÿÿÿint&updateRFSetPosition`/home/slovin/Projects/indi/src/robofocusdriver.c33.fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint calsum`/home/slovin/Projects/indi/src/robofocusdriver.c}ˆ rf_cmdÿÿÿÿ char*ÿÿÿÿunsigned char chksum`/home/slovin/Projects/indi/src/robofocusdriver.c‹Ÿ rf_cmdÿÿÿÿ char*ÿÿÿÿunsigned char commRF`/home/slovin/Projects/indi/src/robofocusdriver.c¦Í i€fdÿÿÿÿintÿÿÿÿ rf_cmdÿÿÿÿ char*ÿÿÿÿintportRFRead`/home/slovin/Projects/indi/src/robofocusdriver.c<d /€fdÿÿÿÿintÿÿÿÿbufÿÿÿÿ char*ÿÿÿÿ nbytesÿÿÿÿintÿÿÿÿtimeoutÿÿÿÿintÿÿÿÿintportRFWrite`/home/slovin/Projects/indi/src/robofocusdriver.cgzfdÿÿÿÿintÿÿÿÿbufÿÿÿÿconst char*ÿÿÿÿint updateRFBacklash`/home/slovin/Projects/indi/src/robofocusdriver.cü3rfdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint updateRFFirmware`/home/slovin/Projects/indi/src/robofocusdriver.c5?fdÿÿÿÿintÿÿÿÿ rf_cmdÿÿÿÿ char*ÿÿÿÿint&updateRFMaxPosition`/home/slovin/Projects/indi/src/robofocusdriver.c ?fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint*updateRFMotorSettings`/home/slovin/Projects/indi/src/robofocusdriver.cAafdÿÿÿÿintÿÿÿÿdutyÿÿÿÿdouble*ÿÿÿÿ delayÿÿÿÿdouble*ÿÿÿÿ ticksÿÿÿÿdouble*ÿÿÿÿint updateRFPosition`/home/slovin/Projects/indi/src/robofocusdriver.cÐåfdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint0updateRFPositionAbsolute`/home/slovin/Projects/indi/src/robofocusdriver.c¥Çfdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint<updateRFPositionRelativeInward`/home/slovin/Projects/indi/src/robofocusdriver.cc‚efdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint>updateRFPositionRelativeOutward`/home/slovin/Projects/indi/src/robofocusdriver.c…£fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint*updateRFPowerSwitches`/home/slovin/Projects/indi/src/robofocusdriver.cÈcfdÿÿÿÿintÿÿÿÿsÿÿÿÿintÿÿÿÿ new_snÿÿÿÿintÿÿÿÿcur_s1LLÿÿÿÿint*ÿÿÿÿcur_s2LRÿÿÿÿint*ÿÿÿÿcur_s3RLÿÿÿÿint*ÿÿÿÿcur_s4RRÿÿÿÿint*ÿÿÿÿint&updateRFSetPosition`/home/slovin/Projects/indi/src/robofocusdriver.cAlfdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint&updateRFTemperature`/home/slovin/Projects/indi/src/robofocusdriver.cèú Gc€fdÿÿÿÿintÿÿÿÿ valueÿÿÿÿdouble*ÿÿÿÿint`/home/slovin/Projects/indi/src/robofocusdriver.hÿÿÿÿZ/home/slovin/Projects/indi/src/sbig_dummy.cppÿÿÿÿ$SBIGUnivDrvCommandZ/home/slovin/Projects/indi/src/sbig_dummy.cpp commandÿÿÿÿ shortÿÿÿÿ Paramsÿÿÿÿ void*ÿÿÿÿResultsÿÿÿÿ void*ÿÿÿÿ shortP/home/slovin/Projects/indi/src/sbigcam.hÿÿÿÿSbigCamP/home/slovin/Projects/indi/src/sbigcam.hz|oActivateRelayP/home/slovin/Projects/indi/src/sbigcam.h -SbigCam ÿÿÿÿÿÿÿÿ(ActivateRelayParams*ÿÿÿÿintAllocateBufferP/home/slovin/Projects/indi/src/sbigcam.h[[NSbigCam  widthÿÿÿÿunsigned shortÿÿÿÿ heightÿÿÿÿunsigned shortÿÿÿÿ unsigned short**AoDelayP/home/slovin/Projects/indi/src/sbigcam.h !SbigCamoÿÿÿÿÿÿÿÿAODelayParams*ÿÿÿÿintAoSetFocusP/home/slovin/Projects/indi/src/sbigcam.h 'SbigCam*ÿÿÿÿÿÿÿÿ"AOSetFocusParams*ÿÿÿÿintAoTipTiltP/home/slovin/Projects/indi/src/sbigcam.h %SbigCamdÿÿÿÿÿÿÿÿ AOTipTiltParams*ÿÿÿÿintBcdPixel2doubleP/home/slovin/Projects/indi/src/sbigcam.h{ {&SbigCamabcdÿÿÿÿ ulongÿÿÿÿ double BitIoP/home/slovin/Projects/indi/src/sbigcam.h, ,-SbigCamcÿÿÿÿÿÿÿÿBitIOParams*ÿÿÿÿÿÿÿÿÿÿÿÿBitIOResults*ÿÿÿÿintCalcSetpointP/home/slovin/Projects/indi/src/sbigcam.hyy1SbigCamotemperatureÿÿÿÿ doubleÿÿÿÿunsigned shortCalcTemperatureP/home/slovin/Projects/indi/src/sbigcam.hz zCSbigCamhthermistorTypeÿÿÿÿ shortÿÿÿÿccdSetpointÿÿÿÿ shortÿÿÿÿ doubleCfwP/home/slovin/Projects/indi/src/sbigcam.h (SbigCamAÿÿÿÿÿÿÿÿCFWParams*ÿÿÿÿÿÿÿÿÿÿÿÿCFWResults*ÿÿÿÿintCfwCloseDeviceP/home/slovin/Projects/indi/src/sbigcam.hR R%SbigCam ÿÿÿÿÿÿÿÿCFWResults*ÿÿÿÿintCfwConnectP/home/slovin/Projects/indi/src/sbigcam.hOOSbigCampintCfwDisconnectP/home/slovin/Projects/indi/src/sbigcam.hPPSbigCameintCfwGetInfoP/home/slovin/Projects/indi/src/sbigcam.hT T!SbigCam/ÿÿÿÿÿÿÿÿCFWResults*ÿÿÿÿintCfwGotoP/home/slovin/Projects/indi/src/sbigcam.hVVSbigCamEÿÿÿÿÿÿÿÿCFWResults*ÿÿÿÿintCfwGotoMonitorP/home/slovin/Projects/indi/src/sbigcam.hWW$SbigCamnÿÿÿÿÿÿÿÿCFWResults*ÿÿÿÿintCfwInitP/home/slovin/Projects/indi/src/sbigcam.hS SSbigCamnÿÿÿÿÿÿÿÿCFWResults*ÿÿÿÿintCfwOpenDeviceP/home/slovin/Projects/indi/src/sbigcam.hQ Q$SbigCamIÿÿÿÿÿÿÿÿCFWResults*ÿÿÿÿintCfwQueryP/home/slovin/Projects/indi/src/sbigcam.hU USbigCam_ÿÿÿÿÿÿÿÿCFWResults*ÿÿÿÿintCfwShowResultsP/home/slovin/Projects/indi/src/sbigcam.hX X0SbigCam nameÿÿÿÿ stringÿÿÿÿÿÿÿÿÿÿÿÿCFWResultsÿÿÿÿvoid&CfwUpdatePropertiesP/home/slovin/Projects/indi/src/sbigcam.hYY'SbigCam*ÿÿÿÿÿÿÿÿCFWResultsÿÿÿÿvoidCheckConnectionP/home/slovin/Projects/indi/src/sbigcam.hH H3SbigCam spÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿboolCheckConnectionP/home/slovin/Projects/indi/src/sbigcam.hI I3SbigCamtnpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿboolCheckConnectionP/home/slovin/Projects/indi/src/sbigcam.hJ J1SbigCam tpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿboolCheckLinkP/home/slovin/Projects/indi/src/sbigcam.h2 2SbigCamlboolCloseDeviceP/home/slovin/Projects/indi/src/sbigcam.hþ þSbigCamsintCloseDriverP/home/slovin/Projects/indi/src/sbigcam.hx xSbigCamiint CreateFitsHeaderP/home/slovin/Projects/indi/src/sbigcam.hggPSbigCamrfptrÿÿÿÿfitsfile*ÿÿÿÿ widthÿÿÿÿunsigned intÿÿÿÿ heightÿÿÿÿunsigned intÿÿÿÿvoidCreateFitsNameP/home/slovin/Projects/indi/src/sbigcam.h` `SbigCamc stringDumpLinesP/home/slovin/Projects/indi/src/sbigcam.h  %SbigCamtÿÿÿÿÿÿÿÿ DumpLinesParams*ÿÿÿÿintEndExposureP/home/slovin/Projects/indi/src/sbigcam.h )SbigCamhÿÿÿÿÿÿÿÿ$EndExposureParams*ÿÿÿÿintEndReadoutP/home/slovin/Projects/indi/src/sbigcam.h  'SbigCameÿÿÿÿÿÿÿÿ"EndReadoutParams*ÿÿÿÿintEstablishLinkP/home/slovin/Projects/indi/src/sbigcam.h SbigCamHintGetCameraIDP/home/slovin/Projects/indi/src/sbigcam.h4 4SbigCamo stringGetCameraNameP/home/slovin/Projects/indi/src/sbigcam.h3 3SbigCams stringGetCameraTypeP/home/slovin/Projects/indi/src/sbigcam.héé<SbigCam CAMERA_TYPEGetCcdInfoP/home/slovin/Projects/indi/src/sbigcam.h /SbigCamtÿÿÿÿÿÿÿÿ"GetCCDInfoParams*ÿÿÿÿÿÿÿÿÿÿÿÿ void*ÿÿÿÿint"GetCcdShutterModeP/home/slovin/Projects/indi/src/sbigcam.hN N9SbigCamMshutterÿÿÿÿint&ÿÿÿÿccd_requestÿÿÿÿintÿÿÿÿintGetCcdSizeInfoP/home/slovin/Projects/indi/src/sbigcam.h56*SbigCam ccdÿÿÿÿintÿÿÿÿrmÿÿÿÿintÿÿÿÿfrmWÿÿÿÿint&ÿÿÿÿfrmHÿÿÿÿint&ÿÿÿÿpixWÿÿÿÿdouble&ÿÿÿÿpixHÿÿÿÿdouble&ÿÿÿÿint8GetCcdTemperaturePoolingTimeP/home/slovin/Projects/indi/src/sbigcam.hC C'SbigCamointGetCfwSelTypeP/home/slovin/Projects/indi/src/sbigcam.hüüSbigCamtintGetDeviceNameP/home/slovin/Projects/indi/src/sbigcam.hòò3SbigCamc char* GetDriverControlP/home/slovin/Projects/indi/src/sbigcam.h' ((SbigCamaÿÿÿÿÿÿÿÿ.GetDriverControlParams*ÿÿÿÿÿÿÿÿÿÿÿÿ0GetDriverControlResults*ÿÿÿÿintGetDriverHandleP/home/slovin/Projects/indi/src/sbigcam.hìì7SbigCam intGetDriverHandleP/home/slovin/Projects/indi/src/sbigcam.h 2SbigCam ÿÿÿÿÿÿÿÿ.GetDriverHandleResults*ÿÿÿÿintGetDriverInfoP/home/slovin/Projects/indi/src/sbigcam.hÿ ÿ5SbigCamoÿÿÿÿÿÿÿÿ(GetDriverInfoParams*ÿÿÿÿÿÿÿÿÿÿÿÿ void*ÿÿÿÿintGetErrorStringP/home/slovin/Projects/indi/src/sbigcam.h% %"SbigCamaerrÿÿÿÿintÿÿÿÿ stringGetExposeTimeP/home/slovin/Projects/indi/src/sbigcam.hnn;SbigCamF double"GetFileDescriptorP/home/slovin/Projects/indi/src/sbigcam.håå1SbigCamaint"GetLastExposeTimeP/home/slovin/Projects/indi/src/sbigcam.hoo@SbigCamL double$GetLastTemperatureP/home/slovin/Projects/indi/src/sbigcam.hqq@SbigCams doubleGetLinkStatusP/home/slovin/Projects/indi/src/sbigcam.hïï6SbigCam boolGetLinkStatusP/home/slovin/Projects/indi/src/sbigcam.h$ $.SbigCamtÿÿÿÿÿÿÿÿ*GetLinkStatusResults*ÿÿÿÿint GetNumOfCcdChipsP/home/slovin/Projects/indi/src/sbigcam.h77SbigCamKint2GetSelectedCcdBinningModeP/home/slovin/Projects/indi/src/sbigcam.hL L0SbigCamPbinningÿÿÿÿint&ÿÿÿÿint$GetSelectedCcdChipP/home/slovin/Projects/indi/src/sbigcam.hK K-SbigCam ccd_requestÿÿÿÿint&ÿÿÿÿint.GetSelectedCcdFrameTypeP/home/slovin/Projects/indi/src/sbigcam.hMM3SbigCam frame_typeÿÿÿÿstring&ÿÿÿÿintGetSerialStatusP/home/slovin/Projects/indi/src/sbigcam.h 2SbigCamtÿÿÿÿÿÿÿÿ.GetSerialStatusResults*ÿÿÿÿint2GetStartExposureTimestampP/home/slovin/Projects/indi/src/sbigcam.hõõOSbigCamh stringISGetPropertiesP/home/slovin/Projects/indi/src/sbigcam.h; ;SbigCamSvoidISNewNumberP/home/slovin/Projects/indi/src/sbigcam.h@ ASbigCam]nameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnumÿÿÿÿintÿÿÿÿvoidISNewSwitchP/home/slovin/Projects/indi/src/sbigcam.h< =SbigCam nameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnumÿÿÿÿintÿÿÿÿvoidISNewTextP/home/slovin/Projects/indi/src/sbigcam.h> ?SbigCamanameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnumÿÿÿÿintÿÿÿÿvoidInitVarsP/home/slovin/Projects/indi/src/sbigcam.hv vSbigCam voidIsDeviceOpenP/home/slovin/Projects/indi/src/sbigcam.hççCSbigCam bool*IsFanControlAvailableP/home/slovin/Projects/indi/src/sbigcam.h88SbigCam/bool(MiscellaneousControlP/home/slovin/Projects/indi/src/sbigcam.h" ";SbigCamtÿÿÿÿÿÿÿÿ6MiscellaneousControlParams*ÿÿÿÿintOpenDeviceP/home/slovin/Projects/indi/src/sbigcam.hý ý&SbigCamsnameÿÿÿÿconst char*ÿÿÿÿintOpenDriverP/home/slovin/Projects/indi/src/sbigcam.hw wSbigCameintPulseOutP/home/slovin/Projects/indi/src/sbigcam.h #SbigCamlÿÿÿÿÿÿÿÿPulseOutParams*ÿÿÿÿint$QueryCommandStatusP/home/slovin/Projects/indi/src/sbigcam.h !,SbigCam ÿÿÿÿÿÿÿÿ2QueryCommandStatusParams*ÿÿÿÿÿÿÿÿÿÿÿÿ4QueryCommandStatusResults*ÿÿÿÿint,QueryTemperatureStatusP/home/slovin/Projects/indi/src/sbigcam.h @SbigCamdÿÿÿÿÿÿÿÿ<QueryTemperatureStatusResults*ÿÿÿÿint,QueryTemperatureStatusP/home/slovin/Projects/indi/src/sbigcam.h ASbigCamuenabledÿÿÿÿ bool&ÿÿÿÿccdTempÿÿÿÿdouble&ÿÿÿÿsetpointTÿÿÿÿdouble&ÿÿÿÿ powerÿÿÿÿdouble&ÿÿÿÿintQueryUsbP/home/slovin/Projects/indi/src/sbigcam.h* *$SbigCam,ÿÿÿÿÿÿÿÿ QueryUSBResults*ÿÿÿÿintReadOffsetP/home/slovin/Projects/indi/src/sbigcam.h# #<SbigCam ÿÿÿÿÿÿÿÿ"ReadOffsetParams*ÿÿÿÿÿÿÿÿÿÿÿÿ$ReadOffsetResults*ÿÿÿÿintReadoutCcdP/home/slovin/Projects/indi/src/sbigcam.h] _$SbigCamrleftÿÿÿÿunsigned shortÿÿÿÿtopÿÿÿÿunsigned shortÿÿÿÿ widthÿÿÿÿunsigned shortÿÿÿÿ heightÿÿÿÿunsigned shortÿÿÿÿ bufferÿÿÿÿ unsigned short**ÿÿÿÿintReadoutLineP/home/slovin/Projects/indi/src/sbigcam.h SbigCamoÿÿÿÿÿÿÿÿ$ReadoutLineParams*ÿÿÿÿresultsÿÿÿÿunsigned short*ÿÿÿÿsubtractÿÿÿÿboolÿÿÿÿintReleaseBufferP/home/slovin/Projects/indi/src/sbigcam.h\\ESbigCam  heightÿÿÿÿunsigned shortÿÿÿÿ bufferÿÿÿÿ unsigned short**ÿÿÿÿintRwUsbI2cP/home/slovin/Projects/indi/src/sbigcam.h+ +#SbigCam ÿÿÿÿÿÿÿÿRWUSBI2CParams*ÿÿÿÿint$SBIGUnivDrvCommandP/home/slovin/Projects/indi/src/sbigcam.h/ /8SbigCam ÿÿÿÿÿÿÿÿPAR_COMMANDÿÿÿÿÿÿÿÿÿÿÿÿ void*ÿÿÿÿÿÿÿÿÿÿÿÿ void*ÿÿÿÿintSaveExposeTimeP/home/slovin/Projects/indi/src/sbigcam.hmmBSbigCam)valÿÿÿÿ doubleÿÿÿÿvoidSaveTemperatureP/home/slovin/Projects/indi/src/sbigcam.hppCSbigCamivalÿÿÿÿ doubleÿÿÿÿvoidSbigCamP/home/slovin/Projects/indi/src/sbigcam.hááSbigCam ÿÿÿÿSbigCamP/home/slovin/Projects/indi/src/sbigcam.hââ(SbigCamMdevice_nameÿÿÿÿconst char*ÿÿÿÿÿÿÿÿSetBlobStateP/home/slovin/Projects/indi/src/sbigcam.hZ Z$SbigCamV stateÿÿÿÿIPStateÿÿÿÿvoidSetCameraTypeP/home/slovin/Projects/indi/src/sbigcam.hêêOSbigCammvalÿÿÿÿCAMERA_TYPEÿÿÿÿvoidSetDeviceNameP/home/slovin/Projects/indi/src/sbigcam.hó ó$SbigCamtÿÿÿÿÿÿÿÿconst char*ÿÿÿÿint SetDriverControlP/home/slovin/Projects/indi/src/sbigcam.h& &3SbigCamoÿÿÿÿÿÿÿÿ.SetDriverControlParams*ÿÿÿÿintSetDriverHandleP/home/slovin/Projects/indi/src/sbigcam.hííSSbigCamdvalÿÿÿÿintÿÿÿÿvoidSetDriverHandleP/home/slovin/Projects/indi/src/sbigcam.h 1SbigCamrÿÿÿÿÿÿÿÿ,SetDriverHandleParams*ÿÿÿÿint"SetFileDescriptorP/home/slovin/Projects/indi/src/sbigcam.hææ;SbigCammvalÿÿÿÿintÿÿÿÿvoidSetLinkStatusP/home/slovin/Projects/indi/src/sbigcam.hððDSbigCammvalÿÿÿÿboolÿÿÿÿvoid2SetStartExposureTimestampP/home/slovin/Projects/indi/src/sbigcam.höù SbigCamrpÿÿÿÿconst char*ÿÿÿÿvoid0SetTemperatureRegulationP/home/slovin/Projects/indi/src/sbigcam.h  CSbigCam#ÿÿÿÿÿÿÿÿ>SetTemperatureRegulationParams*ÿÿÿÿint0SetTemperatureRegulationP/home/slovin/Projects/indi/src/sbigcam.h BSbigCamatempÿÿÿÿ doubleÿÿÿÿ enableÿÿÿÿboolÿÿÿÿintStartExposureP/home/slovin/Projects/indi/src/sbigcam.h -SbigCam ÿÿÿÿÿÿÿÿ(StartExposureParams*ÿÿÿÿintStartExposureP/home/slovin/Projects/indi/src/sbigcam.hF FSbigCam2intStartReadoutP/home/slovin/Projects/indi/src/sbigcam.h +SbigCam*ÿÿÿÿÿÿÿÿ&StartReadoutParams*ÿÿÿÿintStopExposureP/home/slovin/Projects/indi/src/sbigcam.hG GSbigCam intTxSerialBytesP/home/slovin/Projects/indi/src/sbigcam.h ESbigCamtÿÿÿÿÿÿÿÿ(TXSerialBytesParams*ÿÿÿÿÿÿÿÿÿÿÿÿ*TXSerialBytesResults*ÿÿÿÿint0UpdateCcdFramePropertiesP/home/slovin/Projects/indi/src/sbigcam.hB B=SbigCam bUpdateClientÿÿÿÿboolÿÿÿÿint&UpdateCfwPropertiesP/home/slovin/Projects/indi/src/sbigcam.hE ESbigCam intUpdateExposureP/home/slovin/Projects/indi/src/sbigcam.hjjSbigCam voidUpdateExposureP/home/slovin/Projects/indi/src/sbigcam.hll$SbigCam ÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoid UpdatePropertiesP/home/slovin/Projects/indi/src/sbigcam.hD DSbigCam;int"UpdateTemperatureP/home/slovin/Projects/indi/src/sbigcam.hiiSbigCamBvoid"UpdateTemperatureP/home/slovin/Projects/indi/src/sbigcam.hkk'SbigCamsÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoidUploadFitsP/home/slovin/Projects/indi/src/sbigcam.hhh"SbigCam_file_nameÿÿÿÿ stringÿÿÿÿintUsbAdControlP/home/slovin/Projects/indi/src/sbigcam.h) )+SbigCamlÿÿÿÿÿÿÿÿ&USBADControlParams*ÿÿÿÿintWriteFitsP/home/slovin/Projects/indi/src/sbigcam.ha b:SbigCamrfits_nameÿÿÿÿ stringÿÿÿÿ widthÿÿÿÿunsigned shortÿÿÿÿ heightÿÿÿÿunsigned shortÿÿÿÿ bufferÿÿÿÿ unsigned short**ÿÿÿÿint~ SbigCamP/home/slovin/Projects/indi/src/sbigcam.hã ãSbigCam ÿÿÿÿGetCameraTypeP/home/slovin/Projects/indi/src/sbigcam.héé<SbigCam CAMERA_TYPEGetDeviceNameP/home/slovin/Projects/indi/src/sbigcam.hòò3SbigCamc char*GetDriverHandleP/home/slovin/Projects/indi/src/sbigcam.hìì7SbigCam intGetExposeTimeP/home/slovin/Projects/indi/src/sbigcam.hnn;SbigCamF double"GetFileDescriptorP/home/slovin/Projects/indi/src/sbigcam.håå1SbigCamaint"GetLastExposeTimeP/home/slovin/Projects/indi/src/sbigcam.hoo@SbigCamL double$GetLastTemperatureP/home/slovin/Projects/indi/src/sbigcam.hqq@SbigCams doubleGetLinkStatusP/home/slovin/Projects/indi/src/sbigcam.hïï6SbigCam bool2GetStartExposureTimestampP/home/slovin/Projects/indi/src/sbigcam.hõõOSbigCamh stringIsDeviceOpenP/home/slovin/Projects/indi/src/sbigcam.hççCSbigCam boolSaveExposeTimeP/home/slovin/Projects/indi/src/sbigcam.hmmBSbigCam)valÿÿÿÿ doubleÿÿÿÿvoidSaveTemperatureP/home/slovin/Projects/indi/src/sbigcam.hppCSbigCamivalÿÿÿÿ doubleÿÿÿÿvoidSetCameraTypeP/home/slovin/Projects/indi/src/sbigcam.hêêOSbigCammvalÿÿÿÿCAMERA_TYPEÿÿÿÿvoidSetDriverHandleP/home/slovin/Projects/indi/src/sbigcam.hííSSbigCamdvalÿÿÿÿintÿÿÿÿvoid"SetFileDescriptorP/home/slovin/Projects/indi/src/sbigcam.hææ;SbigCammvalÿÿÿÿintÿÿÿÿvoidSetLinkStatusP/home/slovin/Projects/indi/src/sbigcam.hððDSbigCammvalÿÿÿÿboolÿÿÿÿvoid2SetStartExposureTimestampP/home/slovin/Projects/indi/src/sbigcam.höù SbigCamrpÿÿÿÿconst char*ÿÿÿÿvoid2m_camera_typeP/home/slovin/Projects/indi/src/sbigcam.h~~CAMERA_TYPEm_dev_nameP/home/slovin/Projects/indi/src/sbigcam.h  charm_drv_handleP/home/slovin/Projects/indi/src/sbigcam.h intm_fdP/home/slovin/Projects/indi/src/sbigcam.h} }int*m_icam_binning_mode_sP/home/slovin/Projects/indi/src/sbigcam.h¬¬(ISwitch,m_icam_binning_mode_spP/home/slovin/Projects/indi/src/sbigcam.h­­-*ISwitchVectorProperty$m_icam_ccd_frame_nP/home/slovin/Projects/indi/src/sbigcam.h··&INumber&m_icam_ccd_frame_npP/home/slovin/Projects/indi/src/sbigcam.h¸¸**INumberVectorProperty"m_icam_ccd_info_nP/home/slovin/Projects/indi/src/sbigcam.h°°%INumber$m_icam_ccd_info_npP/home/slovin/Projects/indi/src/sbigcam.h±±)*INumberVectorProperty(m_icam_ccd_request_sP/home/slovin/Projects/indi/src/sbigcam.h¥¥'ISwitch*m_icam_ccd_request_spP/home/slovin/Projects/indi/src/sbigcam.h¦¦,*ISwitchVectorProperty&m_icam_connection_sP/home/slovin/Projects/indi/src/sbigcam.h'ISwitch(m_icam_connection_spP/home/slovin/Projects/indi/src/sbigcam.hŽŽ+*ISwitchVectorPropertym_icam_cooler_nP/home/slovin/Projects/indi/src/sbigcam.h˜˜"INumber m_icam_cooler_npP/home/slovin/Projects/indi/src/sbigcam.h™™'*INumberVectorProperty(m_icam_device_port_tP/home/slovin/Projects/indi/src/sbigcam.hŠŠ& IText*m_icam_device_port_tpP/home/slovin/Projects/indi/src/sbigcam.h‹‹+&ITextVectorProperty$m_icam_expose_timeP/home/slovin/Projects/indi/src/sbigcam.hÔÔ" double(m_icam_expose_time_nP/home/slovin/Projects/indi/src/sbigcam.hÒÒ)INumber*m_icam_expose_time_npP/home/slovin/Projects/indi/src/sbigcam.hÓÓ,*INumberVectorProperty$m_icam_fan_state_sP/home/slovin/Projects/indi/src/sbigcam.h‘‘%ISwitch&m_icam_fan_state_spP/home/slovin/Projects/indi/src/sbigcam.h’’**ISwitchVectorPropertym_icam_fits_bP/home/slovin/Projects/indi/src/sbigcam.h×× IBLOBm_icam_fits_bpP/home/slovin/Projects/indi/src/sbigcam.hØØ%&IBLOBVectorProperty$m_icam_fits_name_tP/home/slovin/Projects/indi/src/sbigcam.hÛÛ$ IText&m_icam_fits_name_tpP/home/slovin/Projects/indi/src/sbigcam.hÜÜ)&ITextVectorProperty&m_icam_frame_type_sP/home/slovin/Projects/indi/src/sbigcam.h¢¢(ISwitch(m_icam_frame_type_spP/home/slovin/Projects/indi/src/sbigcam.h££+*ISwitchVectorProperty&m_icam_pixel_size_nP/home/slovin/Projects/indi/src/sbigcam.h³³'INumber(m_icam_pixel_size_npP/home/slovin/Projects/indi/src/sbigcam.h´´+*INumberVectorProperty m_icam_product_tP/home/slovin/Projects/indi/src/sbigcam.h‡‡" IText"m_icam_product_tpP/home/slovin/Projects/indi/src/sbigcam.hˆˆ'&ITextVectorProperty$m_icam_temperatureP/home/slovin/Projects/indi/src/sbigcam.h––" double0m_icam_temperature_msg_sP/home/slovin/Projects/indi/src/sbigcam.hžž+ISwitch2m_icam_temperature_msg_spP/home/slovin/Projects/indi/src/sbigcam.hŸŸ0*ISwitchVectorProperty(m_icam_temperature_nP/home/slovin/Projects/indi/src/sbigcam.h””(INumber*m_icam_temperature_npP/home/slovin/Projects/indi/src/sbigcam.h••-*INumberVectorProperty8m_icam_temperature_polling_nP/home/slovin/Projects/indi/src/sbigcam.h››/INumber:m_icam_temperature_polling_npP/home/slovin/Projects/indi/src/sbigcam.hœœ4*INumberVectorProperty&m_icfw_connection_sP/home/slovin/Projects/indi/src/sbigcam.hËË'ISwitch(m_icfw_connection_spP/home/slovin/Projects/indi/src/sbigcam.hÌÌ+*ISwitchVectorProperty m_icfw_product_tP/home/slovin/Projects/indi/src/sbigcam.hÅÅ" IText"m_icfw_product_tpP/home/slovin/Projects/indi/src/sbigcam.hÆÆ'&ITextVectorPropertym_icfw_slot_nP/home/slovin/Projects/indi/src/sbigcam.hÎÎ INumberm_icfw_slot_npP/home/slovin/Projects/indi/src/sbigcam.hÏÏ&*INumberVectorPropertym_icfw_type_sP/home/slovin/Projects/indi/src/sbigcam.hÈÈ,ISwitchm_icfw_type_spP/home/slovin/Projects/indi/src/sbigcam.hÉÉ%*ISwitchVectorPropertym_link_statusP/home/slovin/Projects/indi/src/sbigcam.h€ €bool4m_start_exposure_timestampP/home/slovin/Projects/indi/src/sbigcam.h‚ ‚& string&CCD_BIN_1x1_IP/home/slovin/Projects/indi/src/sbigcam.hÚ Úconst intCCD_BIN_2x2_EP/home/slovin/Projects/indi/src/sbigcam.hÞ Þconst intCCD_BIN_2x2_IP/home/slovin/Projects/indi/src/sbigcam.hÛ Ûconst intCCD_BIN_3x3_EP/home/slovin/Projects/indi/src/sbigcam.hß ßconst intCCD_BIN_3x3_IP/home/slovin/Projects/indi/src/sbigcam.hÜ Üconst intCCD_BIN_9x9_IP/home/slovin/Projects/indi/src/sbigcam.hÝ Ýconst int(CCD_COOLER_THRESHOLDP/home/slovin/Projects/indi/src/sbigcam.h®®)const doubleCCD_TEMP_STEPP/home/slovin/Projects/indi/src/sbigcam.h··#const double CUR_POLLING_TIMEP/home/slovin/Projects/indi/src/sbigcam.hÃÃ&const doubleDEF_CCD_TEMPP/home/slovin/Projects/indi/src/sbigcam.h¸¸"const doubleDEF_EXP_TIMEP/home/slovin/Projects/indi/src/sbigcam.h..!const doubleDEF_FILTER_SLOTP/home/slovin/Projects/indi/src/sbigcam.hf fconst intDT_AMBIENTP/home/slovin/Projects/indi/src/sbigcam.hff(const double DT_CCDP/home/slovin/Projects/indi/src/sbigcam.hbb&const doubleEXP_TIME_STEPP/home/slovin/Projects/indi/src/sbigcam.h--"const double FILTER_SLOT_STEPP/home/slovin/Projects/indi/src/sbigcam.he e const intINDI_TIMEOUTP/home/slovin/Projects/indi/src/sbigcam.hl l"const double(INVALID_HANDLE_VALUEP/home/slovin/Projects/indi/src/sbigcam.h[ [%const int MAX_ADP/home/slovin/Projects/indi/src/sbigcam.h__(const doubleMAX_CCD_TEMPP/home/slovin/Projects/indi/src/sbigcam.h¶¶#const doubleMAX_CFW_TYPESP/home/slovin/Projects/indi/src/sbigcam.hX Xconst intMAX_EXP_TIMEP/home/slovin/Projects/indi/src/sbigcam.h,,$const doubleMAX_FILTER_SLOTP/home/slovin/Projects/indi/src/sbigcam.hd d const int MAX_POLLING_TIMEP/home/slovin/Projects/indi/src/sbigcam.hÁÁ(const doubleMIN_CCD_TEMPP/home/slovin/Projects/indi/src/sbigcam.hµµ$const doubleMIN_EXP_TIMEP/home/slovin/Projects/indi/src/sbigcam.h++!const doubleMIN_FILTER_SLOTP/home/slovin/Projects/indi/src/sbigcam.hc cconst int MIN_POLLING_TIMEP/home/slovin/Projects/indi/src/sbigcam.hÀÀ%const double POLL_EXPOSURE_MSP/home/slovin/Projects/indi/src/sbigcam.hn n#const int&POLL_TEMPERATURE_MSP/home/slovin/Projects/indi/src/sbigcam.hm m&const intR0P/home/slovin/Projects/indi/src/sbigcam.hcc#const double R_BRIDGE_AMBIENTP/home/slovin/Projects/indi/src/sbigcam.hee*const doubleR_BRIDGE_CCDP/home/slovin/Projects/indi/src/sbigcam.haa)const doubleR_RATIO_AMBIENTP/home/slovin/Projects/indi/src/sbigcam.hdd*const doubleR_RATIO_CCDP/home/slovin/Projects/indi/src/sbigcam.h``(const double"STEP_POLLING_TIMEP/home/slovin/Projects/indi/src/sbigcam.hÂÂ%const doubleT0P/home/slovin/Projects/indi/src/sbigcam.h^^"const doubleTEMP_DIFFP/home/slovin/Projects/indi/src/sbigcam.h¹¹ const double THERMISTOR_TYPEP/home/slovin/Projects/indi/src/sbigcam.hxxÿÿÿÿR/home/slovin/Projects/indi/src/sbigudrv.hÿÿÿÿ_ ABG_STATE7R/home/slovin/Projects/indi/src/sbigudrv.hÅCÅMÿÿÿÿ AD_SIZER/home/slovin/Projects/indi/src/sbigudrv.hß4ß;ÿÿÿÿ AODelayParamsR/home/slovin/Projects/indi/src/sbigudrv.hööÿÿÿÿ AOSetFocusParamsR/home/slovin/Projects/indi/src/sbigudrv.hòòÿÿÿÿ AOTipTiltParamsR/home/slovin/Projects/indi/src/sbigudrv.hîîÿÿÿÿ AO_FOCUS_COMMANDR/home/slovin/Projects/indi/src/sbigudrv.hââ!ÿÿÿÿ &ActivateRelayParamsR/home/slovin/Projects/indi/src/sbigudrv.hÿÿÿÿ BITIO_NAMER/home/slovin/Projects/indi/src/sbigudrv.húIúSÿÿÿÿ BITIO_OPERATIONR/home/slovin/Projects/indi/src/sbigudrv.hù)ù8ÿÿÿÿ BitIOParamsR/home/slovin/Projects/indi/src/sbigudrv.h’’ ÿÿÿÿ BitIOResultsR/home/slovin/Projects/indi/src/sbigudrv.h––ÿÿÿÿ CAMERA_TYPER/home/slovin/Projects/indi/src/sbigudrv.hÒVÒaÿÿÿÿ CCD_INFO_REQUESTR/home/slovin/Projects/indi/src/sbigudrv.hÍÍ/ÿÿÿÿ CCD_REQUESTR/home/slovin/Projects/indi/src/sbigudrv.hÊ=ÊHÿÿÿÿ CFWParamsR/home/slovin/Projects/indi/src/sbigudrv.hƒƒ ÿÿÿÿ CFWResultsR/home/slovin/Projects/indi/src/sbigudrv.hŒŒ ÿÿÿÿ CFW_COMMANDR/home/slovin/Projects/indi/src/sbigudrv.hð,ð7ÿÿÿÿ CFW_COM_PORTR/home/slovin/Projects/indi/src/sbigudrv.h÷J÷Vÿÿÿÿ CFW_ERRORR/home/slovin/Projects/indi/src/sbigudrv.hôôÿÿÿÿ $CFW_GETINFO_SELECTR/home/slovin/Projects/indi/src/sbigudrv.høKø]ÿÿÿÿ CFW_MODEL_SELECTR/home/slovin/Projects/indi/src/sbigudrv.hîî'ÿÿÿÿ CFW_POSITIONR/home/slovin/Projects/indi/src/sbigudrv.hö%ö1ÿÿÿÿ CFW_STATUSR/home/slovin/Projects/indi/src/sbigudrv.hñ4ñ>ÿÿÿÿ ClockADParamsR/home/slovin/Projects/indi/src/sbigudrv.h&&ÿÿÿÿ (DRIVER_CONTROL_PARAMR/home/slovin/Projects/indi/src/sbigudrv.hèQèeÿÿÿÿ DRIVER_REQUESTR/home/slovin/Projects/indi/src/sbigudrv.hÉ@ÉNÿÿÿÿ DumpLinesParamsR/home/slovin/Projects/indi/src/sbigudrv.h``ÿÿÿÿ ENUM_USB_DRIVERR/home/slovin/Projects/indi/src/sbigudrv.hë?ëNÿÿÿÿ "EndExposureParamsR/home/slovin/Projects/indi/src/sbigudrv.hSSÿÿÿÿ EndReadoutParamsR/home/slovin/Projects/indi/src/sbigudrv.hddÿÿÿÿ &EstablishLinkParamsR/home/slovin/Projects/indi/src/sbigudrv.h˜˜ÿÿÿÿ (EstablishLinkResultsR/home/slovin/Projects/indi/src/sbigudrv.hœœÿÿÿÿ FILTER_COMMANDR/home/slovin/Projects/indi/src/sbigudrv.hÜ8ÜFÿÿÿÿ FILTER_STATER/home/slovin/Projects/indi/src/sbigudrv.hÞ Þ,ÿÿÿÿ FILTER_TYPER/home/slovin/Projects/indi/src/sbigudrv.hàCàNÿÿÿÿ GetCCDInfoParamsR/home/slovin/Projects/indi/src/sbigudrv.hªªÿÿÿÿ $GetCCDInfoResults0R/home/slovin/Projects/indi/src/sbigudrv.hÂÂÿÿÿÿ $GetCCDInfoResults2R/home/slovin/Projects/indi/src/sbigudrv.hÉÉÿÿÿÿ $GetCCDInfoResults3R/home/slovin/Projects/indi/src/sbigudrv.hÎÎÿÿÿÿ $GetCCDInfoResults4R/home/slovin/Projects/indi/src/sbigudrv.hÓÓÿÿÿÿ ,GetDriverControlParamsR/home/slovin/Projects/indi/src/sbigudrv.hNNÿÿÿÿ .GetDriverControlResultsR/home/slovin/Projects/indi/src/sbigudrv.hRRÿÿÿÿ ,GetDriverHandleResultsR/home/slovin/Projects/indi/src/sbigudrv.hEEÿÿÿÿ &GetDriverInfoParamsR/home/slovin/Projects/indi/src/sbigudrv.h  ÿÿÿÿ *GetDriverInfoResults0R/home/slovin/Projects/indi/src/sbigudrv.h¦¦ÿÿÿÿ (GetErrorStringParamsR/home/slovin/Projects/indi/src/sbigudrv.h99ÿÿÿÿ *GetErrorStringResultsR/home/slovin/Projects/indi/src/sbigudrv.h==ÿÿÿÿ GetIRQLResultsR/home/slovin/Projects/indi/src/sbigudrv.hÿÿÿÿ (GetLinkStatusResultsR/home/slovin/Projects/indi/src/sbigudrv.hÿÿÿÿ 4GetPentiumCycleCountParamsR/home/slovin/Projects/indi/src/sbigudrv.hggÿÿÿÿ 6GetPentiumCycleCountResultsR/home/slovin/Projects/indi/src/sbigudrv.hllÿÿÿÿ ,GetSerialStatusResultsR/home/slovin/Projects/indi/src/sbigudrv.h””ÿÿÿÿ *GetTurboStatusResultsR/home/slovin/Projects/indi/src/sbigudrv.húúÿÿÿÿ "GetUSTimerResultsR/home/slovin/Projects/indi/src/sbigudrv.hÿÿÿÿ IMAGING_ABGR/home/slovin/Projects/indi/src/sbigudrv.hÎ.Î9ÿÿÿÿ LED_STATER/home/slovin/Projects/indi/src/sbigudrv.hÚ@ÚIÿÿÿÿ MY_LOGICALR/home/slovin/Projects/indi/src/sbigudrv.hÆÆ!unsigned short 4MiscellaneousControlParamsR/home/slovin/Projects/indi/src/sbigudrv.hááÿÿÿÿ OpenDeviceParamsR/home/slovin/Projects/indi/src/sbigudrv.hÿÿÿÿ PAR_COMMANDR/home/slovin/Projects/indi/src/sbigudrv.hvvÿÿÿÿ $PAR_COMMAND_STATUSR/home/slovin/Projects/indi/src/sbigudrv.h¦¦-ÿÿÿÿ PAR_ERRORR/home/slovin/Projects/indi/src/sbigudrv.hš0š9ÿÿÿÿ PORT_RATER/home/slovin/Projects/indi/src/sbigudrv.hÏCÏLÿÿÿÿ PulseOutParamsR/home/slovin/Projects/indi/src/sbigudrv.h‡‡ÿÿÿÿ QUERY_USB_INFOR/home/slovin/Projects/indi/src/sbigudrv.h^^ÿÿÿÿ 0QueryCommandStatusParamsR/home/slovin/Projects/indi/src/sbigudrv.h××ÿÿÿÿ 2QueryCommandStatusResultsR/home/slovin/Projects/indi/src/sbigudrv.hÛÛÿÿÿÿ :QueryTemperatureStatusResultsR/home/slovin/Projects/indi/src/sbigudrv.hzz ÿÿÿÿ QueryUSBResultsR/home/slovin/Projects/indi/src/sbigudrv.hccÿÿÿÿ READOUT_INFOR/home/slovin/Projects/indi/src/sbigudrv.h³³ÿÿÿÿ RWUSBI2CParamsR/home/slovin/Projects/indi/src/sbigudrv.hssÿÿÿÿ RWUSBI2CResultsR/home/slovin/Projects/indi/src/sbigudrv.hwwÿÿÿÿ ReadOffsetParamsR/home/slovin/Projects/indi/src/sbigudrv.hååÿÿÿÿ "ReadOffsetResultsR/home/slovin/Projects/indi/src/sbigudrv.hééÿÿÿÿ "ReadoutLineParamsR/home/slovin/Projects/indi/src/sbigudrv.hZZÿÿÿÿ SBIG_DEVICE_TYPER/home/slovin/Projects/indi/src/sbigudrv.häDäTÿÿÿÿ SHUTTER_COMMANDR/home/slovin/Projects/indi/src/sbigudrv.hÔDÔSÿÿÿÿ SHUTTER_STATE7R/home/slovin/Projects/indi/src/sbigudrv.hÕ<ÕJÿÿÿÿ SendBlockParamsR/home/slovin/Projects/indi/src/sbigudrv.hÿÿÿÿ SendByteParamsR/home/slovin/Projects/indi/src/sbigudrv.hÿÿÿÿ $SendSTVBlockParamsR/home/slovin/Projects/indi/src/sbigudrv.h55ÿÿÿÿ ,SetDriverControlParamsR/home/slovin/Projects/indi/src/sbigudrv.hJJÿÿÿÿ *SetDriverHandleParamsR/home/slovin/Projects/indi/src/sbigudrv.hAAÿÿÿÿ SetIRQLParamsR/home/slovin/Projects/indi/src/sbigudrv.hÿÿÿÿ <SetTemperatureRegulationParamsR/home/slovin/Projects/indi/src/sbigudrv.hrr!ÿÿÿÿ &StartExposureParamsR/home/slovin/Projects/indi/src/sbigudrv.hOOÿÿÿÿ $StartReadoutParamsR/home/slovin/Projects/indi/src/sbigudrv.hmmÿÿÿÿ SystemTestParamsR/home/slovin/Projects/indi/src/sbigudrv.h..ÿÿÿÿ ,TEMPERATURE_REGULATIONR/home/slovin/Projects/indi/src/sbigudrv.hØ?ØUÿÿÿÿ &TXSerialBytesParamsR/home/slovin/Projects/indi/src/sbigudrv.hŒŒÿÿÿÿ (TXSerialBytesResultsR/home/slovin/Projects/indi/src/sbigudrv.hÿÿÿÿ $USBADControlParamsR/home/slovin/Projects/indi/src/sbigudrv.hWWÿÿÿÿ ,USB_AD_CONTROL_COMMANDR/home/slovin/Projects/indi/src/sbigudrv.hêê0ÿÿÿÿ UserEEPROMParamsR/home/slovin/Projects/indi/src/sbigudrv.h››ÿÿÿÿ "UserEEPROMResultsR/home/slovin/Projects/indi/src/sbigudrv.h››%ÿÿÿÿZ/home/slovin/Projects/indi/src/skycommander.cÿÿÿÿ ISInitZ/home/slovin/Projects/indi/src/skycommander.c) ) *Aÿÿÿÿÿÿÿÿvoidÿÿÿÿvoid ISPollZ/home/slovin/Projects/indi/src/skycommander.c( (.ÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoid connectTelescopeZ/home/slovin/Projects/indi/src/skycommander.c* *" QÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidISGetPropertiesZ/home/slovin/Projects/indi/src/skycommander.cKUdevÿÿÿÿconst char*ÿÿÿÿvoid ISInitZ/home/slovin/Projects/indi/src/skycommander.c>IÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidISNewBLOBZ/home/slovin/Projects/indi/src/skycommander.c{~mdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿsizes[]ÿÿÿÿintÿÿÿÿblobs[]ÿÿÿÿ char*ÿÿÿÿformats[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewNumberZ/home/slovin/Projects/indi/src/skycommander.cvydevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchZ/home/slovin/Projects/indi/src/skycommander.cWddevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextZ/home/slovin/Projects/indi/src/skycommander.cfudevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPollZ/home/slovin/Projects/indi/src/skycommander.c€œpÿÿÿÿ void*ÿÿÿÿvoid connectTelescopeZ/home/slovin/Projects/indi/src/skycommander.cž»ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoid PortTZ/home/slovin/Projects/indi/src/skycommander.c1 17 IText PortTPZ/home/slovin/Projects/indi/src/skycommander.c22¢&ITextVectorProperty PowerSZ/home/slovin/Projects/indi/src/skycommander.c..wISwitchPowerSPZ/home/slovin/Projects/indi/src/skycommander.c//²*ISwitchVectorPropertyeqZ/home/slovin/Projects/indi/src/skycommander.c58INumber eqNumZ/home/slovin/Projects/indi/src/skycommander.c9;*INumberVectorPropertyfdZ/home/slovin/Projects/indi/src/skycommander.c,,intX/home/slovin/Projects/indi/src/temmadriver.cÿÿÿÿ*ISGetPropertiesX/home/slovin/Projects/indi/src/temmadriver.cPd1devÿÿÿÿconst char*ÿÿÿÿvoidISNewBLOBX/home/slovin/Projects/indi/src/temmadriver.cfidevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿsizes[]ÿÿÿÿintÿÿÿÿblobs[]ÿÿÿÿ char*ÿÿÿÿformats[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewNumberX/home/slovin/Projects/indi/src/temmadriver.czº F^€devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchX/home/slovin/Projects/indi/src/temmadriver.c½devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextX/home/slovin/Projects/indi/src/temmadriver.ckwdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidTemmaConnectX/home/slovin/Projects/indi/src/temmadriver.c›¥ deviceÿÿÿÿconst char*ÿÿÿÿintTemmaDisconnectX/home/slovin/Projects/indi/src/temmadriver.c§¬(intTemmaabortSlewX/home/slovin/Projects/indi/src/temmadriver.cÖÛ·UÇintTemmareadOutX/home/slovin/Projects/indi/src/temmadriver.cÍætimeoutÿÿÿÿintÿÿÿÿintcalcLSTX/home/slovin/Projects/indi/src/temmadriver.c2 strlstÿÿÿÿ char*ÿÿÿÿ doubleconnectMountX/home/slovin/Projects/indi/src/temmadriver.cI‚voiddisconnectMountX/home/slovin/Projects/indi/src/temmadriver.c„™voiddo_TemmaGOTOX/home/slovin/Projects/indi/src/temmadriver.cÝþ·UÇintdo_TemmaSLEWX/home/slovin/Projects/indi/src/temmadriver.cajmodeÿÿÿÿcharÿÿÿÿintextractDECX/home/slovin/Projects/indi/src/temmadriver.c 2>bufÿÿÿÿ char*ÿÿÿÿintextractRAX/home/slovin/Projects/indi/src/temmadriver.c  '€bufÿÿÿÿ char*ÿÿÿÿint,get_TemmaBOTHcorrspeedX/home/slovin/Projects/indi/src/temmadriver.cŒ•elocal_bufferÿÿÿÿ char*ÿÿÿÿint,get_TemmaCometTrackingX/home/slovin/Projects/indi/src/temmadriver.cûlocal_bufferÿÿÿÿ char*ÿÿÿÿint&get_TemmaCurrentposX/home/slovin/Projects/indi/src/temmadriver.c"9local_bufferÿÿÿÿ char*ÿÿÿÿint*get_TemmaDECcorrspeedX/home/slovin/Projects/indi/src/temmadriver.c— local_bufferÿÿÿÿ char*ÿÿÿÿint&get_TemmaGOTOstatusX/home/slovin/Projects/indi/src/temmadriver.c{Šilocal_bufferÿÿÿÿ char*ÿÿÿÿintget_TemmaLSTX/home/slovin/Projects/indi/src/temmadriver.cäîlocal_bufferÿÿÿÿ char*ÿÿÿÿint"get_TemmaLatitudeX/home/slovin/Projects/indi/src/temmadriver.cÂËlocal_bufferÿÿÿÿ char*ÿÿÿÿint(get_TemmaRAcorrspeedX/home/slovin/Projects/indi/src/temmadriver.c¬¶local_bufferÿÿÿÿ char*ÿÿÿÿint*get_TemmaStandbyStateX/home/slovin/Projects/indi/src/temmadriver.c6local_bufferÿÿÿÿunsigned char*ÿÿÿÿint get_TemmaVERSIONX/home/slovin/Projects/indi/src/temmadriver.clylocal_bufferÿÿÿÿ char*ÿÿÿÿintmountInitX/home/slovin/Projects/indi/src/temmadriver.c8MdvoidopenPortX/home/slovin/Projects/indi/src/temmadriver.cX}e portIDÿÿÿÿconst char*ÿÿÿÿintportReadX/home/slovin/Projects/indi/src/temmadriver.cËbufÿÿÿÿ char*ÿÿÿÿ nbytesÿÿÿÿintÿÿÿÿtimeoutÿÿÿÿintÿÿÿÿintportWriteX/home/slovin/Projects/indi/src/temmadriver.cŽbufÿÿÿÿ char*ÿÿÿÿint&readMountcurrentposX/home/slovin/Projects/indi/src/temmadriver.c6Fpÿÿÿÿ void*ÿÿÿÿvoid"set_CometTrackingX/home/slovin/Projects/indi/src/temmadriver.c®Ô RArateÿÿÿÿintÿÿÿÿDECrateÿÿÿÿintÿÿÿÿint,set_TemmaCometTrackingX/home/slovin/Projects/indi/src/temmadriver.c8?Klocal_bufferÿÿÿÿ char*ÿÿÿÿint&set_TemmaCurrentposX/home/slovin/Projects/indi/src/temmadriver.c;_eÿÿÿÿÿÿÿÿvoidÿÿÿÿint*set_TemmaDECcorrspeedX/home/slovin/Projects/indi/src/temmadriver.c¢ª @rlocal_bufferÿÿÿÿ char*ÿÿÿÿintset_TemmaLSTX/home/slovin/Projects/indi/src/temmadriver.cñø @ylocal_bufferÿÿÿÿ char*ÿÿÿÿint"set_TemmaLatitudeX/home/slovin/Projects/indi/src/temmadriver.cÍâ @v€local_bufferÿÿÿÿ char*ÿÿÿÿint(set_TemmaRAcorrspeedX/home/slovin/Projects/indi/src/temmadriver.c¸Àlocal_bufferÿÿÿÿ char*ÿÿÿÿint$set_TemmaSolarRateX/home/slovin/Projects/indi/src/temmadriver.cAEÿÿÿÿÿÿÿÿvoidÿÿÿÿint*set_TemmaStandbyStateX/home/slovin/Projects/indi/src/temmadriver.conÿÿÿÿintÿÿÿÿint(set_TemmaStellarRateX/home/slovin/Projects/indi/src/temmadriver.cGKDÿÿÿÿÿÿÿÿvoidÿÿÿÿint*switch_TemmamountsideX/home/slovin/Projects/indi/src/temmadriver.cNRÿÿÿÿÿÿÿÿvoidÿÿÿÿint answerX/home/slovin/Projects/indi/src/temmadriver.c//char bufferX/home/slovin/Projects/indi/src/temmadriver.c22unsigned charbuffer2X/home/slovin/Projects/indi/src/temmadriver.c33unsigned charerrormesX/home/slovin/Projects/indi/src/temmadriver.c(-charfdX/home/slovin/Projects/indi/src/temmadriver.c00intread_retX/home/slovin/Projects/indi/src/temmadriver.c11 intwrite_retX/home/slovin/Projects/indi/src/temmadriver.c11intX/home/slovin/Projects/indi/src/temmadriver.hÿÿÿÿ)ISGetPropertiesX/home/slovin/Projects/indi/src/temmadriver.hOO&devÿÿÿÿconst char*ÿÿÿÿvoidISNewNumberX/home/slovin/Projects/indi/src/temmadriver.hQQ[rdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchX/home/slovin/Projects/indi/src/temmadriver.hRR[·UÇdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextX/home/slovin/Projects/indi/src/temmadriver.hPPW (o€devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidTemmaConnectX/home/slovin/Projects/indi/src/temmadriver.hTT$ deviceÿÿÿÿconst char*ÿÿÿÿintTemmaDisconnectX/home/slovin/Projects/indi/src/temmadriver.hUUÿÿÿÿÿÿÿÿvoidÿÿÿÿintTemmaabortSlewX/home/slovin/Projects/indi/src/temmadriver.hWWÿÿÿÿÿÿÿÿvoidÿÿÿÿintTemmareadOutX/home/slovin/Projects/indi/src/temmadriver.hMM A€timeoutÿÿÿÿintÿÿÿÿintcalcLSTX/home/slovin/Projects/indi/src/temmadriver.hSS ¼ strlstÿÿÿÿ char*ÿÿÿÿ doubleconnectMountX/home/slovin/Projects/indi/src/temmadriver.hr rÿÿÿˆÿÿÿÿÿÿÿÿvoidÿÿÿÿvoiddisconnectMountX/home/slovin/Projects/indi/src/temmadriver.hq q"ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoiddo_TemmaGOTOX/home/slovin/Projects/indi/src/temmadriver.hXX *ÿÿÿÿÿÿÿÿvoidÿÿÿÿintdo_TemmaSLEWX/home/slovin/Projects/indi/src/temmadriver.h]]modeÿÿÿÿcharÿÿÿÿintextractDECX/home/slovin/Projects/indi/src/temmadriver.hZZbufÿÿÿÿ char*ÿÿÿÿintextractRAX/home/slovin/Projects/indi/src/temmadriver.hYYbufÿÿÿÿ char*ÿÿÿÿint,get_TemmaBOTHcorrspeedX/home/slovin/Projects/indi/src/temmadriver.h``( L bufferÿÿÿÿ char*ÿÿÿÿint,get_TemmaCometTrackingX/home/slovin/Projects/indi/src/temmadriver.hkk) Ѐ bufferÿÿÿÿ char*ÿÿÿÿint&get_TemmaCurrentposX/home/slovin/Projects/indi/src/temmadriver.h[[% bufferÿÿÿÿ char*ÿÿÿÿint*get_TemmaDECcorrspeedX/home/slovin/Projects/indi/src/temmadriver.haa' bufferÿÿÿÿ char*ÿÿÿÿint&get_TemmaGOTOstatusX/home/slovin/Projects/indi/src/temmadriver.h__% bufferÿÿÿÿ char*ÿÿÿÿintget_TemmaLSTX/home/slovin/Projects/indi/src/temmadriver.hgg +Ð bufferÿÿÿÿ char*ÿÿÿÿint"get_TemmaLatitudeX/home/slovin/Projects/indi/src/temmadriver.hee#·UÇ bufferÿÿÿÿ char*ÿÿÿÿint(get_TemmaRAcorrspeedX/home/slovin/Projects/indi/src/temmadriver.hcc& "€ bufferÿÿÿÿ char*ÿÿÿÿint*get_TemmaStandbyStateX/home/slovin/Projects/indi/src/temmadriver.hjj1 bufferÿÿÿÿunsigned char*ÿÿÿÿint get_TemmaVERSIONX/home/slovin/Projects/indi/src/temmadriver.h^^" bufferÿÿÿÿ char*ÿÿÿÿintmountInitX/home/slovin/Projects/indi/src/temmadriver.hN N =ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidopenPortX/home/slovin/Projects/indi/src/temmadriver.hJJ Õ portIDÿÿÿÿconst char*ÿÿÿÿintportReadX/home/slovin/Projects/indi/src/temmadriver.hKK0 ,bufÿÿÿÿ char*ÿÿÿÿ nbytesÿÿÿÿintÿÿÿÿtimeoutÿÿÿÿintÿÿÿÿintportWriteX/home/slovin/Projects/indi/src/temmadriver.hLL (m€bufÿÿÿÿ char*ÿÿÿÿint&readMountcurrentposX/home/slovin/Projects/indi/src/temmadriver.hs s(ÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoid"set_CometTrackingX/home/slovin/Projects/indi/src/temmadriver.hVV/ RArateÿÿÿÿintÿÿÿÿDECrateÿÿÿÿintÿÿÿÿint,set_TemmaCometTrackingX/home/slovin/Projects/indi/src/temmadriver.hll) ¨€ bufferÿÿÿÿ char*ÿÿÿÿint&set_TemmaCurrentposX/home/slovin/Projects/indi/src/temmadriver.h\\ÿÿÿÿÿÿÿÿvoidÿÿÿÿint*set_TemmaDECcorrspeedX/home/slovin/Projects/indi/src/temmadriver.hbb' bufferÿÿÿÿ char*ÿÿÿÿintset_TemmaLSTX/home/slovin/Projects/indi/src/temmadriver.hhh bufferÿÿÿÿ char*ÿÿÿÿint"set_TemmaLatitudeX/home/slovin/Projects/indi/src/temmadriver.hff#·UÇ bufferÿÿÿÿ char*ÿÿÿÿint(set_TemmaRAcorrspeedX/home/slovin/Projects/indi/src/temmadriver.hdd& E bufferÿÿÿÿ char*ÿÿÿÿint$set_TemmaSolarRateX/home/slovin/Projects/indi/src/temmadriver.hmm·UÇÿÿÿÿÿÿÿÿvoidÿÿÿÿint*set_TemmaStandbyStateX/home/slovin/Projects/indi/src/temmadriver.hii" +Ï€onÿÿÿÿintÿÿÿÿint(set_TemmaStellarRateX/home/slovin/Projects/indi/src/temmadriver.hnn ­€ÿÿÿÿÿÿÿÿvoidÿÿÿÿint*switch_TemmamountsideX/home/slovin/Projects/indi/src/temmadriver.hoo ÿÿÿÿÿÿÿÿvoidÿÿÿÿintOnCoordSetSX/home/slovin/Projects/indi/src/temmadriver.hÞá$ISwitchOnCoordSetSwX/home/slovin/Projects/indi/src/temmadriver.hãæ3*ISwitchVectorPropertyPortX/home/slovin/Projects/indi/src/temmadriver.h©«/&ITextVectorProperty PortTX/home/slovin/Projects/indi/src/temmadriver.h¨ ¨7 ITextRAmotorX/home/slovin/Projects/indi/src/temmadriver.hxz ISwitchRAmotorSwX/home/slovin/Projects/indi/src/temmadriver.h|~.*ISwitchVectorProperty SDTimeX/home/slovin/Projects/indi/src/temmadriver.hÙÜ*INumberVectorProperty STimeX/home/slovin/Projects/indi/src/temmadriver.hÕ×INumberTemmaNoteTX/home/slovin/Projects/indi/src/temmadriver.h¢ ¢U ITextTemmaNoteTPX/home/slovin/Projects/indi/src/temmadriver.h££¤&ITextVectorPropertyTemmaVersionX/home/slovin/Projects/indi/src/temmadriver.hšœ5&ITextVectorPropertyTemmaVersionTX/home/slovin/Projects/indi/src/temmadriver.h™ ™E ITextTimeX/home/slovin/Projects/indi/src/temmadriver.hÑÓ-*INumberVectorPropertyUTCX/home/slovin/Projects/indi/src/temmadriver.hÏÐ1INumberabortSlewSX/home/slovin/Projects/indi/src/temmadriver.hêë$ISwitchabortSlewSwX/home/slovin/Projects/indi/src/temmadriver.hìï'*ISwitchVectorProperty cometX/home/slovin/Projects/indi/src/temmadriver.hÅÈINumbercometNumX/home/slovin/Projects/indi/src/temmadriver.hÊÌP*INumberVectorPropertyeqX/home/slovin/Projects/indi/src/temmadriver.h°³INumber eqNumX/home/slovin/Projects/indi/src/temmadriver.h´¶H*INumberVectorPropertyeqTemmaX/home/slovin/Projects/indi/src/temmadriver.h¿ÁN*INumberVectorProperty eqtemX/home/slovin/Projects/indi/src/temmadriver.h»¾INumbergeoX/home/slovin/Projects/indi/src/temmadriver.hòôBINumber geoNumX/home/slovin/Projects/indi/src/temmadriver.höù*INumberVectorProperty powSwX/home/slovin/Projects/indi/src/temmadriver.h’”**ISwitchVectorProperty powerX/home/slovin/Projects/indi/src/temmadriver.hIISwitchtrackmodeX/home/slovin/Projects/indi/src/temmadriver.hƒ†%ISwitchtrackmodeSwX/home/slovin/Projects/indi/src/temmadriver.hˆŠ2*ISwitchVectorProperty\/home/slovin/Projects/indi/src/trutech_wheel.cÿÿÿÿ  ISInit\/home/slovin/Projects/indi/src/trutech_wheel.c&&.ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoid ISPoll\/home/slovin/Projects/indi/src/trutech_wheel.c((ÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoidcheckPowerN\/home/slovin/Projects/indi/src/trutech_wheel.c--+npÿÿÿÿ,INumberVectorProperty*ÿÿÿÿintcheckPowerS\/home/slovin/Projects/indi/src/trutech_wheel.c,,+spÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿintcheckPowerT\/home/slovin/Projects/indi/src/trutech_wheel.c..)tpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿintconnectFilter\/home/slovin/Projects/indi/src/trutech_wheel.c**ö€ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidgetBasicData\/home/slovin/Projects/indi/src/trutech_wheel.c''ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidgetOnSwitch\/home/slovin/Projects/indi/src/trutech_wheel.c//+ ,€spÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿinthandleExposure\/home/slovin/Projects/indi/src/trutech_wheel.c)) @8ÿÿÿÿÿÿÿÿ void*ÿÿÿÿvoid"isFilterConnected\/home/slovin/Projects/indi/src/trutech_wheel.c00üûÿÿÿÿÿÿÿÿvoidÿÿÿÿintmanageDefaults\/home/slovin/Projects/indi/src/trutech_wheel.c++"errmsg[]ÿÿÿÿcharÿÿÿÿint ISGetProperties\/home/slovin/Projects/indi/src/trutech_wheel.cl{devÿÿÿÿconst char*ÿÿÿÿvoid ISInit\/home/slovin/Projects/indi/src/trutech_wheel.c\j voidISNewBLOB\/home/slovin/Projects/indi/src/trutech_wheel.c}€ €devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿsizes[]ÿÿÿÿintÿÿÿÿblobs[]ÿÿÿÿ char*ÿÿÿÿformats[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewNumber\/home/slovin/Projects/indi/src/trutech_wheel.cÝdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitch\/home/slovin/Projects/indi/src/trutech_wheel.c‚Çý(€devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewText\/home/slovin/Projects/indi/src/trutech_wheel.cÉÚ hdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoid ISPoll\/home/slovin/Projects/indi/src/trutech_wheel.cpÿÿÿÿ void*ÿÿÿÿvoidcheckPowerN\/home/slovin/Projects/indi/src/trutech_wheel.c;Jnpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿintcheckPowerS\/home/slovin/Projects/indi/src/trutech_wheel.c)9spÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿintcheckPowerT\/home/slovin/Projects/indi/src/trutech_wheel.cL\tpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿintconnectFilter\/home/slovin/Projects/indi/src/trutech_wheel.c^ #voidgetOnSwitch\/home/slovin/Projects/indi/src/trutech_wheel.c' ¢spÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿint"isFilterConnected\/home/slovin/Projects/indi/src/trutech_wheel.c„‡·UÇÿÿÿÿÿÿÿÿvoidÿÿÿÿintCOMM_FILL\/home/slovin/Projects/indi/src/trutech_wheel.c5 5charCOMM_INIT\/home/slovin/Projects/indi/src/trutech_wheel.c4 4charCOMM_NL\/home/slovin/Projects/indi/src/trutech_wheel.c6 6charFilterPositionN\/home/slovin/Projects/indi/src/trutech_wheel.cTTrINumber FilterPositionNP\/home/slovin/Projects/indi/src/trutech_wheel.cUUÁ*INumberVectorPropertyFilterSizeN\/home/slovin/Projects/indi/src/trutech_wheel.cXXPINumberFilterSizeNP\/home/slovin/Projects/indi/src/trutech_wheel.cYY¯*INumberVectorProperty HomeS\/home/slovin/Projects/indi/src/trutech_wheel.cPPBISwitch HomeSP\/home/slovin/Projects/indi/src/trutech_wheel.cQQ¥*ISwitchVectorProperty PortT\/home/slovin/Projects/indi/src/trutech_wheel.cL L7 IText PortTP\/home/slovin/Projects/indi/src/trutech_wheel.cMM¡&ITextVectorProperty PowerS\/home/slovin/Projects/indi/src/trutech_wheel.cHHxISwitchPowerSP\/home/slovin/Projects/indi/src/trutech_wheel.cII¸*ISwitchVectorPropertyfd\/home/slovin/Projects/indi/src/trutech_wheel.c3 3 inttargetFilter\/home/slovin/Projects/indi/src/trutech_wheel.c2 2intT/home/slovin/Projects/indi/src/v4ldriver.hÿÿÿÿV4L_DriverT/home/slovin/Projects/indi/src/v4ldriver.hE®ISGetPropertiesT/home/slovin/Projects/indi/src/v4ldriver.hLL2V4L_Driver ¦devÿÿÿÿconst char*ÿÿÿÿvoidISNewNumberT/home/slovin/Projects/indi/src/v4ldriver.hOOgV4L_Driverdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchT/home/slovin/Projects/indi/src/v4ldriver.hMMgV4L_Driverdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextT/home/slovin/Projects/indi/src/v4ldriver.hNNcV4L_Driver „devÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidV4L_DriverT/home/slovin/Projects/indi/src/v4ldriver.hHHV4L_Driver 'zÿÿÿÿaddFITSKeywordsT/home/slovin/Projects/indi/src/v4ldriver.h——'V4L_Driverfptrÿÿÿÿfitsfile*ÿÿÿÿvoidcheckPowerNT/home/slovin/Projects/indi/src/v4ldriver.hšš.V4L_Drivernpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿintcheckPowerST/home/slovin/Projects/indi/src/v4ldriver.h››.V4L_Driverspÿÿÿÿ,ISwitchVectorProperty*ÿÿÿÿintcheckPowerTT/home/slovin/Projects/indi/src/v4ldriver.hœœ,V4L_Drivertpÿÿÿÿ(ITextVectorProperty*ÿÿÿÿintconnectCameraT/home/slovin/Projects/indi/src/v4ldriver.h#V4L_DriverÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidgetBasicDataT/home/slovin/Projects/indi/src/v4ldriver.h"V4L_Driver„ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidgrabImageT/home/slovin/Projects/indi/src/v4ldriver.h––V4L_Driver .€ÿÿÿÿÿÿÿÿvoidÿÿÿÿintinitCamBaseT/home/slovin/Projects/indi/src/v4ldriver.hQQV4L_DrivervoidinitPropertiesT/home/slovin/Projects/indi/src/v4ldriver.hRR0V4L_Driver·UÇdevÿÿÿÿconst char*ÿÿÿÿvoidnewFrameT/home/slovin/Projects/indi/src/v4ldriver.hTT!V4L_Driverepÿÿÿÿ void*ÿÿÿÿvoidupdateFrameT/home/slovin/Projects/indi/src/v4ldriver.hU UV4L_Driver voidupdateStreamT/home/slovin/Projects/indi/src/v4ldriver.h““V4L_Drivervoid$updateV4L1ControlsT/home/slovin/Projects/indi/src/v4ldriver.hŸŸ$V4L_DrivervoiduploadFileT/home/slovin/Projects/indi/src/v4ldriver.h””)V4L_Driverfilenameÿÿÿÿconst char*ÿÿÿÿvoidwriteFITST/home/slovin/Projects/indi/src/v4ldriver.h••6V4L_Driverfilenameÿÿÿÿconst char*ÿÿÿÿerrmsg[]ÿÿÿÿcharÿÿÿÿint~ V4L_DriverT/home/slovin/Projects/indi/src/v4ldriver.hI IV4L_Driver ÄÿÿÿÿCompressST/home/slovin/Projects/indi/src/v4ldriver.hi iISwitchCompressSPT/home/slovin/Projects/indi/src/v4ldriver.h~~$*ISwitchVectorPropertyExposeTimeNT/home/slovin/Projects/indi/src/v4ldriver.hq qINumberExposeTimeNPT/home/slovin/Projects/indi/src/v4ldriver.h‚‚&*INumberVectorProperty FrameNT/home/slovin/Projects/indi/src/v4ldriver.hs sINumberFrameNPT/home/slovin/Projects/indi/src/v4ldriver.h„„!*INumberVectorPropertyFrameRateNT/home/slovin/Projects/indi/src/v4ldriver.hr rINumberFrameRateNPT/home/slovin/Projects/indi/src/v4ldriver.hƒƒ%*INumberVectorPropertyImageAdjustNT/home/slovin/Projects/indi/src/v4ldriver.hu uINumberImageAdjustNPT/home/slovin/Projects/indi/src/v4ldriver.h……'*INumberVectorPropertyImageTypeST/home/slovin/Projects/indi/src/v4ldriver.hj jISwitchImageTypeSPT/home/slovin/Projects/indi/src/v4ldriver.h%*ISwitchVectorProperty PortTT/home/slovin/Projects/indi/src/v4ldriver.hm m IText PortTPT/home/slovin/Projects/indi/src/v4ldriver.hˆˆ&ITextVectorProperty PowerST/home/slovin/Projects/indi/src/v4ldriver.hg gISwitchPowerSPT/home/slovin/Projects/indi/src/v4ldriver.h||!*ISwitchVectorPropertyStreamST/home/slovin/Projects/indi/src/v4ldriver.hh hISwitchStreamSPT/home/slovin/Projects/indi/src/v4ldriver.h}}"*ISwitchVectorPropertyV4LFrameT/home/slovin/Projects/indi/src/v4ldriver.h© © img_t*camNameTT/home/slovin/Projects/indi/src/v4ldriver.hn n ITextcamNameTPT/home/slovin/Projects/indi/src/v4ldriver.h‰‰!&ITextVectorPropertycapture_endT/home/slovin/Projects/indi/src/v4ldriver.h¬ ¬ time_tcapture_startT/home/slovin/Projects/indi/src/v4ldriver.h« « time_tdevice_nameT/home/slovin/Projects/indi/src/v4ldriver.h¦¦"chardividerT/home/slovin/Projects/indi/src/v4ldriver.h¨ ¨ doubleframeCountT/home/slovin/Projects/indi/src/v4ldriver.h§§int imageBT/home/slovin/Projects/indi/src/v4ldriver.hy y IBLOBimageBPT/home/slovin/Projects/indi/src/v4ldriver.hŒŒ&IBLOBVectorPropertyv4l_baseT/home/slovin/Projects/indi/src/v4ldriver.h   V4L1_Base* img_tT/home/slovin/Projects/indi/src/v4ldriver.hccÿÿÿÿV/home/slovin/Projects/indi/src/v4lphilips.hÿÿÿÿV4L_PhilipsV/home/slovin/Projects/indi/src/v4lphilips.hKV4L_Driver ISGetPropertiesV/home/slovin/Projects/indi/src/v4lphilips.h# #*V4L_Philipsdevÿÿÿÿconst char*ÿÿÿÿvoidISNewNumberV/home/slovin/Projects/indi/src/v4lphilips.h& &_V4L_Philipsdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿvalues[]ÿÿÿÿ doubleÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewSwitchV/home/slovin/Projects/indi/src/v4lphilips.h$ $_V4L_Philipsdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿ statesÿÿÿÿISState*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidISNewTextV/home/slovin/Projects/indi/src/v4lphilips.h% %[V4L_Philips ùdevÿÿÿÿconst char*ÿÿÿÿnameÿÿÿÿconst char*ÿÿÿÿtexts[]ÿÿÿÿ char*ÿÿÿÿnames[]ÿÿÿÿ char*ÿÿÿÿnÿÿÿÿintÿÿÿÿvoidV4L_PhilipsV/home/slovin/Projects/indi/src/v4lphilips.hV4L_Philips 'ÿÿÿÿconnectCameraV/home/slovin/Projects/indi/src/v4lphilips.h* *V4L_PhilipsÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidgetBasicDataV/home/slovin/Projects/indi/src/v4lphilips.hH HV4L_Philips"ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidinitCamBaseV/home/slovin/Projects/indi/src/v4lphilips.h( (V4L_PhilipsvoidinitPropertiesV/home/slovin/Projects/indi/src/v4lphilips.h) )(V4L_Philipsdevÿÿÿÿconst char*ÿÿÿÿvoid$updateV4L1ControlsV/home/slovin/Projects/indi/src/v4lphilips.hG GV4L_Philipsvoid~ V4L_PhilipsV/home/slovin/Projects/indi/src/v4lphilips.h  V4L_Philips )©ÿÿÿÿAntiFlickerSV/home/slovin/Projects/indi/src/v4lphilips.h0 0ISwitchAntiFlickerSPV/home/slovin/Projects/indi/src/v4lphilips.h<<'*ISwitchVectorPropertyBackLightSV/home/slovin/Projects/indi/src/v4lphilips.h/ /ISwitchBackLightSPV/home/slovin/Projects/indi/src/v4lphilips.h;;%*ISwitchVectorPropertyCamSettingSV/home/slovin/Projects/indi/src/v4lphilips.h2 2ISwitchCamSettingSPV/home/slovin/Projects/indi/src/v4lphilips.h>>&*ISwitchVectorPropertyNoiseReductionSV/home/slovin/Projects/indi/src/v4lphilips.h1 1ISwitch NoiseReductionSPV/home/slovin/Projects/indi/src/v4lphilips.h==**ISwitchVectorPropertyShutterSpeedNV/home/slovin/Projects/indi/src/v4lphilips.h8 8INumberShutterSpeedNPV/home/slovin/Projects/indi/src/v4lphilips.hCC(*INumberVectorProperty"WhiteBalanceModeSV/home/slovin/Projects/indi/src/v4lphilips.h3 3 ISwitch$WhiteBalanceModeSPV/home/slovin/Projects/indi/src/v4lphilips.h??,*ISwitchVectorPropertyWhiteBalanceNV/home/slovin/Projects/indi/src/v4lphilips.h7 7INumberWhiteBalanceNPV/home/slovin/Projects/indi/src/v4lphilips.hBB(*INumberVectorPropertyv4l_pwcV/home/slovin/Projects/indi/src/v4lphilips.hF FV4L1_PWC*Z/home/slovin/Projects/indi/src/webcam/PPort.hÿÿÿÿ PPortZ/home/slovin/Projects/indi/src/webcam/PPort.hJ  PPortZ/home/slovin/Projects/indi/src/webcam/PPort.h  PPortÿÿÿÿ PPortZ/home/slovin/Projects/indi/src/webcam/PPort.h PPort ioPortÿÿÿÿintÿÿÿÿÿÿÿÿ commitZ/home/slovin/Projects/indi/src/webcam/PPort.hDD PPortboolisRegisterBitZ/home/slovin/Projects/indi/src/webcam/PPort.h@@4 PPort IDÿÿÿÿconst void*ÿÿÿÿbitÿÿÿÿintÿÿÿÿboolregisterBitZ/home/slovin/Projects/indi/src/webcam/PPort.h11, PPortIDÿÿÿÿconst void*ÿÿÿÿbitÿÿÿÿintÿÿÿÿbool resetZ/home/slovin/Projects/indi/src/webcam/PPort.hFF PPortivoid setBitZ/home/slovin/Projects/indi/src/webcam/PPort.h**1 PPortIDÿÿÿÿconst void*ÿÿÿÿbitÿÿÿÿintÿÿÿÿstatÿÿÿÿboolÿÿÿÿboolsetPortZ/home/slovin/Projects/indi/src/webcam/PPort.h"" PPort ioPortÿÿÿÿintÿÿÿÿboolunregisterBitZ/home/slovin/Projects/indi/src/webcam/PPort.h88. PPortIDÿÿÿÿconst void*ÿÿÿÿbitÿÿÿÿintÿÿÿÿbool~ PPortZ/home/slovin/Projects/indi/src/webcam/PPort.h  PPortÿÿÿÿassignedBitZ/home/slovin/Projects/indi/src/webcam/PPort.hHHconst void*bitArrayZ/home/slovin/Projects/indi/src/webcam/PPort.hGGunsigned charcurrentPortZ/home/slovin/Projects/indi/src/webcam/PPort.hI Iport_t*X/home/slovin/Projects/indi/src/webcam/ccvt.hÿÿÿÿhaveBrightnessX/home/slovin/Projects/indi/src/webcam/ccvt.hinthaveColorX/home/slovin/Projects/indi/src/webcam/ccvt.h  inthaveContrastX/home/slovin/Projects/indi/src/webcam/ccvt.hžžinthaveHueX/home/slovin/Projects/indi/src/webcam/ccvt.hŸŸinthaveWhitenessX/home/slovin/Projects/indi/src/webcam/ccvt.h¡¡intioNoBlockX/home/slovin/Projects/indi/src/webcam/ccvt.h››intioUseSelectX/home/slovin/Projects/indi/src/webcam/ccvt.hœœintd/home/slovin/Projects/indi/src/webcam/ccvt_types.hÿÿÿÿ PIXTYPE_bgr24d/home/slovin/Projects/indi/src/webcam/ccvt_types.h&&ÿÿÿÿ PIXTYPE_bgr32d/home/slovin/Projects/indi/src/webcam/ccvt_types.hÿÿÿÿ PIXTYPE_rgb24d/home/slovin/Projects/indi/src/webcam/ccvt_types.h55ÿÿÿÿ PIXTYPE_rgb32d/home/slovin/Projects/indi/src/webcam/ccvt_types.h..ÿÿÿÿh/home/slovin/Projects/indi/src/webcam/empty_file.cppÿÿÿÿX/home/slovin/Projects/indi/src/webcam/port.hÿÿÿÿ port_tX/home/slovin/Projects/indi/src/webcam/port.hOx  clearbit_controlX/home/slovin/Projects/indi/src/webcam/port.haaO port_t·UÇdataÿÿÿÿintÿÿÿÿvoidget_portX/home/slovin/Projects/indi/src/webcam/port.hdd( port_tintoperator boolX/home/slovin/Projects/indi/src/webcam/port.hee6 port_t ÿÿÿÿ port_tX/home/slovin/Projects/indi/src/webcam/port.hQQ port_t iportÿÿÿÿintÿÿÿÿÿÿÿÿread_controlX/home/slovin/Projects/indi/src/webcam/port.hVV6 port_tÿÿÿÿÿÿÿÿvoidÿÿÿÿintread_dataX/home/slovin/Projects/indi/src/webcam/port.hTT2 port_tÿÿÿÿÿÿÿÿvoidÿÿÿÿintread_statusX/home/slovin/Projects/indi/src/webcam/port.hUU5 port_tÿÿÿÿÿÿÿÿvoidÿÿÿÿintsetbit_controlX/home/slovin/Projects/indi/src/webcam/port.h``L port_tdataÿÿÿÿintÿÿÿÿvoidwrite_controlX/home/slovin/Projects/indi/src/webcam/port.h__J port_tdataÿÿÿÿintÿÿÿÿvoidwrite_dataX/home/slovin/Projects/indi/src/webcam/port.h^^8 port_tdataÿÿÿÿintÿÿÿÿvoid~ port_tX/home/slovin/Projects/indi/src/webcam/port.hRR port_tiÿÿÿÿÿÿÿÿvoidÿÿÿÿÿÿÿÿ  clearbit_controlX/home/slovin/Projects/indi/src/webcam/port.haaO port_t·UÇdataÿÿÿÿintÿÿÿÿvoidget_portX/home/slovin/Projects/indi/src/webcam/port.hdd( port_tintoperator boolX/home/slovin/Projects/indi/src/webcam/port.hee6 port_t ÿÿÿÿread_controlX/home/slovin/Projects/indi/src/webcam/port.hVV6 port_tÿÿÿÿÿÿÿÿvoidÿÿÿÿintread_dataX/home/slovin/Projects/indi/src/webcam/port.hTT2 port_tÿÿÿÿÿÿÿÿvoidÿÿÿÿintread_statusX/home/slovin/Projects/indi/src/webcam/port.hUU5 port_tÿÿÿÿÿÿÿÿvoidÿÿÿÿintsetbit_controlX/home/slovin/Projects/indi/src/webcam/port.h``L port_tdataÿÿÿÿintÿÿÿÿvoidwrite_controlX/home/slovin/Projects/indi/src/webcam/port.h__J port_tdataÿÿÿÿintÿÿÿÿvoidwrite_dataX/home/slovin/Projects/indi/src/webcam/port.h^^8 port_tdataÿÿÿÿintÿÿÿÿvoidcontrol_regX/home/slovin/Projects/indi/src/webcam/port.hkkintportX/home/slovin/Projects/indi/src/webcam/port.hhh int port1X/home/slovin/Projects/indi/src/webcam/port.hii int port2X/home/slovin/Projects/indi/src/webcam/port.hjj intb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hÿÿÿÿ pwc_coordb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hTXsizeb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hWW intxb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hVVintyb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hVV intpwc_imagesizeb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h‘• heightb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h”” int widthb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h““ intpwc_ledsb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hŠŽled_offb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h int led_onb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hŒŒ intpwc_mpt_anglesb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h¡¦absoluteb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h££ intpanb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h¤¤inttiltb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h¥¥ intpwc_mpt_rangeb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hª®pan_maxb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h¬¬intpan_minb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h¬¬ inttilt_maxb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h­­inttilt_minb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h­­ intpwc_mpt_statusb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h°µ statusb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h²² inttime_panb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h³³ inttime_tiltb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h´´intpwc_probeb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h\`nameb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h^^chartypeb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h__ intpwc_raw_frameb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h9@cmdb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h<<unsigned chartypeb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h::unsigned shortvbandlengthb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h;;unsigned shortpwc_serialb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hbe serialb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hddchar*pwc_table_init_bufferb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h"& bufferb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h$$ char*lenb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h## int"pwc_video_commandb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h¼Çalternateb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h Âintbandlengthb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hÅÅintcommand_bufb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hÄÄunsigned charcommand_lenb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hÃÃintframe_sizeb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hÆÆintreleaseb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h¿¿ intsizeb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hÁ Áinttypeb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h¾¾ intpwc_wb_speedb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h‚‡control_delayb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h……intcontrol_speedb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.h„„int pwc_whitebalanceb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hv{manual_blueb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hyyintmanual_redb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hyyintmodeb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hxx intread_blueb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hzzintread_redb/home/slovin/Projects/indi/src/webcam/pwc-ioctl.hzz intb/home/slovin/Projects/indi/src/webcam/v4l1_base.hÿÿÿÿV4L1_Baseb/home/slovin/Projects/indi/src/webcam/v4l1_base.hk'V4L1_Baseb/home/slovin/Projects/indi/src/webcam/v4l1_base.h  V4L1_Baseý7€ÿÿÿÿallocBuffersb/home/slovin/Projects/indi/src/webcam/v4l1_base.hFFV4L1_Base ¥voidcheckSizeb/home/slovin/Projects/indi/src/webcam/v4l1_base.h=="V4L1_Base g€xÿÿÿÿint&ÿÿÿÿyÿÿÿÿint&ÿÿÿÿvoidconnectCamb/home/slovin/Projects/indi/src/webcam/v4l1_base.h$$<V4L1_Base·UÇdevpathÿÿÿÿconst char*ÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿintdisconnectCamb/home/slovin/Projects/indi/src/webcam/v4l1_base.h%%V4L1_Base·UÇvoidgetBrightnessb/home/slovin/Projects/indi/src/webcam/v4l1_base.h))V4L1_BaseintgetColorb/home/slovin/Projects/indi/src/webcam/v4l1_base.h++V4L1_Base '|€intgetColorBufferb/home/slovin/Projects/indi/src/webcam/v4l1_base.hOO"V4L1_Base·UÇunsigned char*getContrastb/home/slovin/Projects/indi/src/webcam/v4l1_base.h**V4L1_BaseintgetDeviceNameb/home/slovin/Projects/indi/src/webcam/v4l1_base.h&&V4L1_Base·UÇ char* getFPSb/home/slovin/Projects/indi/src/webcam/v4l1_base.hCCV4L1_BaseintgetHeightb/home/slovin/Projects/indi/src/webcam/v4l1_base.h<<V4L1_Baseint getHueb/home/slovin/Projects/indi/src/webcam/v4l1_base.h,,V4L1_Base '|€intgetMaxMinSizeb/home/slovin/Projects/indi/src/webcam/v4l1_base.h??LV4L1_Basexmaxÿÿÿÿint&ÿÿÿÿymaxÿÿÿÿint&ÿÿÿÿxminÿÿÿÿint&ÿÿÿÿyminÿÿÿÿint&ÿÿÿÿvoid$getPictureSettingsb/home/slovin/Projects/indi/src/webcam/v4l1_base.h88V4L1_Base·UÇvoidgetUb/home/slovin/Projects/indi/src/webcam/v4l1_base.hMMV4L1_Baseunsigned char*getVb/home/slovin/Projects/indi/src/webcam/v4l1_base.hNNV4L1_Baserunsigned char*getWhitenessb/home/slovin/Projects/indi/src/webcam/v4l1_base.h--V4L1_BaseintgetWidthb/home/slovin/Projects/indi/src/webcam/v4l1_base.h;;V4L1_BaseintgetYb/home/slovin/Projects/indi/src/webcam/v4l1_base.hLLV4L1_Base·UÇunsigned char*initb/home/slovin/Projects/indi/src/webcam/v4l1_base.hEE V4L1_BasepreferedPaletteÿÿÿÿintÿÿÿÿvoidmmapCaptureb/home/slovin/Projects/indi/src/webcam/v4l1_base.hHHV4L1_BasevoidmmapFrameb/home/slovin/Projects/indi/src/webcam/v4l1_base.hKKV4L1_Base"unsigned char*mmapInitb/home/slovin/Projects/indi/src/webcam/v4l1_base.hGGV4L1_BaseintmmapSyncb/home/slovin/Projects/indi/src/webcam/v4l1_base.hIIV4L1_Base €voidnewFrameb/home/slovin/Projects/indi/src/webcam/v4l1_base.h66V4L1_Basevoid registerCallbackb/home/slovin/Projects/indi/src/webcam/v4l1_base.hSS*V4L1_BasefpÿÿÿÿWPF*ÿÿÿÿudÿÿÿÿ void*ÿÿÿÿvoidsetBrightnessb/home/slovin/Projects/indi/src/webcam/v4l1_base.h//V4L1_BaseivalÿÿÿÿintÿÿÿÿvoidsetColorb/home/slovin/Projects/indi/src/webcam/v4l1_base.h00V4L1_BasevalÿÿÿÿintÿÿÿÿvoidsetContrastb/home/slovin/Projects/indi/src/webcam/v4l1_base.h..V4L1_Base *É€valÿÿÿÿintÿÿÿÿvoid setFPSb/home/slovin/Projects/indi/src/webcam/v4l1_base.hBBV4L1_Basefpsÿÿÿÿintÿÿÿÿvoid setHueb/home/slovin/Projects/indi/src/webcam/v4l1_base.h11V4L1_Basevalÿÿÿÿintÿÿÿÿvoid$setPictureSettingsb/home/slovin/Projects/indi/src/webcam/v4l1_base.h77V4L1_Base €voidsetSizeb/home/slovin/Projects/indi/src/webcam/v4l1_base.h>>$V4L1_BasexÿÿÿÿintÿÿÿÿyÿÿÿÿintÿÿÿÿboolsetWhitenessb/home/slovin/Projects/indi/src/webcam/v4l1_base.h22V4L1_Basevalÿÿÿÿintÿÿÿÿvoidstart_capturingb/home/slovin/Projects/indi/src/webcam/v4l1_base.hQQ#V4L1_Base errmsgÿÿÿÿ char*ÿÿÿÿintstop_capturingb/home/slovin/Projects/indi/src/webcam/v4l1_base.hRR"V4L1_Base errmsgÿÿÿÿ char*ÿÿÿÿintupdateFrameb/home/slovin/Projects/indi/src/webcam/v4l1_base.h55*V4L1_Basedÿÿÿÿintÿÿÿÿpÿÿÿÿ void*ÿÿÿÿvoid~ V4L1_Baseb/home/slovin/Projects/indi/src/webcam/v4l1_base.h! !V4L1_BaseÿÿÿÿUBufb/home/slovin/Projects/indi/src/webcam/v4l1_base.hiiunsigned char*VBufb/home/slovin/Projects/indi/src/webcam/v4l1_base.hii"unsigned char*YBufb/home/slovin/Projects/indi/src/webcam/v4l1_base.hiiunsigned char*buffer_startb/home/slovin/Projects/indi/src/webcam/v4l1_base.haaunsigned char*callbackb/home/slovin/Projects/indi/src/webcam/v4l1_base.hXXWPF*capabilityb/home/slovin/Projects/indi/src/webcam/v4l1_base.h\\$.struct video_capabilitycolorBufferb/home/slovin/Projects/indi/src/webcam/v4l1_base.hi$i0unsigned char*fdb/home/slovin/Projects/indi/src/webcam/v4l1_base.hWWintframeRateb/home/slovin/Projects/indi/src/webcam/v4l1_base.hffintmmap_bufferb/home/slovin/Projects/indi/src/webcam/v4l1_base.h__"struct video_mbuf&mmap_capture_bufferb/home/slovin/Projects/indi/src/webcam/v4l1_base.hddlong mmap_sync_bufferb/home/slovin/Projects/indi/src/webcam/v4l1_base.hcclongoptionsb/home/slovin/Projects/indi/src/webcam/v4l1_base.hZZunsigned longpicture_formatb/home/slovin/Projects/indi/src/webcam/v4l1_base.h^^%(struct video_picture selectCallBackIDb/home/slovin/Projects/indi/src/webcam/v4l1_base.hhhintstreamActiveb/home/slovin/Projects/indi/src/webcam/v4l1_base.hggbooluptrb/home/slovin/Projects/indi/src/webcam/v4l1_base.hYY  void* windowb/home/slovin/Projects/indi/src/webcam/v4l1_base.h]]&struct video_window`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.hÿÿÿÿV4L1_PWC`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.hVV4L1_BaseV4L1_PWC`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h V4L1_PWCÿÿÿÿcheckSize`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.hHH!V4L1_PWCxÿÿÿÿint&ÿÿÿÿyÿÿÿÿint&ÿÿÿÿvoidconnectCam`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h" ":V4L1_PWCgdevpathÿÿÿÿconst char*ÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿintgetBackLight`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h22V4L1_PWC boolgetCompression`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h,,V4L1_PWCintgetFlicker`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h44V4L1_PWCboolgetFrameRate`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h88V4L1_PWC <intgetGain`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h))V4L1_PWC intgetGama`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h66V4L1_PWCeintgetNoiseRemoval`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h..V4L1_PWCdintgetSharpness`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h00V4L1_PWCintgetWhiteBalance`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h::V4L1_PWC·UÇint,restoreFactorySettings`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h'' V4L1_PWCvoidrestoreSettings`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h&&V4L1_PWCvoidsaveSettings`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h%%"V4L1_PWC errmsgÿÿÿÿ char*ÿÿÿÿintsetBackLight`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h11,V4L1_PWCovalÿÿÿÿboolÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿintsetCompression`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h++!V4L1_PWC valueÿÿÿÿintÿÿÿÿvoidsetExposure`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h***V4L1_PWC(valÿÿÿÿintÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿintsetFlicker`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h33*V4L1_PWC,valÿÿÿÿboolÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿintsetFrameRate`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h77-V4L1_PWCh valueÿÿÿÿintÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿintsetGain`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h(((V4L1_PWC valueÿÿÿÿintÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿintsetGama`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h55V4L1_PWC (9 valueÿÿÿÿintÿÿÿÿvoidsetNoiseRemoval`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h--0V4L1_PWC valueÿÿÿÿintÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿintsetSharpness`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h//-V4L1_PWC valueÿÿÿÿintÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿintsetSize`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.hIIV4L1_PWCxÿÿÿÿintÿÿÿÿyÿÿÿÿintÿÿÿÿboolsetWhiteBalance`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h99%V4L1_PWC errmsgÿÿÿÿ char*ÿÿÿÿint&setWhiteBalanceBlue`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h==2V4L1_PWCvalÿÿÿÿintÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿint&setWhiteBalanceMode`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h;;2V4L1_PWCvalÿÿÿÿintÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿint$setWhiteBalanceRed`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h<<1V4L1_PWCvalÿÿÿÿintÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿint~ V4L1_PWC`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.h  V4L1_PWC aÿÿÿÿlastGain_`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.hPPintmultiplicateur_`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.hQQintskippedFrame_`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.hRRint type_`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.hSS int"whiteBalanceBlue_`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.hOOint"whiteBalanceMode_`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.hMMint whiteBalanceRed_`/home/slovin/Projects/indi/src/webcam/v4l1_pwc.hNNintb/home/slovin/Projects/indi/src/webcam/v4l2_base.hÿÿÿÿV4L2_Baseb/home/slovin/Projects/indi/src/webcam/v4l2_base.h!Š bufferb/home/slovin/Projects/indi/src/webcam/v4l2_base.h)-V4L2_Base lengthb/home/slovin/Projects/indi/src/webcam/v4l2_base.h, ,& size_t startb/home/slovin/Projects/indi/src/webcam/v4l2_base.h+ +% void*1V4L2_Baseb/home/slovin/Projects/indi/src/webcam/v4l2_base.h$$V4L2_BaseÿÿÿÿallocBuffersb/home/slovin/Projects/indi/src/webcam/v4l2_base.hOOV4L2_BasevoidcallFrameb/home/slovin/Projects/indi/src/webcam/v4l2_base.hAAV4L2_Basepÿÿÿÿ void*ÿÿÿÿvoidclose_deviceb/home/slovin/Projects/indi/src/webcam/v4l2_base.hllV4L2_Base 'kÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidconnectCamb/home/slovin/Projects/indi/src/webcam/v4l2_base.h00tV4L2_Basedevpathÿÿÿÿconst char*ÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿpixelFormatÿÿÿÿintÿÿÿÿ widthÿÿÿÿintÿÿÿÿ heightÿÿÿÿintÿÿÿÿintdisconnectCamb/home/slovin/Projects/indi/src/webcam/v4l2_base.h11V4L2_Base „voidenumerate_ctrlb/home/slovin/Projects/indi/src/webcam/v4l2_base.h[[V4L2_Base€ÿÿÿÿÿÿÿÿvoidÿÿÿÿvoidenumerate_menub/home/slovin/Projects/indi/src/webcam/v4l2_base.h\\V4L2_Base cÿÿÿÿÿÿÿÿvoidÿÿÿÿvoiderrno_exitb/home/slovin/Projects/indi/src/webcam/v4l2_base.hjj-V4L2_Basesÿÿÿÿconst char*ÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿintfindMinMaxb/home/slovin/Projects/indi/src/webcam/v4l2_base.hppV4L2_BasevoidgetBrightnessb/home/slovin/Projects/indi/src/webcam/v4l2_base.h55V4L2_Base •intgetColorb/home/slovin/Projects/indi/src/webcam/v4l2_base.h77V4L2_Base CintgetColorBufferb/home/slovin/Projects/indi/src/webcam/v4l2_base.hSS"V4L2_Baseunsigned char*getContrastb/home/slovin/Projects/indi/src/webcam/v4l2_base.h66V4L2_Base X€intgetDeviceNameb/home/slovin/Projects/indi/src/webcam/v4l2_base.h22V4L2_Base  char* getFPSb/home/slovin/Projects/indi/src/webcam/v4l2_base.hMMV4L2_BasesintgetHeightb/home/slovin/Projects/indi/src/webcam/v4l2_base.hGGV4L2_Baseint getHueb/home/slovin/Projects/indi/src/webcam/v4l2_base.h88V4L2_Base †€intgetMaxMinSizeb/home/slovin/Projects/indi/src/webcam/v4l2_base.hIIPV4L2_Base x_maxÿÿÿÿint&ÿÿÿÿ y_maxÿÿÿÿint&ÿÿÿÿ x_minÿÿÿÿint&ÿÿÿÿ y_minÿÿÿÿint&ÿÿÿÿvoid$getPictureSettingsb/home/slovin/Projects/indi/src/webcam/v4l2_base.hCCV4L2_BasenvoidgetUb/home/slovin/Projects/indi/src/webcam/v4l2_base.hQQV4L2_Baseÿÿÿ€unsigned char*getVb/home/slovin/Projects/indi/src/webcam/v4l2_base.hRRV4L2_Baseunsigned char*getWhitenessb/home/slovin/Projects/indi/src/webcam/v4l2_base.h99V4L2_Base *ointgetWidthb/home/slovin/Projects/indi/src/webcam/v4l2_base.hFFV4L2_Base·UÇintgetYb/home/slovin/Projects/indi/src/webcam/v4l2_base.hPPV4L2_Baseunsigned char*init_deviceb/home/slovin/Projects/indi/src/webcam/v4l2_base.hhhHV4L2_Base errmsgÿÿÿÿ char*ÿÿÿÿpixelFormatÿÿÿÿintÿÿÿÿ widthÿÿÿÿintÿÿÿÿ heightÿÿÿÿintÿÿÿÿintinit_mmapb/home/slovin/Projects/indi/src/webcam/v4l2_base.hiiV4L2_Base·UÇ errmsgÿÿÿÿ char*ÿÿÿÿintinit_readb/home/slovin/Projects/indi/src/webcam/v4l2_base.hnn*V4L2_Base·UÇbuffer_sizeÿÿÿÿunsigned intÿÿÿÿvoidinit_userpb/home/slovin/Projects/indi/src/webcam/v4l2_base.hmm+V4L2_Basebuffer_sizeÿÿÿÿunsigned intÿÿÿÿvoidnewFrameb/home/slovin/Projects/indi/src/webcam/v4l2_base.hYY'V4L2_Base cˆfdÿÿÿÿintÿÿÿÿpÿÿÿÿ void*ÿÿÿÿvoidopen_deviceb/home/slovin/Projects/indi/src/webcam/v4l2_base.hgg4V4L2_Basedevpathÿÿÿÿconst char*ÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿint queryINTControlsb/home/slovin/Projects/indi/src/webcam/v4l2_base.h]]3V4L2_Basenvpÿÿÿÿ,INumberVectorProperty*ÿÿÿÿintquery_ctrlb/home/slovin/Projects/indi/src/webcam/v4l2_base.h``„V4L2_Base·UÇctrl_idÿÿÿÿunsigned intÿÿÿÿctrl_minÿÿÿÿdouble&ÿÿÿÿctrl_maxÿÿÿÿdouble&ÿÿÿÿctrl_stepÿÿÿÿdouble&ÿÿÿÿctrl_valueÿÿÿÿdouble&ÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿintread_frameb/home/slovin/Projects/indi/src/webcam/v4l2_base.heeV4L2_Base ‹ errsgÿÿÿÿ char*ÿÿÿÿint registerCallbackb/home/slovin/Projects/indi/src/webcam/v4l2_base.hUU*V4L2_BasefpÿÿÿÿWPF*ÿÿÿÿudÿÿÿÿ void*ÿÿÿÿvoidsetBrightnessb/home/slovin/Projects/indi/src/webcam/v4l2_base.h;;V4L2_Base (B€valÿÿÿÿintÿÿÿÿvoidsetColorb/home/slovin/Projects/indi/src/webcam/v4l2_base.h<<V4L2_BasevalÿÿÿÿintÿÿÿÿvoidsetContrastb/home/slovin/Projects/indi/src/webcam/v4l2_base.h::V4L2_Base  €valÿÿÿÿintÿÿÿÿvoid setFPSb/home/slovin/Projects/indi/src/webcam/v4l2_base.hLLV4L2_Basefpsÿÿÿÿintÿÿÿÿvoid setHueb/home/slovin/Projects/indi/src/webcam/v4l2_base.h==V4L2_BasevalÿÿÿÿintÿÿÿÿvoidsetINTControlb/home/slovin/Projects/indi/src/webcam/v4l2_base.h^^JV4L2_Basectrl_idÿÿÿÿunsigned intÿÿÿÿnew_valueÿÿÿÿ doubleÿÿÿÿ errmsgÿÿÿÿ char*ÿÿÿÿint$setPictureSettingsb/home/slovin/Projects/indi/src/webcam/v4l2_base.hBBV4L2_Baseüü€voidsetSizeb/home/slovin/Projects/indi/src/webcam/v4l2_base.hHH#V4L2_Base„xÿÿÿÿintÿÿÿÿyÿÿÿÿintÿÿÿÿintsetWhitenessb/home/slovin/Projects/indi/src/webcam/v4l2_base.h>>V4L2_Base &¶valÿÿÿÿintÿÿÿÿvoidstart_capturingb/home/slovin/Projects/indi/src/webcam/v4l2_base.hWW#V4L2_Base [ errmsgÿÿÿÿ char*ÿÿÿÿintstop_capturingb/home/slovin/Projects/indi/src/webcam/v4l2_base.hXX"V4L2_Base b€ errmsgÿÿÿÿ char*ÿÿÿÿintuninit_deviceb/home/slovin/Projects/indi/src/webcam/v4l2_base.hff!V4L2_Base errmsgÿÿÿÿ char*ÿÿÿÿint xioctlb/home/slovin/Projects/indi/src/webcam/v4l2_base.hdd,V4L2_Base€fdÿÿÿÿintÿÿÿÿrequestÿÿÿÿintÿÿÿÿargÿÿÿÿ void*ÿÿÿÿint~ V4L2_Baseb/home/slovin/Projects/indi/src/webcam/v4l2_base.h% %V4L2_Baseî?ÿÿÿÿUBufb/home/slovin/Projects/indi/src/webcam/v4l2_base.hˆˆunsigned char*VBufb/home/slovin/Projects/indi/src/webcam/v4l2_base.hˆˆ"unsigned char*YBufb/home/slovin/Projects/indi/src/webcam/v4l2_base.hˆˆunsigned char*buffersb/home/slovin/Projects/indi/src/webcam/v4l2_base.hstruct buffer*callbackb/home/slovin/Projects/indi/src/webcam/v4l2_base.hzzWPF*capb/home/slovin/Projects/indi/src/webcam/v4l2_base.hrr,struct v4l2_capabilitycolorBufferb/home/slovin/Projects/indi/src/webcam/v4l2_base.hˆ$ˆ0unsigned char*cropb/home/slovin/Projects/indi/src/webcam/v4l2_base.htt struct v4l2_cropcropcapb/home/slovin/Projects/indi/src/webcam/v4l2_base.hss&struct v4l2_cropcapdev_nameb/home/slovin/Projects/indi/src/webcam/v4l2_base.h||chardropFrameb/home/slovin/Projects/indi/src/webcam/v4l2_base.h‚‚boolfdb/home/slovin/Projects/indi/src/webcam/v4l2_base.h~~intfmtb/home/slovin/Projects/indi/src/webcam/v4l2_base.huu$struct v4l2_formatframeRateb/home/slovin/Projects/indi/src/webcam/v4l2_base.h……intiob/home/slovin/Projects/indi/src/webcam/v4l2_base.h} }io_methodn_buffersb/home/slovin/Projects/indi/src/webcam/v4l2_base.h€€unsigned intqueryctrlb/home/slovin/Projects/indi/src/webcam/v4l2_base.hww!*struct v4l2_queryctrlquerymenub/home/slovin/Projects/indi/src/webcam/v4l2_base.hxx!*struct v4l2_querymenurgb24_bufferb/home/slovin/Projects/indi/src/webcam/v4l2_base.hˆ2ˆ?unsigned char* selectCallBackIDb/home/slovin/Projects/indi/src/webcam/v4l2_base.h‡‡intuptrb/home/slovin/Projects/indi/src/webcam/v4l2_base.h{{  void*xmaxb/home/slovin/Projects/indi/src/webcam/v4l2_base.h†† intxminb/home/slovin/Projects/indi/src/webcam/v4l2_base.h† †intymaxb/home/slovin/Projects/indi/src/webcam/v4l2_base.h††intyminb/home/slovin/Projects/indi/src/webcam/v4l2_base.h††int io_methodb/home/slovin/Projects/indi/src/webcam/v4l2_base.h'F'OÿÿÿÿX/home/slovin/Projects/indi/src/webcam/vcvt.hÿÿÿÿ`/home/slovin/Projects/indi/src/webcam/videodev.hÿÿÿÿvbi_format`/home/slovin/Projects/indi/src/webcam/videodev.hÕÞ count`/home/slovin/Projects/indi/src/webcam/videodev.hÚÚunsigned int flags`/home/slovin/Projects/indi/src/webcam/videodev.hÛÛunsigned intsample_format`/home/slovin/Projects/indi/src/webcam/videodev.hØØunsigned int samples_per_line`/home/slovin/Projects/indi/src/webcam/videodev.h××unsigned intsampling_rate`/home/slovin/Projects/indi/src/webcam/videodev.hÖÖunsigned int start`/home/slovin/Projects/indi/src/webcam/videodev.hÙÙ intvideo_audio`/home/slovin/Projects/indi/src/webcam/videodev.hs‡  audio`/home/slovin/Projects/indi/src/webcam/videodev.huu intbalance`/home/slovin/Projects/indi/src/webcam/videodev.h……unsigned shortbass`/home/slovin/Projects/indi/src/webcam/videodev.hwwunsigned short flags`/home/slovin/Projects/indi/src/webcam/videodev.hxxunsigned intmode`/home/slovin/Projects/indi/src/webcam/videodev.h„„unsigned shortname`/home/slovin/Projects/indi/src/webcam/videodev.h charstep`/home/slovin/Projects/indi/src/webcam/videodev.h††unsigned short treble`/home/slovin/Projects/indi/src/webcam/videodev.hwwunsigned short volume`/home/slovin/Projects/indi/src/webcam/videodev.hvvunsigned shortvideo_buffer`/home/slovin/Projects/indi/src/webcam/videodev.h©¯base`/home/slovin/Projects/indi/src/webcam/videodev.h«« void*bytesperline`/home/slovin/Projects/indi/src/webcam/videodev.h®®int depth`/home/slovin/Projects/indi/src/webcam/videodev.h­­ int height`/home/slovin/Projects/indi/src/webcam/videodev.h¬¬ int width`/home/slovin/Projects/indi/src/webcam/videodev.h¬ ¬int video_capability`/home/slovin/Projects/indi/src/webcam/videodev.h%/ audios`/home/slovin/Projects/indi/src/webcam/videodev.h** intchannels`/home/slovin/Projects/indi/src/webcam/videodev.h)) intmaxheight`/home/slovin/Projects/indi/src/webcam/videodev.h,,intmaxwidth`/home/slovin/Projects/indi/src/webcam/videodev.h++ intminheight`/home/slovin/Projects/indi/src/webcam/videodev.h..intminwidth`/home/slovin/Projects/indi/src/webcam/videodev.h-- intname`/home/slovin/Projects/indi/src/webcam/videodev.h''chartype`/home/slovin/Projects/indi/src/webcam/videodev.h(( intvideo_capture`/home/slovin/Projects/indi/src/webcam/videodev.hŸ§decimation`/home/slovin/Projects/indi/src/webcam/videodev.h££unsigned short flags`/home/slovin/Projects/indi/src/webcam/videodev.h¤¤unsigned short height`/home/slovin/Projects/indi/src/webcam/videodev.h¢¢unsigned int width`/home/slovin/Projects/indi/src/webcam/videodev.h¢¢unsigned intx`/home/slovin/Projects/indi/src/webcam/videodev.h¡¡unsigned inty`/home/slovin/Projects/indi/src/webcam/videodev.h¡¡unsigned intvideo_channel`/home/slovin/Projects/indi/src/webcam/videodev.h2>channel`/home/slovin/Projects/indi/src/webcam/videodev.h44 int flags`/home/slovin/Projects/indi/src/webcam/videodev.h77unsigned intname`/home/slovin/Projects/indi/src/webcam/videodev.h55charnorm`/home/slovin/Projects/indi/src/webcam/videodev.h==unsigned short tuners`/home/slovin/Projects/indi/src/webcam/videodev.h66 inttype`/home/slovin/Projects/indi/src/webcam/videodev.h::unsigned shortvideo_clip`/home/slovin/Projects/indi/src/webcam/videodev.h‰Ž height`/home/slovin/Projects/indi/src/webcam/videodev.hŒ Œintnext`/home/slovin/Projects/indi/src/webcam/videodev.h$struct video_clip* width`/home/slovin/Projects/indi/src/webcam/videodev.hŒŒ intx`/home/slovin/Projects/indi/src/webcam/videodev.h‹‹inty`/home/slovin/Projects/indi/src/webcam/videodev.h‹‹intvideo_code`/home/slovin/Projects/indi/src/webcam/videodev.h÷üdata`/home/slovin/Projects/indi/src/webcam/videodev.hûûunsigned char*datasize`/home/slovin/Projects/indi/src/webcam/videodev.húú intloadwhat`/home/slovin/Projects/indi/src/webcam/videodev.hùùcharvideo_info`/home/slovin/Projects/indi/src/webcam/videodev.hâìframe_count`/home/slovin/Projects/indi/src/webcam/videodev.hääunsigned int h_size`/home/slovin/Projects/indi/src/webcam/videodev.hååunsigned intpicture_type`/home/slovin/Projects/indi/src/webcam/videodev.hèèunsigned intsmpte_timecode`/home/slovin/Projects/indi/src/webcam/videodev.hççunsigned int$temporal_reference`/home/slovin/Projects/indi/src/webcam/videodev.héé unsigned intuser_data`/home/slovin/Projects/indi/src/webcam/videodev.hêêunsigned char v_size`/home/slovin/Projects/indi/src/webcam/videodev.hææunsigned intvideo_key`/home/slovin/Projects/indi/src/webcam/videodev.h¸¼ flags`/home/slovin/Projects/indi/src/webcam/videodev.h»»unsigned intkey`/home/slovin/Projects/indi/src/webcam/videodev.hººunsigned charvideo_mbuf`/home/slovin/Projects/indi/src/webcam/videodev.hÁÆ frames`/home/slovin/Projects/indi/src/webcam/videodev.hÄÄ intoffsets`/home/slovin/Projects/indi/src/webcam/videodev.hÅÅ intsize`/home/slovin/Projects/indi/src/webcam/videodev.hÃà intvideo_mmap`/home/slovin/Projects/indi/src/webcam/videodev.h±¶ format`/home/slovin/Projects/indi/src/webcam/videodev.hµµunsigned int frame`/home/slovin/Projects/indi/src/webcam/videodev.h³³unsigned int height`/home/slovin/Projects/indi/src/webcam/videodev.h´´ int width`/home/slovin/Projects/indi/src/webcam/videodev.h´ ´intvideo_picture`/home/slovin/Projects/indi/src/webcam/videodev.hVqbrightness`/home/slovin/Projects/indi/src/webcam/videodev.hXXunsigned short colour`/home/slovin/Projects/indi/src/webcam/videodev.hZZunsigned shortcontrast`/home/slovin/Projects/indi/src/webcam/videodev.h[[unsigned short depth`/home/slovin/Projects/indi/src/webcam/videodev.h]]unsigned shorthue`/home/slovin/Projects/indi/src/webcam/videodev.hYYunsigned shortpalette`/home/slovin/Projects/indi/src/webcam/videodev.h^^unsigned shortwhiteness`/home/slovin/Projects/indi/src/webcam/videodev.h\\unsigned shortvideo_play_mode`/home/slovin/Projects/indi/src/webcam/videodev.hïômode`/home/slovin/Projects/indi/src/webcam/videodev.hññ intp1`/home/slovin/Projects/indi/src/webcam/videodev.hòòintp2`/home/slovin/Projects/indi/src/webcam/videodev.hóóintvideo_tuner`/home/slovin/Projects/indi/src/webcam/videodev.h@T flags`/home/slovin/Projects/indi/src/webcam/videodev.hEEunsigned intmode`/home/slovin/Projects/indi/src/webcam/videodev.hNNunsigned shortname`/home/slovin/Projects/indi/src/webcam/videodev.hCCcharrangehigh`/home/slovin/Projects/indi/src/webcam/videodev.hDD"unsigned longrangelow`/home/slovin/Projects/indi/src/webcam/videodev.hDDunsigned long signal`/home/slovin/Projects/indi/src/webcam/videodev.hSSunsigned short tuner`/home/slovin/Projects/indi/src/webcam/videodev.hBB intvideo_unit`/home/slovin/Projects/indi/src/webcam/videodev.hÌÓ audio`/home/slovin/Projects/indi/src/webcam/videodev.hÑÑ int radio`/home/slovin/Projects/indi/src/webcam/videodev.hÐÐ intteletext`/home/slovin/Projects/indi/src/webcam/videodev.hÒÒ intvbi`/home/slovin/Projects/indi/src/webcam/videodev.hÏÏint video`/home/slovin/Projects/indi/src/webcam/videodev.hÎÎ intvideo_window`/home/slovin/Projects/indi/src/webcam/videodev.hchromakey`/home/slovin/Projects/indi/src/webcam/videodev.h””unsigned intclipcount`/home/slovin/Projects/indi/src/webcam/videodev.h——int clips`/home/slovin/Projects/indi/src/webcam/videodev.h––$struct video_clip* flags`/home/slovin/Projects/indi/src/webcam/videodev.h••unsigned int height`/home/slovin/Projects/indi/src/webcam/videodev.h““unsigned int width`/home/slovin/Projects/indi/src/webcam/videodev.h““unsigned intx`/home/slovin/Projects/indi/src/webcam/videodev.h’’unsigned inty`/home/slovin/Projects/indi/src/webcam/videodev.h’’unsigned intb/home/slovin/Projects/indi/src/webcam/videodev2.hÿÿÿÿv4l2_audiob/home/slovin/Projects/indi/src/webcam/videodev2.hcapabilityb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned int indexb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned intmodeb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned intnameb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned charreservedb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned intv4l2_audiooutb/home/slovin/Projects/indi/src/webcam/videodev2.hcapabilityb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned int indexb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned intmodeb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned intnameb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned charreservedb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned intv4l2_bufferb/home/slovin/Projects/indi/src/webcam/videodev2.h„˜(videodev2_0)b/home/slovin/Projects/indi/src/webcam/videodev2.h‘”v4l2_buffer offsetb/home/slovin/Projects/indi/src/webcam/videodev2.h’’unsigned intuserptrb/home/slovin/Projects/indi/src/webcam/videodev2.h““unsigned long bytesusedb/home/slovin/Projects/indi/src/webcam/videodev2.hˆˆunsigned int fieldb/home/slovin/Projects/indi/src/webcam/videodev2.hŠŠenum v4l2_field flagsb/home/slovin/Projects/indi/src/webcam/videodev2.h‰‰unsigned int indexb/home/slovin/Projects/indi/src/webcam/videodev2.h††unsigned int inputb/home/slovin/Projects/indi/src/webcam/videodev2.h––unsigned int lengthb/home/slovin/Projects/indi/src/webcam/videodev2.h••unsigned intmb/home/slovin/Projects/indi/src/webcam/videodev2.h””ÿÿÿÿ memoryb/home/slovin/Projects/indi/src/webcam/videodev2.h enum v4l2_memoryreservedb/home/slovin/Projects/indi/src/webcam/videodev2.h——unsigned intsequenceb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned inttimecodeb/home/slovin/Projects/indi/src/webcam/videodev2.hŒŒ(struct v4l2_timecodetimestampb/home/slovin/Projects/indi/src/webcam/videodev2.h‹‹struct timevaltypeb/home/slovin/Projects/indi/src/webcam/videodev2.h‡‡$enum v4l2_buf_typev4l2_capabilityb/home/slovin/Projects/indi/src/webcam/videodev2.h™¡bus_infob/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned charcapabilitiesb/home/slovin/Projects/indi/src/webcam/videodev2.hŸŸunsigned intcardb/home/slovin/Projects/indi/src/webcam/videodev2.hœœunsigned char driverb/home/slovin/Projects/indi/src/webcam/videodev2.h››unsigned charreservedb/home/slovin/Projects/indi/src/webcam/videodev2.h  unsigned intversionb/home/slovin/Projects/indi/src/webcam/videodev2.hžžunsigned int v4l2_captureparmb/home/slovin/Projects/indi/src/webcam/videodev2.hÎÖcapabilityb/home/slovin/Projects/indi/src/webcam/videodev2.hÐÐunsigned intcapturemodeb/home/slovin/Projects/indi/src/webcam/videodev2.hÑÑunsigned intextendedmodeb/home/slovin/Projects/indi/src/webcam/videodev2.hÓÓunsigned intreadbuffersb/home/slovin/Projects/indi/src/webcam/videodev2.hÔÔ&unsigned intreservedb/home/slovin/Projects/indi/src/webcam/videodev2.hÕÕunsigned inttimeperframeb/home/slovin/Projects/indi/src/webcam/videodev2.hÒÒ "struct v4l2_fractv4l2_clipb/home/slovin/Projects/indi/src/webcam/videodev2.hº¾cb/home/slovin/Projects/indi/src/webcam/videodev2.h¼¼ struct v4l2_rectnextb/home/slovin/Projects/indi/src/webcam/videodev2.h½½"struct v4l2_clip*v4l2_controlb/home/slovin/Projects/indi/src/webcam/videodev2.h‚†idb/home/slovin/Projects/indi/src/webcam/videodev2.h„„unsigned int valueb/home/slovin/Projects/indi/src/webcam/videodev2.h… …intv4l2_cropb/home/slovin/Projects/indi/src/webcam/videodev2.hðócb/home/slovin/Projects/indi/src/webcam/videodev2.hòò struct v4l2_recttypeb/home/slovin/Projects/indi/src/webcam/videodev2.hññ$enum v4l2_buf_typev4l2_cropcapb/home/slovin/Projects/indi/src/webcam/videodev2.héî boundsb/home/slovin/Projects/indi/src/webcam/videodev2.hë ë& struct v4l2_rectdefrectb/home/slovin/Projects/indi/src/webcam/videodev2.hì ì' struct v4l2_rectpixelaspectb/home/slovin/Projects/indi/src/webcam/videodev2.hí í+"struct v4l2_fracttypeb/home/slovin/Projects/indi/src/webcam/videodev2.hêê$enum v4l2_buf_typev4l2_fmtdescb/home/slovin/Projects/indi/src/webcam/videodev2.hòúdescriptionb/home/slovin/Projects/indi/src/webcam/videodev2.h÷÷*unsigned char flagsb/home/slovin/Projects/indi/src/webcam/videodev2.höö!unsigned int indexb/home/slovin/Projects/indi/src/webcam/videodev2.hôôunsigned intpixelformatb/home/slovin/Projects/indi/src/webcam/videodev2.høø%unsigned intreservedb/home/slovin/Projects/indi/src/webcam/videodev2.hùù%unsigned inttypeb/home/slovin/Projects/indi/src/webcam/videodev2.hõõ$enum v4l2_buf_typev4l2_formatb/home/slovin/Projects/indi/src/webcam/videodev2.h5?(videodev2_1)b/home/slovin/Projects/indi/src/webcam/videodev2.h8>v4l2_formatpixb/home/slovin/Projects/indi/src/webcam/videodev2.h::,struct v4l2_pix_formatraw_datab/home/slovin/Projects/indi/src/webcam/videodev2.h==unsigned charvbib/home/slovin/Projects/indi/src/webcam/videodev2.h<<,struct v4l2_vbi_formatwinb/home/slovin/Projects/indi/src/webcam/videodev2.h;;$struct v4l2_windowfmtb/home/slovin/Projects/indi/src/webcam/videodev2.h>>ÿÿÿÿtypeb/home/slovin/Projects/indi/src/webcam/videodev2.h77$enum v4l2_buf_typev4l2_fractb/home/slovin/Projects/indi/src/webcam/videodev2.h‘”denominatorb/home/slovin/Projects/indi/src/webcam/videodev2.h““unsigned intnumeratorb/home/slovin/Projects/indi/src/webcam/videodev2.h’’unsigned int v4l2_framebufferb/home/slovin/Projects/indi/src/webcam/videodev2.h§¯baseb/home/slovin/Projects/indi/src/webcam/videodev2.h­­ void*capabilityb/home/slovin/Projects/indi/src/webcam/videodev2.h©©unsigned int flagsb/home/slovin/Projects/indi/src/webcam/videodev2.hªªunsigned intfmtb/home/slovin/Projects/indi/src/webcam/videodev2.h®®,struct v4l2_pix_formatv4l2_frequencyb/home/slovin/Projects/indi/src/webcam/videodev2.hõûfrequencyb/home/slovin/Projects/indi/src/webcam/videodev2.hù#ù,unsigned intreservedb/home/slovin/Projects/indi/src/webcam/videodev2.húú'unsigned int tunerb/home/slovin/Projects/indi/src/webcam/videodev2.h÷÷!unsigned inttypeb/home/slovin/Projects/indi/src/webcam/videodev2.høø(enum v4l2_tuner_typev4l2_inputb/home/slovin/Projects/indi/src/webcam/videodev2.hKUaudiosetb/home/slovin/Projects/indi/src/webcam/videodev2.hPPunsigned int indexb/home/slovin/Projects/indi/src/webcam/videodev2.hMMunsigned intnameb/home/slovin/Projects/indi/src/webcam/videodev2.hNNunsigned charreservedb/home/slovin/Projects/indi/src/webcam/videodev2.hTTunsigned int statusb/home/slovin/Projects/indi/src/webcam/videodev2.hSSunsigned intstdb/home/slovin/Projects/indi/src/webcam/videodev2.hRRv4l2_std_id tunerb/home/slovin/Projects/indi/src/webcam/videodev2.hQQunsigned inttypeb/home/slovin/Projects/indi/src/webcam/videodev2.hOOunsigned int(v4l2_jpegcompressionb/home/slovin/Projects/indi/src/webcam/videodev2.hZvAPP_datab/home/slovin/Projects/indi/src/webcam/videodev2.haacharAPP_lenb/home/slovin/Projects/indi/src/webcam/videodev2.h`` intAPPnb/home/slovin/Projects/indi/src/webcam/videodev2.h^^ intCOM_datab/home/slovin/Projects/indi/src/webcam/videodev2.hddcharCOM_lenb/home/slovin/Projects/indi/src/webcam/videodev2.hcc intjpeg_markersb/home/slovin/Projects/indi/src/webcam/videodev2.hffunsigned intqualityb/home/slovin/Projects/indi/src/webcam/videodev2.h\\ intv4l2_modulatorb/home/slovin/Projects/indi/src/webcam/videodev2.hÔÝcapabilityb/home/slovin/Projects/indi/src/webcam/videodev2.hØØunsigned int indexb/home/slovin/Projects/indi/src/webcam/videodev2.hÖÖunsigned intnameb/home/slovin/Projects/indi/src/webcam/videodev2.h××unsigned charrangehighb/home/slovin/Projects/indi/src/webcam/videodev2.hÚÚunsigned intrangelowb/home/slovin/Projects/indi/src/webcam/videodev2.hÙÙunsigned intreservedb/home/slovin/Projects/indi/src/webcam/videodev2.hÜÜunsigned inttxsubchansb/home/slovin/Projects/indi/src/webcam/videodev2.hÛÛunsigned intv4l2_outputb/home/slovin/Projects/indi/src/webcam/videodev2.hpyaudiosetb/home/slovin/Projects/indi/src/webcam/videodev2.huuunsigned int indexb/home/slovin/Projects/indi/src/webcam/videodev2.hrrunsigned intmodulatorb/home/slovin/Projects/indi/src/webcam/videodev2.hvvunsigned intnameb/home/slovin/Projects/indi/src/webcam/videodev2.hssunsigned charreservedb/home/slovin/Projects/indi/src/webcam/videodev2.hxxunsigned intstdb/home/slovin/Projects/indi/src/webcam/videodev2.hwwv4l2_std_idtypeb/home/slovin/Projects/indi/src/webcam/videodev2.httunsigned intv4l2_outputparmb/home/slovin/Projects/indi/src/webcam/videodev2.hÛãcapabilityb/home/slovin/Projects/indi/src/webcam/videodev2.hÝÝunsigned intextendedmodeb/home/slovin/Projects/indi/src/webcam/videodev2.hààunsigned intoutputmodeb/home/slovin/Projects/indi/src/webcam/videodev2.hÞÞunsigned intreservedb/home/slovin/Projects/indi/src/webcam/videodev2.hââunsigned inttimeperframeb/home/slovin/Projects/indi/src/webcam/videodev2.hßß "struct v4l2_fractwritebuffersb/home/slovin/Projects/indi/src/webcam/videodev2.háá'unsigned intv4l2_pix_formatb/home/slovin/Projects/indi/src/webcam/videodev2.h·Ábytesperlineb/home/slovin/Projects/indi/src/webcam/videodev2.h½½&unsigned intcolorspaceb/home/slovin/Projects/indi/src/webcam/videodev2.h¿¿'(enum v4l2_colorspace fieldb/home/slovin/Projects/indi/src/webcam/videodev2.h¼¼enum v4l2_field heightb/home/slovin/Projects/indi/src/webcam/videodev2.hººunsigned intpixelformatb/home/slovin/Projects/indi/src/webcam/videodev2.h»»#unsigned intprivb/home/slovin/Projects/indi/src/webcam/videodev2.hÀÀunsigned intsizeimageb/home/slovin/Projects/indi/src/webcam/videodev2.h¾¾#unsigned int widthb/home/slovin/Projects/indi/src/webcam/videodev2.h¹¹unsigned intv4l2_queryctrlb/home/slovin/Projects/indi/src/webcam/videodev2.h‰” default_valueb/home/slovin/Projects/indi/src/webcam/videodev2.h‘ ‘int flagsb/home/slovin/Projects/indi/src/webcam/videodev2.h’’"unsigned intidb/home/slovin/Projects/indi/src/webcam/videodev2.h‹‹unsigned intmaximumb/home/slovin/Projects/indi/src/webcam/videodev2.h intminimumb/home/slovin/Projects/indi/src/webcam/videodev2.hŽ Žintnameb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned charreservedb/home/slovin/Projects/indi/src/webcam/videodev2.h““unsigned intstepb/home/slovin/Projects/indi/src/webcam/videodev2.hinttypeb/home/slovin/Projects/indi/src/webcam/videodev2.hŒŒ&enum v4l2_ctrl_typev4l2_querymenub/home/slovin/Projects/indi/src/webcam/videodev2.h—idb/home/slovin/Projects/indi/src/webcam/videodev2.h™™unsigned int indexb/home/slovin/Projects/indi/src/webcam/videodev2.hššunsigned intnameb/home/slovin/Projects/indi/src/webcam/videodev2.h››unsigned charreservedb/home/slovin/Projects/indi/src/webcam/videodev2.hœœunsigned intv4l2_rectb/home/slovin/Projects/indi/src/webcam/videodev2.hŠ heightb/home/slovin/Projects/indi/src/webcam/videodev2.hŽŽ intleftb/home/slovin/Projects/indi/src/webcam/videodev2.h‹‹ inttopb/home/slovin/Projects/indi/src/webcam/videodev2.hŒŒ int widthb/home/slovin/Projects/indi/src/webcam/videodev2.h int&v4l2_requestbuffersb/home/slovin/Projects/indi/src/webcam/videodev2.h|‚ countb/home/slovin/Projects/indi/src/webcam/videodev2.h~~#unsigned int memoryb/home/slovin/Projects/indi/src/webcam/videodev2.h€€ enum v4l2_memoryreservedb/home/slovin/Projects/indi/src/webcam/videodev2.h)unsigned inttypeb/home/slovin/Projects/indi/src/webcam/videodev2.h$enum v4l2_buf_typev4l2_standardb/home/slovin/Projects/indi/src/webcam/videodev2.h=Eframelinesb/home/slovin/Projects/indi/src/webcam/videodev2.hCCunsigned intframeperiodb/home/slovin/Projects/indi/src/webcam/videodev2.hBB!"struct v4l2_fractidb/home/slovin/Projects/indi/src/webcam/videodev2.h@@v4l2_std_id indexb/home/slovin/Projects/indi/src/webcam/videodev2.h?? unsigned intnameb/home/slovin/Projects/indi/src/webcam/videodev2.hAAunsigned charreservedb/home/slovin/Projects/indi/src/webcam/videodev2.hDDunsigned intv4l2_streamparmb/home/slovin/Projects/indi/src/webcam/videodev2.hDM(videodev2_2)b/home/slovin/Projects/indi/src/webcam/videodev2.hGLv4l2_streamparmcaptureb/home/slovin/Projects/indi/src/webcam/videodev2.hII!.struct v4l2_captureparm outputb/home/slovin/Projects/indi/src/webcam/videodev2.hJJ,struct v4l2_outputparmraw_datab/home/slovin/Projects/indi/src/webcam/videodev2.hKKunsigned charparmb/home/slovin/Projects/indi/src/webcam/videodev2.hLLÿÿÿÿtypeb/home/slovin/Projects/indi/src/webcam/videodev2.hFF$enum v4l2_buf_typev4l2_timecodeb/home/slovin/Projects/indi/src/webcam/videodev2.h  flagsb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned int framesb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned char hoursb/home/slovin/Projects/indi/src/webcam/videodev2.h  unsigned charminutesb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned charsecondsb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned chartypeb/home/slovin/Projects/indi/src/webcam/videodev2.hunsigned intuserbitsb/home/slovin/Projects/indi/src/webcam/videodev2.h  unsigned charv4l2_tunerb/home/slovin/Projects/indi/src/webcam/videodev2.hÅÒ afcb/home/slovin/Projects/indi/src/webcam/videodev2.hÐÐ intaudmodeb/home/slovin/Projects/indi/src/webcam/videodev2.hÎÎunsigned intcapabilityb/home/slovin/Projects/indi/src/webcam/videodev2.hÊÊunsigned int indexb/home/slovin/Projects/indi/src/webcam/videodev2.hÇ Ç%unsigned intnameb/home/slovin/Projects/indi/src/webcam/videodev2.hÈÈunsigned charrangehighb/home/slovin/Projects/indi/src/webcam/videodev2.hÌÌunsigned intrangelowb/home/slovin/Projects/indi/src/webcam/videodev2.hËËunsigned intreservedb/home/slovin/Projects/indi/src/webcam/videodev2.hÑÑunsigned intrxsubchansb/home/slovin/Projects/indi/src/webcam/videodev2.hÍÍunsigned int signalb/home/slovin/Projects/indi/src/webcam/videodev2.hÏÏ inttypeb/home/slovin/Projects/indi/src/webcam/videodev2.hÉÉ(enum v4l2_tuner_typev4l2_vbi_formatb/home/slovin/Projects/indi/src/webcam/videodev2.h( countb/home/slovin/Projects/indi/src/webcam/videodev2.h%%unsigned int flagsb/home/slovin/Projects/indi/src/webcam/videodev2.h&&unsigned int offsetb/home/slovin/Projects/indi/src/webcam/videodev2.h!!unsigned intreservedb/home/slovin/Projects/indi/src/webcam/videodev2.h''unsigned intsample_formatb/home/slovin/Projects/indi/src/webcam/videodev2.h##unsigned int samples_per_lineb/home/slovin/Projects/indi/src/webcam/videodev2.h""unsigned intsampling_rateb/home/slovin/Projects/indi/src/webcam/videodev2.h  unsigned int startb/home/slovin/Projects/indi/src/webcam/videodev2.h$$ intv4l2_windowb/home/slovin/Projects/indi/src/webcam/videodev2.hÀÈ bitmapb/home/slovin/Projects/indi/src/webcam/videodev2.hÇÇ void*chromakeyb/home/slovin/Projects/indi/src/webcam/videodev2.hÄÄunsigned intclipcountb/home/slovin/Projects/indi/src/webcam/videodev2.hÆÆunsigned int clipsb/home/slovin/Projects/indi/src/webcam/videodev2.hÅÅ"struct v4l2_clip* fieldb/home/slovin/Projects/indi/src/webcam/videodev2.hÃÃenum v4l2_fieldwb/home/slovin/Projects/indi/src/webcam/videodev2.h struct v4l2_rect$*V4L2_BUF_TYPE_PRIVATEb/home/slovin/Projects/indi/src/webcam/videodev2.hQQ$int2V4L2_BUF_TYPE_VBI_CAPTUREb/home/slovin/Projects/indi/src/webcam/videodev2.hOO!int0V4L2_BUF_TYPE_VBI_OUTPUTb/home/slovin/Projects/indi/src/webcam/videodev2.hPP!int6V4L2_BUF_TYPE_VIDEO_CAPTUREb/home/slovin/Projects/indi/src/webcam/videodev2.hLL!int4V4L2_BUF_TYPE_VIDEO_OUTPUTb/home/slovin/Projects/indi/src/webcam/videodev2.hMM!int6V4L2_BUF_TYPE_VIDEO_OVERLAYb/home/slovin/Projects/indi/src/webcam/videodev2.hNN!int:V4L2_COLORSPACE_470_SYSTEM_BGb/home/slovin/Projects/indi/src/webcam/videodev2.hvv"int8V4L2_COLORSPACE_470_SYSTEM_Mb/home/slovin/Projects/indi/src/webcam/videodev2.huu"int*V4L2_COLORSPACE_BT878b/home/slovin/Projects/indi/src/webcam/videodev2.hrr"int(V4L2_COLORSPACE_JPEGb/home/slovin/Projects/indi/src/webcam/videodev2.h||"int,V4L2_COLORSPACE_REC709b/home/slovin/Projects/indi/src/webcam/videodev2.hoo"int2V4L2_COLORSPACE_SMPTE170Mb/home/slovin/Projects/indi/src/webcam/videodev2.hii"int2V4L2_COLORSPACE_SMPTE240Mb/home/slovin/Projects/indi/src/webcam/videodev2.hll"int(V4L2_COLORSPACE_SRGBb/home/slovin/Projects/indi/src/webcam/videodev2.h"int,V4L2_CTRL_TYPE_BOOLEANb/home/slovin/Projects/indi/src/webcam/videodev2.hVV int*V4L2_CTRL_TYPE_BUTTONb/home/slovin/Projects/indi/src/webcam/videodev2.hXXint,V4L2_CTRL_TYPE_INTEGERb/home/slovin/Projects/indi/src/webcam/videodev2.hUU int&V4L2_CTRL_TYPE_MENUb/home/slovin/Projects/indi/src/webcam/videodev2.hWWint(V4L2_FIELD_ALTERNATEb/home/slovin/Projects/indi/src/webcam/videodev2.h99intV4L2_FIELD_ANYb/home/slovin/Projects/indi/src/webcam/videodev2.h..int"V4L2_FIELD_BOTTOMb/home/slovin/Projects/indi/src/webcam/videodev2.h44int*V4L2_FIELD_INTERLACEDb/home/slovin/Projects/indi/src/webcam/videodev2.h55intV4L2_FIELD_NONEb/home/slovin/Projects/indi/src/webcam/videodev2.h22int"V4L2_FIELD_SEQ_BTb/home/slovin/Projects/indi/src/webcam/videodev2.h88int"V4L2_FIELD_SEQ_TBb/home/slovin/Projects/indi/src/webcam/videodev2.h66intV4L2_FIELD_TOPb/home/slovin/Projects/indi/src/webcam/videodev2.h33int V4L2_MEMORY_MMAPb/home/slovin/Projects/indi/src/webcam/videodev2.haa!int&V4L2_MEMORY_OVERLAYb/home/slovin/Projects/indi/src/webcam/videodev2.hcc!int&V4L2_MEMORY_USERPTRb/home/slovin/Projects/indi/src/webcam/videodev2.hbb!int0V4L2_PRIORITY_BACKGROUNDb/home/slovin/Projects/indi/src/webcam/videodev2.h„„int*V4L2_PRIORITY_DEFAULTb/home/slovin/Projects/indi/src/webcam/videodev2.h‡‡6int2V4L2_PRIORITY_INTERACTIVEb/home/slovin/Projects/indi/src/webcam/videodev2.h……int(V4L2_PRIORITY_RECORDb/home/slovin/Projects/indi/src/webcam/videodev2.h††int&V4L2_PRIORITY_UNSETb/home/slovin/Projects/indi/src/webcam/videodev2.hƒƒint(V4L2_TUNER_ANALOG_TVb/home/slovin/Projects/indi/src/webcam/videodev2.h]]int V4L2_TUNER_RADIOb/home/slovin/Projects/indi/src/webcam/videodev2.h\\int v4l2_std_idb/home/slovin/Projects/indi/src/webcam/videodev2.hùù&$unsigned long longindi-0.5/TODO0000644000175000017500000000017110605175720010603 0ustar jrjrTODO: - RTML Support - Multi user Scheduler daemon - Web interface - Vantage Pro/Pro2 Weather Station - More Devices! indi-0.5/Makefile.am0000644000175000017500000000022210605175720012144 0ustar jrjr# not a GNU package. You can remove this line, if # have all needed files, that a GNU package needs AUTOMAKE_OPTIONS = foreign 1.4 SUBDIRS = src indi-0.5/NEWS0000644000175000017500000000034510605175720010615 0ustar jrjr------------------------------------------------------------------------- News ------------------------------------------------------------------------- For the latest news on INDI, refer to INDI's website @ http://indi.sf.net indi-0.5/Makefile.in0000644000175000017500000004644710610536735012203 0ustar jrjr# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/configure AUTHORS COPYING.LIB ChangeLog INSTALL \ NEWS TODO config.guess config.sub depcomp install-sh ltconfig \ ltmain.sh missing mkinstalldirs subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno configure.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ install-recursive installcheck-recursive installdirs-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BSD_FALSE = @BSD_FALSE@ BSD_TRUE = @BSD_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_SUBDIR = @EXTRA_SUBDIR@ F77 = @F77@ FFLAGS = @FFLAGS@ GREP = @GREP@ HAVE_LIBSBIGUDRV_FALSE = @HAVE_LIBSBIGUDRV_FALSE@ HAVE_LIBSBIGUDRV_TRUE = @HAVE_LIBSBIGUDRV_TRUE@ HAVE_LIBUSB_FALSE = @HAVE_LIBUSB_FALSE@ HAVE_LIBUSB_TRUE = @HAVE_LIBUSB_TRUE@ HAVE_V4L2_FALSE = @HAVE_V4L2_FALSE@ HAVE_V4L2_TRUE = @HAVE_V4L2_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBCFITSIO = @LIBCFITSIO@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSBIGUDRV = @LIBSBIGUDRV@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LINUX_FALSE = @LINUX_FALSE@ LINUX_TRUE = @LINUX_TRUE@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ NULL_FALSE = @NULL_FALSE@ NULL_TRUE = @NULL_TRUE@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_F77 = @ac_ct_F77@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ # not a GNU package. You can remove this line, if # have all needed files, that a GNU package needs AUTOMAKE_OPTIONS = foreign 1.4 SUBDIRS = src all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ cd $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) cd $(top_srcdir) && $(AUTOHEADER) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool uninstall-info-am: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) mkdir $(distdir) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(mkdir_p) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-exec-am: install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-info-am uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ check-am clean clean-generic clean-libtool clean-recursive \ ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ dist-shar dist-tarZ dist-zip distcheck distclean \ distclean-generic distclean-hdr distclean-libtool \ distclean-recursive distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-generic \ mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: indi-0.5/COPYING.LIB0000644000175000017500000006133410605175720011563 0ustar jrjr GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! indi-0.5/configure0000755000175000017500000256220010610536735012035 0ustar jrjr#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.60. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell autoconf@gnu.org about your system, echo including any error possibly output before this echo message } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # Find out whether ``test -x'' works. Don't use a zero-byte file, as # systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then as_executable_p="test -x" else as_executable_p=: fi rm -f conf$$.file # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` ;; esac echo=${ECHO-echo} if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then # Yippee, $echo works! : else # Restart under the correct shell. exec $SHELL "$0" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat </dev/null 2>&1 && unset CDPATH if test -z "$ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if (echo_test_string=`eval $cmd`) 2>/dev/null && echo_test_string=`eval $cmd` && (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null then break fi done fi if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then echo="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$echo" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. echo='print -r' elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} else # Try using printf. echo='printf %s\n' if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL echo="$CONFIG_SHELL $0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then echo="$CONFIG_SHELL $0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "$0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} else # Oops. We lost completely, so just stick with echo. echo=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. ECHO=$echo if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" fi tagnames=${tagnames+${tagnames},}CXX tagnames=${tagnames+${tagnames},}F77 exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="configure.in" # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #endif #if HAVE_STDINT_H # include #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT CC CFLAGS ac_ct_CC GREP EGREP LN_S ECHO AR RANLIB STRIP CPP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE LIBUSB LIBCFITSIO EXTRA_SUBDIR LIBSBIGUDRV BSD_TRUE BSD_FALSE LINUX_TRUE LINUX_FALSE NULL_TRUE NULL_FALSE HAVE_LIBUSB_TRUE HAVE_LIBUSB_FALSE HAVE_V4L2_TRUE HAVE_V4L2_FALSE HAVE_LIBSBIGUDRV_TRUE HAVE_LIBSBIGUDRV_FALSE LIBOBJS LTLIBOBJS' ac_subst_files='' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS CPPFLAGS CCC CC CFLAGS CPP CXXCPP F77 FFLAGS' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval with_$ac_package=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute directory names. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-libusb=PATH libusb path (default /usr) --disable-v4l2 disable V4L2 interface for INDI Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-pic try to use only PIC/non-PIC objects [default=use both] --with-tags[=TAGS] include additional configurations [automatic] Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CC C compiler command CFLAGS C compiler flags CPP C preprocessor CXXCPP C++ preprocessor F77 Fortran 77 compiler command FFLAGS Fortran 77 compiler flags Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.60 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.60. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then set x "$CONFIG_SITE" elif test "x$prefix" != xNONE; then set x "$prefix/share/config.site" "$prefix/etc/config.site" else set x "$ac_default_prefix/share/config.site" \ "$ac_default_prefix/etc/config.site" fi shift for ac_site_file do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" rm -f config.h >&/dev/null touch config.h ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6; } if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6; } if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { echo "$as_me:$LINENO: checking target system type" >&5 echo $ECHO_N "checking target system type... $ECHO_C" >&6; } if test "${ac_cv_target+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_target" >&5 echo "${ECHO_T}$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 echo "$as_me: error: invalid value of canonical target" >&2;} { (exit 1); exit 1; }; };; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { echo "$as_me:$LINENO: result: $CXX" >&5 echo "${ECHO_T}$CXX" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 echo "${ECHO_T}$ac_ct_CXX" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C++ compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5 echo $ECHO_N "checking for C++ compiler default output file name... $ECHO_C" >&6; } ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # # List of possible output files, starting from the most likely. # The algorithm is not robust to junk in `.', hence go to wildcards (a.*) # only as a last resort. b.out is created by i960 compilers. ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' # # The IRIX 6 linker writes into existing files which may not be # executable, retaining their permissions. Remove them first so a # subsequent execution test works. ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { (ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C++ compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C++ compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6; } # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5 echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6; } { echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } if test "${ac_cv_cxx_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } GXX=`test $ac_compiler_gnu = yes && echo yes` ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6; } ;; xno) { echo "$as_me:$LINENO: result: unsupported" >&5 echo "${ECHO_T}unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; esac ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=yes fi # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi { echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6; } if test "${lt_cv_path_SED+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done fi SED=$lt_cv_path_SED { echo "$as_me:$LINENO: result: $SED" >&5 echo "${ECHO_T}$SED" >&6; } { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Extract the first word of "grep ggrep" to use in msg output if test -z "$GREP"; then set dummy grep ggrep; ac_prog_name=$2 if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS fi GREP="$ac_cv_path_GREP" if test -z "$GREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 echo "${ECHO_T}$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else # Extract the first word of "egrep" to use in msg output if test -z "$EGREP"; then set dummy egrep; ac_prog_name=$2 if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS fi EGREP="$ac_cv_path_EGREP" if test -z "$EGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { echo "$as_me:$LINENO: checking for ld used by $CC" >&5 echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { echo "$as_me:$LINENO: checking for GNU ld" >&5 echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; } else { echo "$as_me:$LINENO: checking for non-GNU ld" >&5 echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; } fi if test "${lt_cv_path_LD+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 echo "${ECHO_T}$LD" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; } if test "${lt_cv_prog_gnu_ld+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6; } if test "${lt_cv_ld_reload_flag+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_ld_reload_flag='-r' fi { echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac { echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6; } if test "${lt_cv_path_NM+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm fi fi { echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 echo "${ECHO_T}$lt_cv_path_NM" >&6; } NM="$lt_cv_path_NM" { echo "$as_me:$LINENO: checking whether ln -s works" >&5 echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { echo "$as_me:$LINENO: result: no, using $LN_S" >&5 echo "${ECHO_T}no, using $LN_S" >&6; } fi { echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6; } if test "${lt_cv_deplibs_check_method+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix4* | aix5*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump'. lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | kfreebsd*-gnu | dragonfly*) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix3*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux*) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; nto-qnx*) lt_cv_deplibs_check_method=unknown ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6; } file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line 4240 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6; } if test "${lt_cv_cc_needs_belf+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then lt_cv_cc_needs_belf=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) LD="${LD-ld} -64" ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; } if test -z "$CXXCPP"; then if test "${ac_cv_prog_CXXCPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { echo "$as_me:$LINENO: result: $CXXCPP" >&5 echo "${ECHO_T}$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in g77 f77 xlf frt pgf77 cf77 fort77 fl32 af77 f90 xlf90 pgf90 pghpf epcf90 gfortran g95 f95 fort xlf95 ifort ifc efc pgf95 lf95 ftn do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_F77+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$F77"; then ac_cv_prog_F77="$F77" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_F77="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi F77=$ac_cv_prog_F77 if test -n "$F77"; then { echo "$as_me:$LINENO: result: $F77" >&5 echo "${ECHO_T}$F77" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$F77" && break done fi if test -z "$F77"; then ac_ct_F77=$F77 for ac_prog in g77 f77 xlf frt pgf77 cf77 fort77 fl32 af77 f90 xlf90 pgf90 pghpf epcf90 gfortran g95 f95 fort xlf95 ifort ifc efc pgf95 lf95 ftn do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_F77+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_F77"; then ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_F77="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_F77=$ac_cv_prog_ac_ct_F77 if test -n "$ac_ct_F77"; then { echo "$as_me:$LINENO: result: $ac_ct_F77" >&5 echo "${ECHO_T}$ac_ct_F77" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_F77" && break done if test "x$ac_ct_F77" = x; then F77="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac F77=$ac_ct_F77 fi fi # Provide some information about the compiler. echo "$as_me:$LINENO: checking for Fortran 77 compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } rm -f a.out # If we don't use `.F' as extension, the preprocessor is not run on the # input file. (Note that this only needs to work for GNU compilers.) ac_save_ext=$ac_ext ac_ext=F { echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5 echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6; } if test "${ac_cv_f77_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF program main #ifndef __GNUC__ choke me #endif end _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_f77_compiler_gnu=$ac_compiler_gnu fi { echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6; } ac_ext=$ac_save_ext ac_test_FFLAGS=${FFLAGS+set} ac_save_FFLAGS=$FFLAGS FFLAGS= { echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5 echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_f77_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else FFLAGS=-g cat >conftest.$ac_ext <<_ACEOF program main end _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_f77_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_f77_g=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5 echo "${ECHO_T}$ac_cv_prog_f77_g" >&6; } if test "$ac_test_FFLAGS" = set; then FFLAGS=$ac_save_FFLAGS elif test $ac_cv_prog_f77_g = yes; then if test "x$ac_cv_f77_compiler_gnu" = xyes; then FFLAGS="-g -O2" else FFLAGS="-g" fi else if test "x$ac_cv_f77_compiler_gnu" = xyes; then FFLAGS="-O2" else FFLAGS= fi fi G77=`test $ac_compiler_gnu = yes && echo yes` ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! # find the maximum length of command line arguments { echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6; } if test "${lt_cv_sys_max_cmd_len+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ = "XX$teststring") >/dev/null 2>&1 && new_result=`expr "X$teststring" : ".*" 2>&1` && lt_cv_sys_max_cmd_len=$new_result && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done teststring= # Add a significant safety factor because C++ compilers can tack on massive # amounts of additional arguments before passing them to the linker. # It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6; } else { echo "$as_me:$LINENO: result: none" >&5 echo "${ECHO_T}none" >&6; } fi # Check for command to grab the raw symbol name followed by C symbol from nm. { echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6; } if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Transform an extracted symbol line into a proper C declaration lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32*) symcode='[ABCDGISTW]' ;; hpux*) # Its linker distinguishes data from code symbols if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ;; linux*) if test "$host_cpu" = ia64; then symcode='[ABCDGIRSTW]' lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Try without a prefix undercore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Now try to grab the symbols. nlist=conftest.nm if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if grep ' nm_test_var$' "$nlist" >/dev/null; then if grep ' nm_test_func$' "$nlist" >/dev/null; then cat < conftest.$ac_ext #ifdef __cplusplus extern "C" { #endif EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' cat <> conftest.$ac_ext #if defined (__STDC__) && __STDC__ # define lt_ptr_t void * #else # define lt_ptr_t char * # define const #endif /* The mapping between symbol names and symbols. */ const struct { const char *name; lt_ptr_t address; } lt_preloaded_symbols[] = { EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext cat <<\EOF >> conftest.$ac_ext {0, (lt_ptr_t) 0} }; #ifdef __cplusplus } #endif EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_save_CFLAGS" else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { echo "$as_me:$LINENO: result: failed" >&5 echo "${ECHO_T}failed" >&6; } else { echo "$as_me:$LINENO: result: ok" >&5 echo "${ECHO_T}ok" >&6; } fi { echo "$as_me:$LINENO: checking for objdir" >&5 echo $ECHO_N "checking for objdir... $ECHO_C" >&6; } if test "${lt_cv_objdir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 echo "${ECHO_T}$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='sed -e 1s/^X//' sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' # Constants: rm="rm -f" # Global variables: default_ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a ltmain="$ac_aux_dir/ltmain.sh" ofile="$default_ofile" with_gnu_ld="$lt_cv_prog_gnu_ld" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="${ac_tool_prefix}ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { echo "$as_me:$LINENO: result: $AR" >&5 echo "${ECHO_T}$AR" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_AR"; then ac_ct_AR=$AR # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 echo "${ECHO_T}$ac_ct_AR" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi else AR="$ac_cv_prog_AR" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru test -z "$AS" && AS=as test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$LD" && LD=ld test -z "$LN_S" && LN_S="ln -s" test -z "$MAGIC_CMD" && MAGIC_CMD=file test -z "$NM" && NM=nm test -z "$SED" && SED=sed test -z "$OBJDUMP" && OBJDUMP=objdump test -z "$RANLIB" && RANLIB=: test -z "$STRIP" && STRIP=: test -z "$ac_objext" && ac_objext=o # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6; } if test "${lt_cv_path_MAGIC_CMD+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 echo "${ECHO_T}$MAGIC_CMD" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { echo "$as_me:$LINENO: checking for file" >&5 echo $ECHO_N "checking for file... $ECHO_C" >&6; } if test "${lt_cv_path_MAGIC_CMD+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 echo "${ECHO_T}$MAGIC_CMD" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac enable_dlopen=no enable_win32_dll=no # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Check whether --with-pic was given. if test "${with_pic+set}" = set; then withval=$with_pic; pic_mode="$withval" else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Use C for the default configuration in the libtool script tagname= lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;\n" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}\n' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext printf "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $rm conftest* lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then lt_prog_compiler_no_builtin_flag=' -fno-builtin' { echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:6658: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:6662: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= { echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; interix3*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; *) lt_prog_compiler_pic='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files case $cc_basename in xlc*) lt_prog_compiler_pic='-qnocommon' lt_prog_compiler_wl='-Wl,' ;; esac ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; linux*) case $cc_basename in icc* | ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; esac ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 echo "${ECHO_T}$lt_prog_compiler_pic" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6; } if test "${lt_prog_compiler_pic_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:6926: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:6930: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_pic_works=yes fi fi $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6; } if test x"$lt_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } if test "${lt_prog_compiler_static_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" printf "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_static_works=yes fi else lt_prog_compiler_static_works=yes fi fi $rm conftest* LDFLAGS="$save_LDFLAGS" fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 echo "${ECHO_T}$lt_prog_compiler_static_works" >&6; } if test x"$lt_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_c_o=no $rm -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:7030: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:7034: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files $rm out/* && rmdir out cd .. rmdir conftest $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { echo "$as_me:$LINENO: result: $hard_links" >&5 echo "${ECHO_T}$hard_links" >&6; } if test "$hard_links" = no; then { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } runpath_var= allow_undefined_flag= enable_shared_with_static_runtimes=no archive_cmds= archive_expsym_cmds= old_archive_From_new_cmds= old_archive_from_expsyms_cmds= export_dynamic_flag_spec= whole_archive_flag_spec= thread_safe_flag_spec= hardcode_libdir_flag_spec= hardcode_libdir_flag_spec_ld= hardcode_libdir_separator= hardcode_direct=no hardcode_minus_L=no hardcode_shlibpath_var=unsupported link_all_deplibs=unknown hardcode_automatic=no module_cmds= module_expsym_cmds= always_export_symbols=no export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms="_GLOBAL_OFFSET_TABLE_" # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. extract_expsyms_cmds= # Just being paranoid about ensuring that cc_basename is set. for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` case $host_os in cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>/dev/null` in *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix3* | aix4* | aix5*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. EOF fi ;; amigaos*) archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we can't use # them. ld_shlibs=no ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; interix3*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; linux*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then tmp_addflag= case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; esac archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test $supports_anon_versioning = yes; then archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ $echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. EOF elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix5*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_libdir_separator=':' link_all_deplibs=yes if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 hardcode_direct=yes else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # see comment about different semantics on the GNU ld section ld_shlibs=no ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_From_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' fix_srcfile_path='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes=yes ;; darwin* | rhapsody*) case $host_os in rhapsody* | darwin1.[012]) allow_undefined_flag='${wl}-undefined ${wl}suppress' ;; *) # Darwin 1.3 on if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' else case ${MACOSX_DEPLOYMENT_TARGET} in 10.[012]) allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup' ;; esac fi ;; esac archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported whole_archive_flag_spec='' link_all_deplibs=yes if test "$GCC" = yes ; then output_verbose_link_cmd='echo' archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else case $cc_basename in xlc*) output_verbose_link_cmd='echo' archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) ld_shlibs=no ;; esac fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; freebsd1*) ld_shlibs=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | kfreebsd*-gnu | dragonfly*) archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_libdir_flag_spec_ld='+b $libdir' hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_ld='-rpath $libdir' fi hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: link_all_deplibs=yes ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; openbsd*) hardcode_direct=yes hardcode_shlibpath_var=no if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' fi hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z text' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' else wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine linker options so we # cannot just pass the convience library names through # without $wl, iff we do not link with $LD. # Luckily, gcc supports the same syntax we need for Sun Studio. # Supported since Solaris 2.6 (maybe 2.5.1?) case $wlarc in '') whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; *) whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; esac ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac fi { echo "$as_me:$LINENO: result: $ld_shlibs" >&5 echo "${ECHO_T}$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } $rm conftest* printf "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then archive_cmds_need_lc=no else archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $rm conftest* { echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 echo "${ECHO_T}$archive_cmds_need_lc" >&6; } ;; esac fi ;; esac { echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix4* | aix5*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` else sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' fi sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; kfreebsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='GNU ld.so' ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; freebsd*) # from 4.6 on shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix3*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; knetbsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='GNU ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; nto-qnx*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no export_dynamic_flag_spec='${wl}-Blargedynsym' runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' shlibpath_overrides_runpath=no else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' shlibpath_overrides_runpath=yes case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { echo "$as_me:$LINENO: result: $dynamic_linker" >&5 echo "${ECHO_T}$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi { echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || \ test -n "$runpath_var" || \ test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existant directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { echo "$as_me:$LINENO: result: $hardcode_action" >&5 echo "${ECHO_T}$hardcode_action" >&6; } if test "$hardcode_action" = relink; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi striplib= old_striplib= { echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi ;; *) { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } ;; esac fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } if test $ac_cv_lib_dl_dlopen = yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) { echo "$as_me:$LINENO: checking for shl_load" >&5 echo $ECHO_N "checking for shl_load... $ECHO_C" >&6; } if test "${ac_cv_func_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define shl_load to an innocuous variant, in case declares shl_load. For example, HP-UX 11i declares gettimeofday. */ #define shl_load innocuous_shl_load /* System header to define __stub macros and hopefully few prototypes, which can conflict with char shl_load (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef shl_load /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_shl_load || defined __stub___shl_load choke me #endif int main () { return shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 echo "${ECHO_T}$ac_cv_func_shl_load" >&6; } if test $ac_cv_func_shl_load = yes; then lt_cv_dlopen="shl_load" else { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; } if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; } if test $ac_cv_lib_dld_shl_load = yes; then lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" else { echo "$as_me:$LINENO: checking for dlopen" >&5 echo $ECHO_N "checking for dlopen... $ECHO_C" >&6; } if test "${ac_cv_func_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define dlopen to an innocuous variant, in case declares dlopen. For example, HP-UX 11i declares gettimeofday. */ #define dlopen innocuous_dlopen /* System header to define __stub macros and hopefully few prototypes, which can conflict with char dlopen (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef dlopen /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_dlopen || defined __stub___dlopen choke me #endif int main () { return dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 echo "${ECHO_T}$ac_cv_func_dlopen" >&6; } if test $ac_cv_func_dlopen = yes; then lt_cv_dlopen="dlopen" else { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } if test $ac_cv_lib_dl_dlopen = yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6; } if test "${ac_cv_lib_svld_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_svld_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6; } if test $ac_cv_lib_svld_dlopen = yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6; } if test "${ac_cv_lib_dld_dld_link+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dld_dld_link=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; } if test $ac_cv_lib_dld_dld_link = yes; then lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6; } if test "${lt_cv_dlopen_self+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif #ifdef __cplusplus extern "C" void exit (int); #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); exit (status); } EOF if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 echo "${ECHO_T}$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6; } if test "${lt_cv_dlopen_self_static+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif #ifdef __cplusplus extern "C" void exit (int); #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); exit (status); } EOF if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi # Report which library types will actually be built { echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $can_build_shared" >&5 echo "${ECHO_T}$can_build_shared" >&6; } { echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix4* | aix5*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { echo "$as_me:$LINENO: result: $enable_shared" >&5 echo "${ECHO_T}$enable_shared" >&6; } { echo "$as_me:$LINENO: checking whether to build static libraries" >&5 echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { echo "$as_me:$LINENO: result: $enable_static" >&5 echo "${ECHO_T}$enable_static" >&6; } # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh # with your package, and you will get complaints that there are # no rules to generate ltmain.sh. if test -f "$ltmain"; then # See if we are running on zsh, and set the options which allow our commands through # without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ deplibs_check_method reload_flag reload_cmds need_locks \ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ old_postinstall_cmds old_postuninstall_cmds \ compiler \ CC \ LD \ lt_prog_compiler_wl \ lt_prog_compiler_pic \ lt_prog_compiler_static \ lt_prog_compiler_no_builtin_flag \ export_dynamic_flag_spec \ thread_safe_flag_spec \ whole_archive_flag_spec \ enable_shared_with_static_runtimes \ old_archive_cmds \ old_archive_from_new_cmds \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ archive_cmds \ archive_expsym_cmds \ postinstall_cmds \ postuninstall_cmds \ old_archive_from_expsyms_cmds \ allow_undefined_flag \ no_undefined_flag \ export_symbols_cmds \ hardcode_libdir_flag_spec \ hardcode_libdir_flag_spec_ld \ hardcode_libdir_separator \ hardcode_automatic \ module_cmds \ module_expsym_cmds \ lt_cv_prog_compiler_c_o \ exclude_expsyms \ include_expsyms; do case $var in old_archive_cmds | \ old_archive_from_new_cmds | \ archive_cmds | \ archive_expsym_cmds | \ module_cmds | \ module_expsym_cmds | \ old_archive_from_expsyms_cmds | \ export_symbols_cmds | \ extract_expsyms_cmds | reload_cmds | finish_cmds | \ postinstall_cmds | postuninstall_cmds | \ old_postinstall_cmds | old_postuninstall_cmds | \ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) # Double-quote double-evaled strings. eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ;; *) eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ;; esac done case $lt_echo in *'\$0 --fallback-echo"') lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ;; esac cfgfile="${ofile}T" trap "$rm \"$cfgfile\"; exit 1" 1 2 15 $rm -f "$cfgfile" { echo "$as_me:$LINENO: creating $ofile" >&5 echo "$as_me: creating $ofile" >&6;} cat <<__EOF__ >> "$cfgfile" #! $SHELL # `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 # Free Software Foundation, Inc. # # This file is part of GNU Libtool: # Originally by Gordon Matzigkeit , 1996 # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="$SED -e 1s/^X//" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # The names of the tagged configurations supported by this script. available_tags= # ### BEGIN LIBTOOL CONFIG # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC # LTCC compiler flags. LTCFLAGS=$lt_LTCFLAGS # A language-specific compiler. CC=$lt_compiler # Is the compiler the GNU C compiler? with_gcc=$GCC # An ERE matcher. EGREP=$lt_EGREP # The linker used to build libraries. LD=$lt_LD # Whether we need hard or soft links. LN_S=$lt_LN_S # A BSD-compatible nm program. NM=$lt_NM # A symbol stripping program STRIP=$lt_STRIP # Used to examine libraries when file_magic_cmd begins "file" MAGIC_CMD=$MAGIC_CMD # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Object file suffix (normally "o"). objext="$ac_objext" # Old archive suffix (normally "a"). libext="$libext" # Shared library suffix (normally ".so"). shrext_cmds='$shrext_cmds' # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic pic_mode=$pic_mode # What is the maximum length of a command? max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$lt_thread_safe_flag_spec # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Commands used to build and install an old-style archive. RANLIB=$lt_RANLIB old_archive_cmds=$lt_old_archive_cmds old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build and install a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds postinstall_cmds=$lt_postinstall_cmds postuninstall_cmds=$lt_postuninstall_cmds # Commands used to build a loadable module (assumed same as above if empty) module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. predep_objects=$lt_predep_objects # Dependencies to place after the objects being linked to create a # shared library. postdep_objects=$lt_postdep_objects # Dependencies to place before the objects being linked to create a # shared library. predeps=$lt_predeps # Dependencies to place after the objects being linked to create a # shared library. postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$lt_file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that forces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$lt_finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # If ld is used when linking, flag to hardcode \$libdir into # a binary during linking. This must work even if \$libdir does # not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the # resulting binary. hardcode_direct=$hardcode_direct # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to yes if building a shared library automatically hardcodes DIR into the library # and all subsequent libraries and executables linked against it. hardcode_automatic=$hardcode_automatic # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. variables_saved_for_relink="$variables_saved_for_relink" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Compile-time system search path for libraries sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$fix_srcfile_path" # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # ### END LIBTOOL CONFIG __EOF__ case $host_os in aix3*) cat <<\EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi EOF ;; esac # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || \ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" else # If there is no Makefile yet, we rely on a make rule to execute # `config.status --recheck' to rerun these tests and create the # libtool script then. ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` if test -f "$ltmain_in"; then test -f Makefile && make "$ltmain" fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu CC="$lt_save_CC" # Check whether --with-tags was given. if test "${with_tags+set}" = set; then withval=$with_tags; tagnames="$withval" fi if test -f "$ltmain" && test -n "$tagnames"; then if test ! -f "${ofile}"; then { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5 echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;} fi if test -z "$LTCC"; then eval "`$SHELL ${ofile} --config | grep '^LTCC='`" if test -z "$LTCC"; then { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5 echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;} else { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5 echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;} fi fi if test -z "$LTCFLAGS"; then eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" fi # Extract list of available tagged configurations in $ofile. # Note that this assumes the entire list is on one line. available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for tagname in $tagnames; do IFS="$lt_save_ifs" # Check whether tagname contains only valid characters case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in "") ;; *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5 echo "$as_me: error: invalid tag name: $tagname" >&2;} { (exit 1); exit 1; }; } ;; esac if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null then { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5 echo "$as_me: error: tag name \"$tagname\" already exists" >&2;} { (exit 1); exit 1; }; } fi # Update the list of available tags. if test -n "$tagname"; then echo appending configuration tag \"$tagname\" to $ofile case $tagname in CXX) if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_flag_spec_ld_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;\n" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext printf "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $rm conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} compiler=$CC compiler_CXX=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # We don't want -fno-exception wen compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { echo "$as_me:$LINENO: checking for ld used by $CC" >&5 echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { echo "$as_me:$LINENO: checking for GNU ld" >&5 echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; } else { echo "$as_me:$LINENO: checking for non-GNU ld" >&5 echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; } fi if test "${lt_cv_path_LD+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 echo "${ECHO_T}$LD" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; } if test "${lt_cv_prog_gnu_ld+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ grep 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix5*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes if test "$GXX" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 hardcode_direct_CXX=yes else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols_CXX=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_CXX='-berok' # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' ${wl}-bernotok' allow_undefined_flag_CXX=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' archive_cmds_need_lc_CXX=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; darwin* | rhapsody*) case $host_os in rhapsody* | darwin1.[012]) allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress' ;; *) # Darwin 1.3 on if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' else case ${MACOSX_DEPLOYMENT_TARGET} in 10.[012]) allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup' ;; esac fi ;; esac archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported whole_archive_flag_spec_CXX='' link_all_deplibs_CXX=yes if test "$GXX" = yes ; then lt_int_apple_cc_single_mod=no output_verbose_link_cmd='echo' if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then lt_int_apple_cc_single_mod=yes fi if test "X$lt_int_apple_cc_single_mod" = Xyes ; then archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' else archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' fi module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds if test "X$lt_int_apple_cc_single_mod" = Xyes ; then archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' fi module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else case $cc_basename in xlc*) output_verbose_link_cmd='echo' archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) ld_shlibs_CXX=no ;; esac fi ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd[12]*) # C++ shared libraries reported to be fairly broken before switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | kfreebsd*-gnu | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; gnu*) ;; hpux9*) hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='${wl}-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes; then archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) hardcode_libdir_flag_spec_ld_CXX='+b $libdir' ;; *) export_dynamic_flag_spec_CXX='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix3*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: ;; linux*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc*) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC*) # Portland Group C++ compiler archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; openbsd2*) # C++ shared libraries are fairly broken ld_shlibs_CXX=no ;; openbsd*) hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='${wl}-E' whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd='echo' ;; osf3*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ $rm $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The C++ compiler is used as linker so we must use $wl # flag to pass the commands to the underlying system # linker. We must also pass each convience library through # to the system linker between allextract/defaultextract. # The C++ compiler will combine linker options so we # cannot just pass the convience library names through # without $wl. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then no_undefined_flag_CXX=' ${wl}-z ${wl}defs' if $CC --version | grep -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" fi hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='${wl}-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. # So that behaviour is only enabled if SCOABSPATH is set to a # non-empty value in the environment. Most likely only useful for # creating official distributions of packages. # This is a hack until libtool officially supports absolute path # names for shared libraries. no_undefined_flag_CXX='${wl}-z,text' allow_undefined_flag_CXX='${wl}-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 echo "${ECHO_T}$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no GCC_CXX="$GXX" LD_CXX="$LD" cat > conftest.$ac_ext <&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no # The `*' in the case matches for architectures that use `case' in # $output_verbose_cmd can trigger glob expansion during the loop # eval without this substitution. output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` for p in `eval $output_verbose_link_cmd`; do case $p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" \ || test $p = "-R"; then prev=$p continue else prev= fi if test "$pre_test_object_deps_done" = no; then case $p in -L* | -R*) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX="${prev}${p}" else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX="${prev}${p}" else postdeps_CXX="${postdeps_CXX} ${prev}${p}" fi fi ;; *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$predep_objects_CXX"; then predep_objects_CXX="$p" else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX="$p" else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $rm -f confest.$objext # PORTME: override above test on systems where it is broken case $host_os in interix3*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; solaris*) case $cc_basename in CC*) # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. postdeps_CXX='-lCstd -lCrun' ;; esac ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= { echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | os2* | pw32*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; interix3*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix4* | aix5*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; darwin*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files case $cc_basename in xlc*) lt_prog_compiler_pic_CXX='-qnocommon' lt_prog_compiler_wl_CXX='-Wl,' ;; esac ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | kfreebsd*-gnu | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux*) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; icpc* | ecpc*) # Intel C++ lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC*) # Portland Group C++ compiler. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6; } if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:11950: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:11954: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_pic_works_CXX=yes fi fi $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6; } if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } if test "${lt_prog_compiler_static_works_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_static_works_CXX=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" printf "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_static_works_CXX=yes fi else lt_prog_compiler_static_works_CXX=yes fi fi $rm conftest* LDFLAGS="$save_LDFLAGS" fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5 echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6; } if test x"$lt_prog_compiler_static_works_CXX" = xyes; then : else lt_prog_compiler_static_CXX= fi { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_c_o_CXX=no $rm -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:12054: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:12058: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files $rm out/* && rmdir out cd .. rmdir conftest $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { echo "$as_me:$LINENO: result: $hard_links" >&5 echo "${ECHO_T}$hard_links" >&6; } if test "$hard_links" = no; then { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in aix4* | aix5*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX="$ltdll_cmds" ;; cygwin* | mingw*) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 echo "${ECHO_T}$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } $rm conftest* printf "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then archive_cmds_need_lc_CXX=no else archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $rm conftest* { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6; } ;; esac fi ;; esac { echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix4* | aix5*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` else sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' fi sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; kfreebsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='GNU ld.so' ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; freebsd*) # from 4.6 on shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix3*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; knetbsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='GNU ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; nto-qnx*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no export_dynamic_flag_spec='${wl}-Blargedynsym' runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' shlibpath_overrides_runpath=no else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' shlibpath_overrides_runpath=yes case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { echo "$as_me:$LINENO: result: $dynamic_linker" >&5 echo "${ECHO_T}$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi { echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || \ test -n "$runpath_var_CXX" || \ test "X$hardcode_automatic_CXX" = "Xyes" ; then # We can hardcode non-existant directories. if test "$hardcode_direct_CXX" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no && test "$hardcode_minus_L_CXX" != no; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5 echo "${ECHO_T}$hardcode_action_CXX" >&6; } if test "$hardcode_action_CXX" = relink; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh # with your package, and you will get complaints that there are # no rules to generate ltmain.sh. if test -f "$ltmain"; then # See if we are running on zsh, and set the options which allow our commands through # without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ deplibs_check_method reload_flag reload_cmds need_locks \ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ old_postinstall_cmds old_postuninstall_cmds \ compiler_CXX \ CC_CXX \ LD_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_static_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ export_dynamic_flag_spec_CXX \ thread_safe_flag_spec_CXX \ whole_archive_flag_spec_CXX \ enable_shared_with_static_runtimes_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ postinstall_cmds_CXX \ postuninstall_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ export_symbols_cmds_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_flag_spec_ld_CXX \ hardcode_libdir_separator_CXX \ hardcode_automatic_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ lt_cv_prog_compiler_c_o_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX; do case $var in old_archive_cmds_CXX | \ old_archive_from_new_cmds_CXX | \ archive_cmds_CXX | \ archive_expsym_cmds_CXX | \ module_cmds_CXX | \ module_expsym_cmds_CXX | \ old_archive_from_expsyms_cmds_CXX | \ export_symbols_cmds_CXX | \ extract_expsyms_cmds | reload_cmds | finish_cmds | \ postinstall_cmds | postuninstall_cmds | \ old_postinstall_cmds | old_postuninstall_cmds | \ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) # Double-quote double-evaled strings. eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ;; *) eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ;; esac done case $lt_echo in *'\$0 --fallback-echo"') lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ;; esac cfgfile="$ofile" cat <<__EOF__ >> "$cfgfile" # ### BEGIN LIBTOOL TAG CONFIG: $tagname # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC # LTCC compiler flags. LTCFLAGS=$lt_LTCFLAGS # A language-specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU C compiler? with_gcc=$GCC_CXX # An ERE matcher. EGREP=$lt_EGREP # The linker used to build libraries. LD=$lt_LD_CXX # Whether we need hard or soft links. LN_S=$lt_LN_S # A BSD-compatible nm program. NM=$lt_NM # A symbol stripping program STRIP=$lt_STRIP # Used to examine libraries when file_magic_cmd begins "file" MAGIC_CMD=$MAGIC_CMD # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Object file suffix (normally "o"). objext="$ac_objext" # Old archive suffix (normally "a"). libext="$libext" # Shared library suffix (normally ".so"). shrext_cmds='$shrext_cmds' # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX pic_mode=$pic_mode # What is the maximum length of a command? max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Commands used to build and install an old-style archive. RANLIB=$lt_RANLIB old_archive_cmds=$lt_old_archive_cmds_CXX old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build and install a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX postinstall_cmds=$lt_postinstall_cmds postuninstall_cmds=$lt_postuninstall_cmds # Commands used to build a loadable module (assumed same as above if empty) module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. predep_objects=$lt_predep_objects_CXX # Dependencies to place after the objects being linked to create a # shared library. postdep_objects=$lt_postdep_objects_CXX # Dependencies to place before the objects being linked to create a # shared library. predeps=$lt_predeps_CXX # Dependencies to place after the objects being linked to create a # shared library. postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$lt_file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that forces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$lt_finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # If ld is used when linking, flag to hardcode \$libdir into # a binary during linking. This must work even if \$libdir does # not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the # resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to yes if building a shared library automatically hardcodes DIR into the library # and all subsequent libraries and executables linked against it. hardcode_automatic=$hardcode_automatic_CXX # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. variables_saved_for_relink="$variables_saved_for_relink" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Compile-time system search path for libraries sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$fix_srcfile_path_CXX" # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # ### END LIBTOOL TAG CONFIG: $tagname __EOF__ else # If there is no Makefile yet, we rely on a make rule to execute # `config.status --recheck' to rerun these tests and create the # libtool script then. ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` if test -f "$ltmain_in"; then test -f Makefile && make "$ltmain" fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu CC=$lt_save_CC LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ldcxx=$with_gnu_ld with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld else tagname="" fi ;; F77) if test -n "$F77" && test "X$F77" != "Xno"; then ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu archive_cmds_need_lc_F77=no allow_undefined_flag_F77= always_export_symbols_F77=no archive_expsym_cmds_F77= export_dynamic_flag_spec_F77= hardcode_direct_F77=no hardcode_libdir_flag_spec_F77= hardcode_libdir_flag_spec_ld_F77= hardcode_libdir_separator_F77= hardcode_minus_L_F77=no hardcode_automatic_F77=no module_cmds_F77= module_expsym_cmds_F77= link_all_deplibs_F77=unknown old_archive_cmds_F77=$old_archive_cmds no_undefined_flag_F77= whole_archive_flag_spec_F77= enable_shared_with_static_runtimes_F77=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o objext_F77=$objext # Code to be used in simple compile tests lt_simple_compile_test_code=" subroutine t\n return\n end\n" # Code to be used in simple link tests lt_simple_link_test_code=" program t\n end\n" # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext printf "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $rm conftest* # Allow CC to be a program name with arguments. lt_save_CC="$CC" CC=${F77-"f77"} compiler=$CC compiler_F77=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` { echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $can_build_shared" >&5 echo "${ECHO_T}$can_build_shared" >&6; } { echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix4* | aix5*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { echo "$as_me:$LINENO: result: $enable_shared" >&5 echo "${ECHO_T}$enable_shared" >&6; } { echo "$as_me:$LINENO: checking whether to build static libraries" >&5 echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { echo "$as_me:$LINENO: result: $enable_static" >&5 echo "${ECHO_T}$enable_static" >&6; } GCC_F77="$G77" LD_F77="$LD" lt_prog_compiler_wl_F77= lt_prog_compiler_pic_F77= lt_prog_compiler_static_F77= { echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } if test "$GCC" = yes; then lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_static_F77='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_F77='-Bstatic' fi ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' ;; beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_F77='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_F77='-fno-common' ;; interix3*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared_F77=no enable_shared=no ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_F77=-Kconform_pic fi ;; hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_F77='-fPIC' ;; esac ;; *) lt_prog_compiler_pic_F77='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl_F77='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_F77='-Bstatic' else lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' fi ;; darwin*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files case $cc_basename in xlc*) lt_prog_compiler_pic_F77='-qnocommon' lt_prog_compiler_wl_F77='-Wl,' ;; esac ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_F77='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl_F77='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_F77='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static_F77='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl_F77='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static_F77='-non_shared' ;; newsos6) lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-Bstatic' ;; linux*) case $cc_basename in icc* | ecc*) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-fpic' lt_prog_compiler_static_F77='-Bstatic' ;; ccc*) lt_prog_compiler_wl_F77='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static_F77='-non_shared' ;; esac ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl_F77='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static_F77='-non_shared' ;; solaris*) lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-Bstatic' case $cc_basename in f77* | f90* | f95*) lt_prog_compiler_wl_F77='-Qoption ld ';; *) lt_prog_compiler_wl_F77='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl_F77='-Qoption ld ' lt_prog_compiler_pic_F77='-PIC' lt_prog_compiler_static_F77='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic_F77='-Kconform_pic' lt_prog_compiler_static_F77='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-Bstatic' ;; unicos*) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_can_build_shared_F77=no ;; uts4*) lt_prog_compiler_pic_F77='-pic' lt_prog_compiler_static_F77='-Bstatic' ;; *) lt_prog_compiler_can_build_shared_F77=no ;; esac fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_F77"; then { echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6; } if test "${lt_prog_compiler_pic_works_F77+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_pic_works_F77=no ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_F77" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:13624: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:13628: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_pic_works_F77=yes fi fi $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6; } if test x"$lt_prog_compiler_pic_works_F77" = xyes; then case $lt_prog_compiler_pic_F77 in "" | " "*) ;; *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; esac else lt_prog_compiler_pic_F77= lt_prog_compiler_can_build_shared_F77=no fi fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_F77= ;; *) lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77" ;; esac # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\" { echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } if test "${lt_prog_compiler_static_works_F77+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_static_works_F77=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" printf "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_static_works_F77=yes fi else lt_prog_compiler_static_works_F77=yes fi fi $rm conftest* LDFLAGS="$save_LDFLAGS" fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5 echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6; } if test x"$lt_prog_compiler_static_works_F77" = xyes; then : else lt_prog_compiler_static_F77= fi { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_c_o_F77=no $rm -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:13728: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:13732: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_F77=yes fi fi chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files $rm out/* && rmdir out cd .. rmdir conftest $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { echo "$as_me:$LINENO: result: $hard_links" >&5 echo "${ECHO_T}$hard_links" >&6; } if test "$hard_links" = no; then { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } runpath_var= allow_undefined_flag_F77= enable_shared_with_static_runtimes_F77=no archive_cmds_F77= archive_expsym_cmds_F77= old_archive_From_new_cmds_F77= old_archive_from_expsyms_cmds_F77= export_dynamic_flag_spec_F77= whole_archive_flag_spec_F77= thread_safe_flag_spec_F77= hardcode_libdir_flag_spec_F77= hardcode_libdir_flag_spec_ld_F77= hardcode_libdir_separator_F77= hardcode_direct_F77=no hardcode_minus_L_F77=no hardcode_shlibpath_var_F77=unsupported link_all_deplibs_F77=unknown hardcode_automatic_F77=no module_cmds_F77= module_expsym_cmds_F77= always_export_symbols_F77=no export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms_F77= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_" # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. extract_expsyms_cmds= # Just being paranoid about ensuring that cc_basename is set. for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` case $host_os in cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs_F77=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_F77='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec_F77= fi supports_anon_versioning=no case `$LD -v 2>/dev/null` in *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix3* | aix4* | aix5*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs_F77=no cat <&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. EOF fi ;; amigaos*) archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_minus_L_F77=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we can't use # them. ld_shlibs_F77=no ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_F77=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs_F77=no fi ;; cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_F77='-L$libdir' allow_undefined_flag_F77=unsupported always_export_symbols_F77=no enable_shared_with_static_runtimes_F77=yes export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_F77=no fi ;; interix3*) hardcode_direct_F77=no hardcode_shlibpath_var_F77=no hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' export_dynamic_flag_spec_F77='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; linux*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then tmp_addflag= case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; esac archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test $supports_anon_versioning = yes; then archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ $echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi else ld_shlibs_F77=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs_F77=no cat <&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. EOF elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs_F77=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs_F77=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' else ld_shlibs_F77=no fi ;; esac ;; sunos4*) archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct_F77=yes hardcode_shlibpath_var_F77=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs_F77=no fi ;; esac if test "$ld_shlibs_F77" = no; then runpath_var= hardcode_libdir_flag_spec_F77= export_dynamic_flag_spec_F77= whole_archive_flag_spec_F77= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag_F77=unsupported always_export_symbols_F77=yes archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L_F77=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct_F77=unsupported fi ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix5*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_F77='' hardcode_direct_F77=yes hardcode_libdir_separator_F77=':' link_all_deplibs_F77=yes if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 hardcode_direct_F77=yes else # We have old collect2 hardcode_direct_F77=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_F77=yes hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_libdir_separator_F77= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols_F77=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_F77='-berok' # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF program main end _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_F77="-z nodefs" archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF program main end _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_F77=' ${wl}-bernotok' allow_undefined_flag_F77=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_F77='$convenience' archive_cmds_need_lc_F77=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_minus_L_F77=yes # see comment about different semantics on the GNU ld section ld_shlibs_F77=no ;; bsdi[45]*) export_dynamic_flag_spec_F77=-rdynamic ;; cygwin* | mingw* | pw32*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_F77=' ' allow_undefined_flag_F77=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_From_new_cmds_F77='true' # FIXME: Should let the user specify the lib program. old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs' fix_srcfile_path_F77='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes_F77=yes ;; darwin* | rhapsody*) case $host_os in rhapsody* | darwin1.[012]) allow_undefined_flag_F77='${wl}-undefined ${wl}suppress' ;; *) # Darwin 1.3 on if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' else case ${MACOSX_DEPLOYMENT_TARGET} in 10.[012]) allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup' ;; esac fi ;; esac archive_cmds_need_lc_F77=no hardcode_direct_F77=no hardcode_automatic_F77=yes hardcode_shlibpath_var_F77=unsupported whole_archive_flag_spec_F77='' link_all_deplibs_F77=yes if test "$GCC" = yes ; then output_verbose_link_cmd='echo' archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else case $cc_basename in xlc*) output_verbose_link_cmd='echo' archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) ld_shlibs_F77=no ;; esac fi ;; dgux*) archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_shlibpath_var_F77=no ;; freebsd1*) ld_shlibs_F77=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec_F77='-R$libdir' hardcode_direct_F77=yes hardcode_shlibpath_var_F77=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_F77=yes hardcode_minus_L_F77=yes hardcode_shlibpath_var_F77=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | kfreebsd*-gnu | dragonfly*) archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec_F77='-R$libdir' hardcode_direct_F77=yes hardcode_shlibpath_var_F77=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' hardcode_libdir_separator_F77=: hardcode_direct_F77=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L_F77=yes export_dynamic_flag_spec_F77='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' hardcode_libdir_separator_F77=: hardcode_direct_F77=yes export_dynamic_flag_spec_F77='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L_F77=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' hardcode_libdir_separator_F77=: case $host_cpu in hppa*64*|ia64*) hardcode_libdir_flag_spec_ld_F77='+b $libdir' hardcode_direct_F77=no hardcode_shlibpath_var_F77=no ;; *) hardcode_direct_F77=yes export_dynamic_flag_spec_F77='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L_F77=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_ld_F77='-rpath $libdir' fi hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_F77=: link_all_deplibs_F77=yes ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec_F77='-R$libdir' hardcode_direct_F77=yes hardcode_shlibpath_var_F77=no ;; newsos6) archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_F77=yes hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_F77=: hardcode_shlibpath_var_F77=no ;; openbsd*) hardcode_direct_F77=yes hardcode_shlibpath_var_F77=no if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' export_dynamic_flag_spec_F77='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec_F77='-R$libdir' ;; *) archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' ;; esac fi ;; os2*) hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_minus_L_F77=yes allow_undefined_flag_F77=unsupported archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag_F77=' -expect_unresolved \*' archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' fi hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_F77=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' else allow_undefined_flag_F77=' -expect_unresolved \*' archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec_F77='-rpath $libdir' fi hardcode_libdir_separator_F77=: ;; solaris*) no_undefined_flag_F77=' -z text' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' else wlarc='' archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' fi hardcode_libdir_flag_spec_F77='-R$libdir' hardcode_shlibpath_var_F77=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine linker options so we # cannot just pass the convience library names through # without $wl, iff we do not link with $LD. # Luckily, gcc supports the same syntax we need for Sun Studio. # Supported since Solaris 2.6 (maybe 2.5.1?) case $wlarc in '') whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;; *) whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; esac ;; esac link_all_deplibs_F77=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_direct_F77=yes hardcode_minus_L_F77=yes hardcode_shlibpath_var_F77=no ;; sysv4) case $host_vendor in sni) archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_F77=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds_F77='$CC -r -o $output$reload_objs' hardcode_direct_F77=no ;; motorola) archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var_F77=no ;; sysv4.3*) archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var_F77=no export_dynamic_flag_spec_F77='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var_F77=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs_F77=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) no_undefined_flag_F77='${wl}-z,text' archive_cmds_need_lc_F77=no hardcode_shlibpath_var_F77=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_F77='${wl}-z,text' allow_undefined_flag_F77='${wl}-z,nodefs' archive_cmds_need_lc_F77=no hardcode_shlibpath_var_F77=no hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator_F77=':' link_all_deplibs_F77=yes export_dynamic_flag_spec_F77='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_shlibpath_var_F77=no ;; *) ld_shlibs_F77=no ;; esac fi { echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5 echo "${ECHO_T}$ld_shlibs_F77" >&6; } test "$ld_shlibs_F77" = no && can_build_shared=no # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_F77" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_F77=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds_F77 in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } $rm conftest* printf "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_F77 pic_flag=$lt_prog_compiler_pic_F77 compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_F77 allow_undefined_flag_F77= if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then archive_cmds_need_lc_F77=no else archive_cmds_need_lc_F77=yes fi allow_undefined_flag_F77=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $rm conftest* { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5 echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6; } ;; esac fi ;; esac { echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix4* | aix5*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` else sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' fi sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; kfreebsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='GNU ld.so' ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; freebsd*) # from 4.6 on shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix3*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; knetbsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='GNU ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; nto-qnx*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no export_dynamic_flag_spec='${wl}-Blargedynsym' runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' shlibpath_overrides_runpath=no else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' shlibpath_overrides_runpath=yes case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { echo "$as_me:$LINENO: result: $dynamic_linker" >&5 echo "${ECHO_T}$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi { echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } hardcode_action_F77= if test -n "$hardcode_libdir_flag_spec_F77" || \ test -n "$runpath_var_F77" || \ test "X$hardcode_automatic_F77" = "Xyes" ; then # We can hardcode non-existant directories. if test "$hardcode_direct_F77" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no && test "$hardcode_minus_L_F77" != no; then # Linking always hardcodes the temporary library directory. hardcode_action_F77=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_F77=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_F77=unsupported fi { echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5 echo "${ECHO_T}$hardcode_action_F77" >&6; } if test "$hardcode_action_F77" = relink; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh # with your package, and you will get complaints that there are # no rules to generate ltmain.sh. if test -f "$ltmain"; then # See if we are running on zsh, and set the options which allow our commands through # without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ deplibs_check_method reload_flag reload_cmds need_locks \ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ old_postinstall_cmds old_postuninstall_cmds \ compiler_F77 \ CC_F77 \ LD_F77 \ lt_prog_compiler_wl_F77 \ lt_prog_compiler_pic_F77 \ lt_prog_compiler_static_F77 \ lt_prog_compiler_no_builtin_flag_F77 \ export_dynamic_flag_spec_F77 \ thread_safe_flag_spec_F77 \ whole_archive_flag_spec_F77 \ enable_shared_with_static_runtimes_F77 \ old_archive_cmds_F77 \ old_archive_from_new_cmds_F77 \ predep_objects_F77 \ postdep_objects_F77 \ predeps_F77 \ postdeps_F77 \ compiler_lib_search_path_F77 \ archive_cmds_F77 \ archive_expsym_cmds_F77 \ postinstall_cmds_F77 \ postuninstall_cmds_F77 \ old_archive_from_expsyms_cmds_F77 \ allow_undefined_flag_F77 \ no_undefined_flag_F77 \ export_symbols_cmds_F77 \ hardcode_libdir_flag_spec_F77 \ hardcode_libdir_flag_spec_ld_F77 \ hardcode_libdir_separator_F77 \ hardcode_automatic_F77 \ module_cmds_F77 \ module_expsym_cmds_F77 \ lt_cv_prog_compiler_c_o_F77 \ exclude_expsyms_F77 \ include_expsyms_F77; do case $var in old_archive_cmds_F77 | \ old_archive_from_new_cmds_F77 | \ archive_cmds_F77 | \ archive_expsym_cmds_F77 | \ module_cmds_F77 | \ module_expsym_cmds_F77 | \ old_archive_from_expsyms_cmds_F77 | \ export_symbols_cmds_F77 | \ extract_expsyms_cmds | reload_cmds | finish_cmds | \ postinstall_cmds | postuninstall_cmds | \ old_postinstall_cmds | old_postuninstall_cmds | \ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) # Double-quote double-evaled strings. eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ;; *) eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ;; esac done case $lt_echo in *'\$0 --fallback-echo"') lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ;; esac cfgfile="$ofile" cat <<__EOF__ >> "$cfgfile" # ### BEGIN LIBTOOL TAG CONFIG: $tagname # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_F77 # Whether or not to disallow shared libs when runtime libs are static allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC # LTCC compiler flags. LTCFLAGS=$lt_LTCFLAGS # A language-specific compiler. CC=$lt_compiler_F77 # Is the compiler the GNU C compiler? with_gcc=$GCC_F77 # An ERE matcher. EGREP=$lt_EGREP # The linker used to build libraries. LD=$lt_LD_F77 # Whether we need hard or soft links. LN_S=$lt_LN_S # A BSD-compatible nm program. NM=$lt_NM # A symbol stripping program STRIP=$lt_STRIP # Used to examine libraries when file_magic_cmd begins "file" MAGIC_CMD=$MAGIC_CMD # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_F77 # Object file suffix (normally "o"). objext="$ac_objext" # Old archive suffix (normally "a"). libext="$libext" # Shared library suffix (normally ".so"). shrext_cmds='$shrext_cmds' # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_F77 pic_mode=$pic_mode # What is the maximum length of a command? max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 # Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_F77 # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77 # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Commands used to build and install an old-style archive. RANLIB=$lt_RANLIB old_archive_cmds=$lt_old_archive_cmds_F77 old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 # Commands used to build and install a shared archive. archive_cmds=$lt_archive_cmds_F77 archive_expsym_cmds=$lt_archive_expsym_cmds_F77 postinstall_cmds=$lt_postinstall_cmds postuninstall_cmds=$lt_postuninstall_cmds # Commands used to build a loadable module (assumed same as above if empty) module_cmds=$lt_module_cmds_F77 module_expsym_cmds=$lt_module_expsym_cmds_F77 # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. predep_objects=$lt_predep_objects_F77 # Dependencies to place after the objects being linked to create a # shared library. postdep_objects=$lt_postdep_objects_F77 # Dependencies to place before the objects being linked to create a # shared library. predeps=$lt_predeps_F77 # Dependencies to place after the objects being linked to create a # shared library. postdeps=$lt_postdeps_F77 # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_F77 # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$lt_file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_F77 # Flag that forces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_F77 # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$lt_finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_F77 # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 # If ld is used when linking, flag to hardcode \$libdir into # a binary during linking. This must work even if \$libdir does # not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 # Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the # resulting binary. hardcode_direct=$hardcode_direct_F77 # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$hardcode_minus_L_F77 # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 # Set to yes if building a shared library automatically hardcodes DIR into the library # and all subsequent libraries and executables linked against it. hardcode_automatic=$hardcode_automatic_F77 # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. variables_saved_for_relink="$variables_saved_for_relink" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_F77 # Compile-time system search path for libraries sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$fix_srcfile_path_F77" # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols_F77 # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_F77 # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_F77 # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_F77 # ### END LIBTOOL TAG CONFIG: $tagname __EOF__ else # If there is no Makefile yet, we rely on a make rule to execute # `config.status --recheck' to rerun these tests and create the # libtool script then. ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` if test -f "$ltmain_in"; then test -f Makefile && make "$ltmain" fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu CC="$lt_save_CC" else tagname="" fi ;; GCJ) if test -n "$GCJ" && test "X$GCJ" != "Xno"; then # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o objext_GCJ=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}\n" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext printf "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $rm conftest* # Allow CC to be a program name with arguments. lt_save_CC="$CC" CC=${GCJ-"gcj"} compiler=$CC compiler_GCJ=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # GCJ did not exist at the time GCC didn't implicitly link libc in. archive_cmds_need_lc_GCJ=no old_archive_cmds_GCJ=$old_archive_cmds lt_prog_compiler_no_builtin_flag_GCJ= if test "$GCC" = yes; then lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin' { echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:15958: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:15962: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl_GCJ= lt_prog_compiler_pic_GCJ= lt_prog_compiler_static_GCJ= { echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } if test "$GCC" = yes; then lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_static_GCJ='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_GCJ='-Bstatic' fi ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4' ;; beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_GCJ='-fno-common' ;; interix3*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared_GCJ=no enable_shared=no ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_GCJ=-Kconform_pic fi ;; hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_GCJ='-fPIC' ;; esac ;; *) lt_prog_compiler_pic_GCJ='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl_GCJ='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_GCJ='-Bstatic' else lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp' fi ;; darwin*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files case $cc_basename in xlc*) lt_prog_compiler_pic_GCJ='-qnocommon' lt_prog_compiler_wl_GCJ='-Wl,' ;; esac ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl_GCJ='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_GCJ='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl_GCJ='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static_GCJ='-non_shared' ;; newsos6) lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-Bstatic' ;; linux*) case $cc_basename in icc* | ecc*) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-fpic' lt_prog_compiler_static_GCJ='-Bstatic' ;; ccc*) lt_prog_compiler_wl_GCJ='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static_GCJ='-non_shared' ;; esac ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl_GCJ='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static_GCJ='-non_shared' ;; solaris*) lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-Bstatic' case $cc_basename in f77* | f90* | f95*) lt_prog_compiler_wl_GCJ='-Qoption ld ';; *) lt_prog_compiler_wl_GCJ='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl_GCJ='-Qoption ld ' lt_prog_compiler_pic_GCJ='-PIC' lt_prog_compiler_static_GCJ='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic_GCJ='-Kconform_pic' lt_prog_compiler_static_GCJ='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-Bstatic' ;; unicos*) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_can_build_shared_GCJ=no ;; uts4*) lt_prog_compiler_pic_GCJ='-pic' lt_prog_compiler_static_GCJ='-Bstatic' ;; *) lt_prog_compiler_can_build_shared_GCJ=no ;; esac fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_GCJ"; then { echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5 echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6; } if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_pic_works_GCJ=no ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_GCJ" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:16226: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:16230: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_pic_works_GCJ=yes fi fi $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5 echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6; } if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then case $lt_prog_compiler_pic_GCJ in "" | " "*) ;; *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;; esac else lt_prog_compiler_pic_GCJ= lt_prog_compiler_can_build_shared_GCJ=no fi fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_GCJ= ;; *) lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ" ;; esac # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\" { echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_prog_compiler_static_works_GCJ=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" printf "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_static_works_GCJ=yes fi else lt_prog_compiler_static_works_GCJ=yes fi fi $rm conftest* LDFLAGS="$save_LDFLAGS" fi { echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5 echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6; } if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then : else lt_prog_compiler_static_GCJ= fi { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else lt_cv_prog_compiler_c_o_GCJ=no $rm -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:16330: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:16334: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_GCJ=yes fi fi chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files $rm out/* && rmdir out cd .. rmdir conftest $rm conftest* fi { echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5 echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { echo "$as_me:$LINENO: result: $hard_links" >&5 echo "${ECHO_T}$hard_links" >&6; } if test "$hard_links" = no; then { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } runpath_var= allow_undefined_flag_GCJ= enable_shared_with_static_runtimes_GCJ=no archive_cmds_GCJ= archive_expsym_cmds_GCJ= old_archive_From_new_cmds_GCJ= old_archive_from_expsyms_cmds_GCJ= export_dynamic_flag_spec_GCJ= whole_archive_flag_spec_GCJ= thread_safe_flag_spec_GCJ= hardcode_libdir_flag_spec_GCJ= hardcode_libdir_flag_spec_ld_GCJ= hardcode_libdir_separator_GCJ= hardcode_direct_GCJ=no hardcode_minus_L_GCJ=no hardcode_shlibpath_var_GCJ=unsupported link_all_deplibs_GCJ=unknown hardcode_automatic_GCJ=no module_cmds_GCJ= module_expsym_cmds_GCJ= always_export_symbols_GCJ=no export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms_GCJ= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_" # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. extract_expsyms_cmds= # Just being paranoid about ensuring that cc_basename is set. for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` case $host_os in cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs_GCJ=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec_GCJ= fi supports_anon_versioning=no case `$LD -v 2>/dev/null` in *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix3* | aix4* | aix5*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs_GCJ=no cat <&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. EOF fi ;; amigaos*) archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_minus_L_GCJ=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we can't use # them. ld_shlibs_GCJ=no ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_GCJ=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs_GCJ=no fi ;; cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_GCJ='-L$libdir' allow_undefined_flag_GCJ=unsupported always_export_symbols_GCJ=no enable_shared_with_static_runtimes_GCJ=yes export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_GCJ=no fi ;; interix3*) hardcode_direct_GCJ=no hardcode_shlibpath_var_GCJ=no hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' export_dynamic_flag_spec_GCJ='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; linux*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then tmp_addflag= case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; esac archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test $supports_anon_versioning = yes; then archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ $echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi else ld_shlibs_GCJ=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs_GCJ=no cat <&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. EOF elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs_GCJ=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs_GCJ=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' else ld_shlibs_GCJ=no fi ;; esac ;; sunos4*) archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct_GCJ=yes hardcode_shlibpath_var_GCJ=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs_GCJ=no fi ;; esac if test "$ld_shlibs_GCJ" = no; then runpath_var= hardcode_libdir_flag_spec_GCJ= export_dynamic_flag_spec_GCJ= whole_archive_flag_spec_GCJ= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag_GCJ=unsupported always_export_symbols_GCJ=yes archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L_GCJ=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct_GCJ=unsupported fi ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix5*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_GCJ='' hardcode_direct_GCJ=yes hardcode_libdir_separator_GCJ=':' link_all_deplibs_GCJ=yes if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 hardcode_direct_GCJ=yes else # We have old collect2 hardcode_direct_GCJ=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_GCJ=yes hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_libdir_separator_GCJ= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols_GCJ=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_GCJ='-berok' # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_GCJ="-z nodefs" archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_GCJ=' ${wl}-bernotok' allow_undefined_flag_GCJ=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_GCJ='$convenience' archive_cmds_need_lc_GCJ=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_minus_L_GCJ=yes # see comment about different semantics on the GNU ld section ld_shlibs_GCJ=no ;; bsdi[45]*) export_dynamic_flag_spec_GCJ=-rdynamic ;; cygwin* | mingw* | pw32*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_GCJ=' ' allow_undefined_flag_GCJ=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_From_new_cmds_GCJ='true' # FIXME: Should let the user specify the lib program. old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs' fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes_GCJ=yes ;; darwin* | rhapsody*) case $host_os in rhapsody* | darwin1.[012]) allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress' ;; *) # Darwin 1.3 on if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' else case ${MACOSX_DEPLOYMENT_TARGET} in 10.[012]) allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup' ;; esac fi ;; esac archive_cmds_need_lc_GCJ=no hardcode_direct_GCJ=no hardcode_automatic_GCJ=yes hardcode_shlibpath_var_GCJ=unsupported whole_archive_flag_spec_GCJ='' link_all_deplibs_GCJ=yes if test "$GCC" = yes ; then output_verbose_link_cmd='echo' archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else case $cc_basename in xlc*) output_verbose_link_cmd='echo' archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) ld_shlibs_GCJ=no ;; esac fi ;; dgux*) archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_shlibpath_var_GCJ=no ;; freebsd1*) ld_shlibs_GCJ=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec_GCJ='-R$libdir' hardcode_direct_GCJ=yes hardcode_shlibpath_var_GCJ=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_GCJ=yes hardcode_minus_L_GCJ=yes hardcode_shlibpath_var_GCJ=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | kfreebsd*-gnu | dragonfly*) archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec_GCJ='-R$libdir' hardcode_direct_GCJ=yes hardcode_shlibpath_var_GCJ=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' hardcode_libdir_separator_GCJ=: hardcode_direct_GCJ=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L_GCJ=yes export_dynamic_flag_spec_GCJ='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' hardcode_libdir_separator_GCJ=: hardcode_direct_GCJ=yes export_dynamic_flag_spec_GCJ='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L_GCJ=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' hardcode_libdir_separator_GCJ=: case $host_cpu in hppa*64*|ia64*) hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' hardcode_direct_GCJ=no hardcode_shlibpath_var_GCJ=no ;; *) hardcode_direct_GCJ=yes export_dynamic_flag_spec_GCJ='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L_GCJ=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir' fi hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_GCJ=: link_all_deplibs_GCJ=yes ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec_GCJ='-R$libdir' hardcode_direct_GCJ=yes hardcode_shlibpath_var_GCJ=no ;; newsos6) archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_GCJ=yes hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_GCJ=: hardcode_shlibpath_var_GCJ=no ;; openbsd*) hardcode_direct_GCJ=yes hardcode_shlibpath_var_GCJ=no if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' export_dynamic_flag_spec_GCJ='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec_GCJ='-R$libdir' ;; *) archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' ;; esac fi ;; os2*) hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_minus_L_GCJ=yes allow_undefined_flag_GCJ=unsupported archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag_GCJ=' -expect_unresolved \*' archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' fi hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_GCJ=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' else allow_undefined_flag_GCJ=' -expect_unresolved \*' archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec_GCJ='-rpath $libdir' fi hardcode_libdir_separator_GCJ=: ;; solaris*) no_undefined_flag_GCJ=' -z text' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' else wlarc='' archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' fi hardcode_libdir_flag_spec_GCJ='-R$libdir' hardcode_shlibpath_var_GCJ=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine linker options so we # cannot just pass the convience library names through # without $wl, iff we do not link with $LD. # Luckily, gcc supports the same syntax we need for Sun Studio. # Supported since Solaris 2.6 (maybe 2.5.1?) case $wlarc in '') whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;; *) whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; esac ;; esac link_all_deplibs_GCJ=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_direct_GCJ=yes hardcode_minus_L_GCJ=yes hardcode_shlibpath_var_GCJ=no ;; sysv4) case $host_vendor in sni) archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_GCJ=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds_GCJ='$CC -r -o $output$reload_objs' hardcode_direct_GCJ=no ;; motorola) archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var_GCJ=no ;; sysv4.3*) archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var_GCJ=no export_dynamic_flag_spec_GCJ='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var_GCJ=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs_GCJ=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) no_undefined_flag_GCJ='${wl}-z,text' archive_cmds_need_lc_GCJ=no hardcode_shlibpath_var_GCJ=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_GCJ='${wl}-z,text' allow_undefined_flag_GCJ='${wl}-z,nodefs' archive_cmds_need_lc_GCJ=no hardcode_shlibpath_var_GCJ=no hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator_GCJ=':' link_all_deplibs_GCJ=yes export_dynamic_flag_spec_GCJ='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_shlibpath_var_GCJ=no ;; *) ld_shlibs_GCJ=no ;; esac fi { echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5 echo "${ECHO_T}$ld_shlibs_GCJ" >&6; } test "$ld_shlibs_GCJ" = no && can_build_shared=no # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_GCJ" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_GCJ=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds_GCJ in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } $rm conftest* printf "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_GCJ pic_flag=$lt_prog_compiler_pic_GCJ compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ allow_undefined_flag_GCJ= if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then archive_cmds_need_lc_GCJ=no else archive_cmds_need_lc_GCJ=yes fi allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $rm conftest* { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5 echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6; } ;; esac fi ;; esac { echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix4* | aix5*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` else sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' fi sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; kfreebsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='GNU ld.so' ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; freebsd*) # from 4.6 on shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix3*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; knetbsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='GNU ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; nto-qnx*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no export_dynamic_flag_spec='${wl}-Blargedynsym' runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' shlibpath_overrides_runpath=no else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' shlibpath_overrides_runpath=yes case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { echo "$as_me:$LINENO: result: $dynamic_linker" >&5 echo "${ECHO_T}$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi { echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } hardcode_action_GCJ= if test -n "$hardcode_libdir_flag_spec_GCJ" || \ test -n "$runpath_var_GCJ" || \ test "X$hardcode_automatic_GCJ" = "Xyes" ; then # We can hardcode non-existant directories. if test "$hardcode_direct_GCJ" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no && test "$hardcode_minus_L_GCJ" != no; then # Linking always hardcodes the temporary library directory. hardcode_action_GCJ=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_GCJ=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_GCJ=unsupported fi { echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5 echo "${ECHO_T}$hardcode_action_GCJ" >&6; } if test "$hardcode_action_GCJ" = relink; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh # with your package, and you will get complaints that there are # no rules to generate ltmain.sh. if test -f "$ltmain"; then # See if we are running on zsh, and set the options which allow our commands through # without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ deplibs_check_method reload_flag reload_cmds need_locks \ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ old_postinstall_cmds old_postuninstall_cmds \ compiler_GCJ \ CC_GCJ \ LD_GCJ \ lt_prog_compiler_wl_GCJ \ lt_prog_compiler_pic_GCJ \ lt_prog_compiler_static_GCJ \ lt_prog_compiler_no_builtin_flag_GCJ \ export_dynamic_flag_spec_GCJ \ thread_safe_flag_spec_GCJ \ whole_archive_flag_spec_GCJ \ enable_shared_with_static_runtimes_GCJ \ old_archive_cmds_GCJ \ old_archive_from_new_cmds_GCJ \ predep_objects_GCJ \ postdep_objects_GCJ \ predeps_GCJ \ postdeps_GCJ \ compiler_lib_search_path_GCJ \ archive_cmds_GCJ \ archive_expsym_cmds_GCJ \ postinstall_cmds_GCJ \ postuninstall_cmds_GCJ \ old_archive_from_expsyms_cmds_GCJ \ allow_undefined_flag_GCJ \ no_undefined_flag_GCJ \ export_symbols_cmds_GCJ \ hardcode_libdir_flag_spec_GCJ \ hardcode_libdir_flag_spec_ld_GCJ \ hardcode_libdir_separator_GCJ \ hardcode_automatic_GCJ \ module_cmds_GCJ \ module_expsym_cmds_GCJ \ lt_cv_prog_compiler_c_o_GCJ \ exclude_expsyms_GCJ \ include_expsyms_GCJ; do case $var in old_archive_cmds_GCJ | \ old_archive_from_new_cmds_GCJ | \ archive_cmds_GCJ | \ archive_expsym_cmds_GCJ | \ module_cmds_GCJ | \ module_expsym_cmds_GCJ | \ old_archive_from_expsyms_cmds_GCJ | \ export_symbols_cmds_GCJ | \ extract_expsyms_cmds | reload_cmds | finish_cmds | \ postinstall_cmds | postuninstall_cmds | \ old_postinstall_cmds | old_postuninstall_cmds | \ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) # Double-quote double-evaled strings. eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ;; *) eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ;; esac done case $lt_echo in *'\$0 --fallback-echo"') lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ;; esac cfgfile="$ofile" cat <<__EOF__ >> "$cfgfile" # ### BEGIN LIBTOOL TAG CONFIG: $tagname # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_GCJ # Whether or not to disallow shared libs when runtime libs are static allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC # LTCC compiler flags. LTCFLAGS=$lt_LTCFLAGS # A language-specific compiler. CC=$lt_compiler_GCJ # Is the compiler the GNU C compiler? with_gcc=$GCC_GCJ # An ERE matcher. EGREP=$lt_EGREP # The linker used to build libraries. LD=$lt_LD_GCJ # Whether we need hard or soft links. LN_S=$lt_LN_S # A BSD-compatible nm program. NM=$lt_NM # A symbol stripping program STRIP=$lt_STRIP # Used to examine libraries when file_magic_cmd begins "file" MAGIC_CMD=$MAGIC_CMD # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_GCJ # Object file suffix (normally "o"). objext="$ac_objext" # Old archive suffix (normally "a"). libext="$libext" # Shared library suffix (normally ".so"). shrext_cmds='$shrext_cmds' # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_GCJ pic_mode=$pic_mode # What is the maximum length of a command? max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ # Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_GCJ # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Commands used to build and install an old-style archive. RANLIB=$lt_RANLIB old_archive_cmds=$lt_old_archive_cmds_GCJ old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ # Commands used to build and install a shared archive. archive_cmds=$lt_archive_cmds_GCJ archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ postinstall_cmds=$lt_postinstall_cmds postuninstall_cmds=$lt_postuninstall_cmds # Commands used to build a loadable module (assumed same as above if empty) module_cmds=$lt_module_cmds_GCJ module_expsym_cmds=$lt_module_expsym_cmds_GCJ # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. predep_objects=$lt_predep_objects_GCJ # Dependencies to place after the objects being linked to create a # shared library. postdep_objects=$lt_postdep_objects_GCJ # Dependencies to place before the objects being linked to create a # shared library. predeps=$lt_predeps_GCJ # Dependencies to place after the objects being linked to create a # shared library. postdeps=$lt_postdeps_GCJ # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$lt_file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_GCJ # Flag that forces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_GCJ # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$lt_finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_GCJ # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ # If ld is used when linking, flag to hardcode \$libdir into # a binary during linking. This must work even if \$libdir does # not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ # Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the # resulting binary. hardcode_direct=$hardcode_direct_GCJ # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$hardcode_minus_L_GCJ # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ # Set to yes if building a shared library automatically hardcodes DIR into the library # and all subsequent libraries and executables linked against it. hardcode_automatic=$hardcode_automatic_GCJ # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. variables_saved_for_relink="$variables_saved_for_relink" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_GCJ # Compile-time system search path for libraries sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$fix_srcfile_path_GCJ" # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols_GCJ # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_GCJ # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_GCJ # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_GCJ # ### END LIBTOOL TAG CONFIG: $tagname __EOF__ else # If there is no Makefile yet, we rely on a make rule to execute # `config.status --recheck' to rerun these tests and create the # libtool script then. ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` if test -f "$ltmain_in"; then test -f Makefile && make "$ltmain" fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu CC="$lt_save_CC" else tagname="" fi ;; RC) # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o objext_RC=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext printf "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $rm conftest* # Allow CC to be a program name with arguments. lt_save_CC="$CC" CC=${RC-"windres"} compiler=$CC compiler_RC=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` lt_cv_prog_compiler_c_o_RC=yes # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh # with your package, and you will get complaints that there are # no rules to generate ltmain.sh. if test -f "$ltmain"; then # See if we are running on zsh, and set the options which allow our commands through # without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ deplibs_check_method reload_flag reload_cmds need_locks \ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ old_postinstall_cmds old_postuninstall_cmds \ compiler_RC \ CC_RC \ LD_RC \ lt_prog_compiler_wl_RC \ lt_prog_compiler_pic_RC \ lt_prog_compiler_static_RC \ lt_prog_compiler_no_builtin_flag_RC \ export_dynamic_flag_spec_RC \ thread_safe_flag_spec_RC \ whole_archive_flag_spec_RC \ enable_shared_with_static_runtimes_RC \ old_archive_cmds_RC \ old_archive_from_new_cmds_RC \ predep_objects_RC \ postdep_objects_RC \ predeps_RC \ postdeps_RC \ compiler_lib_search_path_RC \ archive_cmds_RC \ archive_expsym_cmds_RC \ postinstall_cmds_RC \ postuninstall_cmds_RC \ old_archive_from_expsyms_cmds_RC \ allow_undefined_flag_RC \ no_undefined_flag_RC \ export_symbols_cmds_RC \ hardcode_libdir_flag_spec_RC \ hardcode_libdir_flag_spec_ld_RC \ hardcode_libdir_separator_RC \ hardcode_automatic_RC \ module_cmds_RC \ module_expsym_cmds_RC \ lt_cv_prog_compiler_c_o_RC \ exclude_expsyms_RC \ include_expsyms_RC; do case $var in old_archive_cmds_RC | \ old_archive_from_new_cmds_RC | \ archive_cmds_RC | \ archive_expsym_cmds_RC | \ module_cmds_RC | \ module_expsym_cmds_RC | \ old_archive_from_expsyms_cmds_RC | \ export_symbols_cmds_RC | \ extract_expsyms_cmds | reload_cmds | finish_cmds | \ postinstall_cmds | postuninstall_cmds | \ old_postinstall_cmds | old_postuninstall_cmds | \ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) # Double-quote double-evaled strings. eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ;; *) eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ;; esac done case $lt_echo in *'\$0 --fallback-echo"') lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ;; esac cfgfile="$ofile" cat <<__EOF__ >> "$cfgfile" # ### BEGIN LIBTOOL TAG CONFIG: $tagname # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_RC # Whether or not to disallow shared libs when runtime libs are static allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC # LTCC compiler flags. LTCFLAGS=$lt_LTCFLAGS # A language-specific compiler. CC=$lt_compiler_RC # Is the compiler the GNU C compiler? with_gcc=$GCC_RC # An ERE matcher. EGREP=$lt_EGREP # The linker used to build libraries. LD=$lt_LD_RC # Whether we need hard or soft links. LN_S=$lt_LN_S # A BSD-compatible nm program. NM=$lt_NM # A symbol stripping program STRIP=$lt_STRIP # Used to examine libraries when file_magic_cmd begins "file" MAGIC_CMD=$MAGIC_CMD # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_RC # Object file suffix (normally "o"). objext="$ac_objext" # Old archive suffix (normally "a"). libext="$libext" # Shared library suffix (normally ".so"). shrext_cmds='$shrext_cmds' # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_RC pic_mode=$pic_mode # What is the maximum length of a command? max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC # Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_RC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Commands used to build and install an old-style archive. RANLIB=$lt_RANLIB old_archive_cmds=$lt_old_archive_cmds_RC old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC # Commands used to build and install a shared archive. archive_cmds=$lt_archive_cmds_RC archive_expsym_cmds=$lt_archive_expsym_cmds_RC postinstall_cmds=$lt_postinstall_cmds postuninstall_cmds=$lt_postuninstall_cmds # Commands used to build a loadable module (assumed same as above if empty) module_cmds=$lt_module_cmds_RC module_expsym_cmds=$lt_module_expsym_cmds_RC # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. predep_objects=$lt_predep_objects_RC # Dependencies to place after the objects being linked to create a # shared library. postdep_objects=$lt_postdep_objects_RC # Dependencies to place before the objects being linked to create a # shared library. predeps=$lt_predeps_RC # Dependencies to place after the objects being linked to create a # shared library. postdeps=$lt_postdeps_RC # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_RC # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$lt_file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_RC # Flag that forces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_RC # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$lt_finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_RC # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC # If ld is used when linking, flag to hardcode \$libdir into # a binary during linking. This must work even if \$libdir does # not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC # Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the # resulting binary. hardcode_direct=$hardcode_direct_RC # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$hardcode_minus_L_RC # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_RC # Set to yes if building a shared library automatically hardcodes DIR into the library # and all subsequent libraries and executables linked against it. hardcode_automatic=$hardcode_automatic_RC # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. variables_saved_for_relink="$variables_saved_for_relink" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_RC # Compile-time system search path for libraries sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$fix_srcfile_path_RC" # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols_RC # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_RC # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_RC # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_RC # ### END LIBTOOL TAG CONFIG: $tagname __EOF__ else # If there is no Makefile yet, we rely on a make rule to execute # `config.status --recheck' to rerun these tests and create the # libtool script then. ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` if test -f "$ltmain_in"; then test -f Makefile && make "$ltmain" fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu CC="$lt_save_CC" ;; *) { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5 echo "$as_me: error: Unsupported tag name: $tagname" >&2;} { (exit 1); exit 1; }; } ;; esac # Append the new tag name to the list of available tags. if test -n "$tagname" ; then available_tags="$available_tags $tagname" fi fi done IFS="$lt_save_ifs" # Now substitute the updated list of available tags. if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then mv "${ofile}T" "$ofile" chmod +x "$ofile" else rm -f "${ofile}T" { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5 echo "$as_me: error: unable to update list of available tagged configurations." >&2;} { (exit 1); exit 1; }; } fi fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' # Prevent multiple expansion am__api_version="1.9" # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { echo "$as_me:$LINENO: checking whether build environment is sane" >&5 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm -f conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then # We used to keeping the `.' as first argument, in order to # allow $(mkdir_p) to be used without argument. As in # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. However this is wrong # for two reasons: # 1. if the package is installed by a user who cannot write `.' # make install will fail, # 2. the above comment should most certainly read # $(mkdir_p) $(DESTDIR)$(somedir) # so it does not work when $(somedir) is undefined and # $(DESTDIR) is not. # To support the latter case, we have to write # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), # so the `.' trick is pointless. mkdir_p='mkdir -p --' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. for d in ./-p ./--version; do test -d $d && rmdir $d done # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. if test -f "$ac_aux_dir/mkinstalldirs"; then mkdir_p='$(mkinstalldirs)' else mkdir_p='$(install_sh) -d' fi fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$AWK" && break done { echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } SET_MAKE= else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi { echo "$as_me:$LINENO: result: $_am_result" >&5 echo "${ECHO_T}$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=indi VERSION=0.5 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} install_sh=${install_sh-"$am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' depcc="$CC" am_compiler_list= { echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi depcc="$CXX" am_compiler_list= { echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi timezone_int=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { daylight = 0; timezone = 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define TIMEZONE_IS_INT 1 _ACEOF else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >>confdefs.h <<\_ACEOF #define TIMEZONE_IS_INT 0 _ACEOF fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # INDI driver for the FLI CCD case "${host_os}" in *linux* ) OSDIR=linux ;; *bsd* ) OSDIR=bsd ;; * ) OSDIR=null ;; esac # This variable to is check for the availability of libusb have_libusb="no" # Check whether --enable-libusb was given. if test "${enable_libusb+set}" = set; then enableval=$enable_libusb; case ${enableval} in "" | "yes" | "YES") ;; "no" | "NO") use_libusb=false ;; *) CPPFLAGS="$CPPFLAGS -I${enableval}/include" LDFLAGS="$LDFLAGS -L${enableval}/lib" ;; esac fi if test "${use_libusb}" != false ; then for ac_header in usb.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_cxx_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF have_libusb="yes" else { echo "$as_me:$LINENO: WARNING: usb.h not found, use --enable-libusb=PATH. Otherwise, INDI will compile without Apogee & SBIG USB support." >&5 echo "$as_me: WARNING: usb.h not found, use --enable-libusb=PATH. Otherwise, INDI will compile without Apogee & SBIG USB support." >&2;} fi done ac_save_LIBS="$LIBS" LIBS="$LIBS $COREFOUNDATION $IOKIT" { echo "$as_me:$LINENO: checking for usb_init in -lusb" >&5 echo $ECHO_N "checking for usb_init in -lusb... $ECHO_C" >&6; } if test "${ac_cv_lib_usb_usb_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lusb $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char usb_init (); int main () { return usb_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_usb_usb_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_usb_usb_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_usb_usb_init" >&5 echo "${ECHO_T}$ac_cv_lib_usb_usb_init" >&6; } if test $ac_cv_lib_usb_usb_init = yes; then LIBUSB="$LIBUSB -lusb" have_libusb="yes" else { echo "$as_me:$LINENO: WARNING: libusb not found. INDI will compile without Apogee & SBIG USB support." >&5 echo "$as_me: WARNING: libusb not found. INDI will compile without Apogee & SBIG USB support." >&2;} fi LIBS="$ac_save_LIBS" fi have_cfitsio=false ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu LDFLAGS="$LDFLAGS -lm -lz" { echo "$as_me:$LINENO: checking for ffppx in -lcfitsio" >&5 echo $ECHO_N "checking for ffppx in -lcfitsio... $ECHO_C" >&6; } if test "${ac_cv_lib_cfitsio_ffppx+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcfitsio $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ffppx (); int main () { return ffppx (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_cfitsio_ffppx=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_cfitsio_ffppx=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_cfitsio_ffppx" >&5 echo "${ECHO_T}$ac_cv_lib_cfitsio_ffppx" >&6; } if test $ac_cv_lib_cfitsio_ffppx = yes; then LIBS="-lcfitsio $LIBS" else EXTRA_SUBDIR="cfitsio" LIBCFITSIO="cfitsio/libcfitsio.la" fi LDFLAGS="-lusb $LDFLAGS" { echo "$as_me:$LINENO: checking for SBIGUnivDrvCommand in -lsbigudrv" >&5 echo $ECHO_N "checking for SBIGUnivDrvCommand in -lsbigudrv... $ECHO_C" >&6; } if test "${ac_cv_lib_sbigudrv_SBIGUnivDrvCommand+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsbigudrv $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SBIGUnivDrvCommand (); int main () { return SBIGUnivDrvCommand (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_sbigudrv_SBIGUnivDrvCommand=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_sbigudrv_SBIGUnivDrvCommand=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_sbigudrv_SBIGUnivDrvCommand" >&5 echo "${ECHO_T}$ac_cv_lib_sbigudrv_SBIGUnivDrvCommand" >&6; } if test $ac_cv_lib_sbigudrv_SBIGUnivDrvCommand = yes; then have_libsbigudrv=true LIBSBIGUDRV="-lsbigudrv" else have_libsbigudrv=false LIBSBIGUDRV="libsbigudrv.la" fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu have_v4l2=false case "$target" in *-*-linux*) # Check whether --enable-v4l2 was given. if test "${enable_v4l2+set}" = set; then enableval=$enable_v4l2; case "${enableval}" in no) disable_v4l2=yes ;; yes) disable_v4l2=no ;; *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --disable-v4l2" >&5 echo "$as_me: error: bad value ${enableval} for --disable-v4l2" >&2;} { (exit 1); exit 1; }; } ;; esac else disable_v4l2=no fi if test x$disable_v4l2 = xno; then { echo "$as_me:$LINENO: checking for struct v4l2_buffer" >&5 echo $ECHO_N "checking for struct v4l2_buffer... $ECHO_C" >&6; } if test "${ac_cv_type_struct_v4l2_buffer+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include typedef struct v4l2_buffer ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_struct_v4l2_buffer=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_struct_v4l2_buffer=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_struct_v4l2_buffer" >&5 echo "${ECHO_T}$ac_cv_type_struct_v4l2_buffer" >&6; } if test $ac_cv_type_struct_v4l2_buffer = yes; then have_v4l2=true else have_v4l2=false fi if test x$have_v4l2 = xfalse; then KERNEL_VERSION=`uname -r` as_ac_File=`echo "ac_cv_file_/lib/modules/$KERNEL_VERSION/build/include/linux/videodev2.h" | $as_tr_sh` { echo "$as_me:$LINENO: checking for /lib/modules/$KERNEL_VERSION/build/include/linux/videodev2.h" >&5 echo $ECHO_N "checking for /lib/modules/$KERNEL_VERSION/build/include/linux/videodev2.h... $ECHO_C" >&6; } if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else test "$cross_compiling" = yes && { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} { (exit 1); exit 1; }; } if test -r "/lib/modules/$KERNEL_VERSION/build/include/linux/videodev2.h"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi ac_res=`eval echo '${'$as_ac_File'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_File'}'` = yes; then have_v4l2=true else { echo "$as_me:$LINENO: WARNING: " >&5 echo "$as_me: WARNING: " >&2;} { echo "$as_me:$LINENO: WARNING: " >&5 echo "$as_me: WARNING: " >&2;} { echo "$as_me:$LINENO: WARNING: We cannot locate videodev2.h in /usr/include/linux" >&5 echo "$as_me: WARNING: We cannot locate videodev2.h in /usr/include/linux" >&2;} { echo "$as_me:$LINENO: WARNING: This file is responsible for V4L2 in INDI" >&5 echo "$as_me: WARNING: This file is responsible for V4L2 in INDI" >&2;} { echo "$as_me:$LINENO: WARNING: INDI will be compiled with legacy V4L 1 support." >&5 echo "$as_me: WARNING: INDI will be compiled with legacy V4L 1 support." >&2;} { echo "$as_me:$LINENO: WARNING: " >&5 echo "$as_me: WARNING: " >&2;} { echo "$as_me:$LINENO: WARNING: " >&5 echo "$as_me: WARNING: " >&2;} fi fi else have_v4l2=false fi ;; *) ;; esac if test x$have_v4l2 = xtrue; then cat >>confdefs.h <<\_ACEOF #define HAVE_LINUX_VIDEODEV2_H 1 _ACEOF fi if test x$OSDIR = xbsd; then BSD_TRUE= BSD_FALSE='#' else BSD_TRUE='#' BSD_FALSE= fi if test x$OSDIR = xlinux; then LINUX_TRUE= LINUX_FALSE='#' else LINUX_TRUE='#' LINUX_FALSE= fi if test x$OSDIR = xnull; then NULL_TRUE= NULL_FALSE='#' else NULL_TRUE='#' NULL_FALSE= fi if test x$have_libusb = xyes; then HAVE_LIBUSB_TRUE= HAVE_LIBUSB_FALSE='#' else HAVE_LIBUSB_TRUE='#' HAVE_LIBUSB_FALSE= fi if test x$have_v4l2 = xtrue; then HAVE_V4L2_TRUE= HAVE_V4L2_FALSE='#' else HAVE_V4L2_TRUE='#' HAVE_V4L2_FALSE= fi if test x$have_libsbigudrv = xtrue; then HAVE_LIBSBIGUDRV_TRUE= HAVE_LIBSBIGUDRV_FALSE='#' else HAVE_LIBSBIGUDRV_TRUE='#' HAVE_LIBSBIGUDRV_FALSE= fi ac_config_files="$ac_config_files Makefile src/Makefile src/fli/Makefile src/webcam/Makefile src/apogee/Makefile src/cfitsio/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { echo "$as_me:$LINENO: updating cache $cache_file" >&5 echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${BSD_TRUE}" && test -z "${BSD_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"BSD\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"BSD\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"LINUX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"LINUX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${NULL_TRUE}" && test -z "${NULL_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"NULL\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"NULL\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${HAVE_LIBUSB_TRUE}" && test -z "${HAVE_LIBUSB_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"HAVE_LIBUSB\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"HAVE_LIBUSB\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${HAVE_V4L2_TRUE}" && test -z "${HAVE_V4L2_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"HAVE_V4L2\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"HAVE_V4L2\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${HAVE_LIBSBIGUDRV_TRUE}" && test -z "${HAVE_LIBSBIGUDRV_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"HAVE_LIBSBIGUDRV\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"HAVE_LIBSBIGUDRV\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # Find out whether ``test -x'' works. Don't use a zero-byte file, as # systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then as_executable_p="test -x" else as_executable_p=: fi rm -f conf$$.file # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.60. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.60, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=$SHELL export CONFIG_SHELL exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/fli/Makefile") CONFIG_FILES="$CONFIG_FILES src/fli/Makefile" ;; "src/webcam/Makefile") CONFIG_FILES="$CONFIG_FILES src/webcam/Makefile" ;; "src/apogee/Makefile") CONFIG_FILES="$CONFIG_FILES src/apogee/Makefile" ;; "src/cfitsio/Makefile") CONFIG_FILES="$CONFIG_FILES src/cfitsio/Makefile" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # # Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "$CONFIG_FILES"; then _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF SHELL!$SHELL$ac_delim PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim PACKAGE_NAME!$PACKAGE_NAME$ac_delim PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim PACKAGE_STRING!$PACKAGE_STRING$ac_delim PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim exec_prefix!$exec_prefix$ac_delim prefix!$prefix$ac_delim program_transform_name!$program_transform_name$ac_delim bindir!$bindir$ac_delim sbindir!$sbindir$ac_delim libexecdir!$libexecdir$ac_delim datarootdir!$datarootdir$ac_delim datadir!$datadir$ac_delim sysconfdir!$sysconfdir$ac_delim sharedstatedir!$sharedstatedir$ac_delim localstatedir!$localstatedir$ac_delim includedir!$includedir$ac_delim oldincludedir!$oldincludedir$ac_delim docdir!$docdir$ac_delim infodir!$infodir$ac_delim htmldir!$htmldir$ac_delim dvidir!$dvidir$ac_delim pdfdir!$pdfdir$ac_delim psdir!$psdir$ac_delim libdir!$libdir$ac_delim localedir!$localedir$ac_delim mandir!$mandir$ac_delim DEFS!$DEFS$ac_delim ECHO_C!$ECHO_C$ac_delim ECHO_N!$ECHO_N$ac_delim ECHO_T!$ECHO_T$ac_delim LIBS!$LIBS$ac_delim build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim build!$build$ac_delim build_cpu!$build_cpu$ac_delim build_vendor!$build_vendor$ac_delim build_os!$build_os$ac_delim host!$host$ac_delim host_cpu!$host_cpu$ac_delim host_vendor!$host_vendor$ac_delim host_os!$host_os$ac_delim target!$target$ac_delim target_cpu!$target_cpu$ac_delim target_vendor!$target_vendor$ac_delim target_os!$target_os$ac_delim CXX!$CXX$ac_delim CXXFLAGS!$CXXFLAGS$ac_delim LDFLAGS!$LDFLAGS$ac_delim CPPFLAGS!$CPPFLAGS$ac_delim ac_ct_CXX!$ac_ct_CXX$ac_delim EXEEXT!$EXEEXT$ac_delim OBJEXT!$OBJEXT$ac_delim CC!$CC$ac_delim CFLAGS!$CFLAGS$ac_delim ac_ct_CC!$ac_ct_CC$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim LN_S!$LN_S$ac_delim ECHO!$ECHO$ac_delim AR!$AR$ac_delim RANLIB!$RANLIB$ac_delim STRIP!$STRIP$ac_delim CPP!$CPP$ac_delim CXXCPP!$CXXCPP$ac_delim F77!$F77$ac_delim FFLAGS!$FFLAGS$ac_delim ac_ct_F77!$ac_ct_F77$ac_delim LIBTOOL!$LIBTOOL$ac_delim INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim INSTALL_DATA!$INSTALL_DATA$ac_delim CYGPATH_W!$CYGPATH_W$ac_delim PACKAGE!$PACKAGE$ac_delim VERSION!$VERSION$ac_delim ACLOCAL!$ACLOCAL$ac_delim AUTOCONF!$AUTOCONF$ac_delim AUTOMAKE!$AUTOMAKE$ac_delim AUTOHEADER!$AUTOHEADER$ac_delim MAKEINFO!$MAKEINFO$ac_delim install_sh!$install_sh$ac_delim INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim mkdir_p!$mkdir_p$ac_delim AWK!$AWK$ac_delim SET_MAKE!$SET_MAKE$ac_delim am__leading_dot!$am__leading_dot$ac_delim AMTAR!$AMTAR$ac_delim am__tar!$am__tar$ac_delim am__untar!$am__untar$ac_delim DEPDIR!$DEPDIR$ac_delim am__include!$am__include$ac_delim am__quote!$am__quote$ac_delim AMDEP_TRUE!$AMDEP_TRUE$ac_delim AMDEP_FALSE!$AMDEP_FALSE$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF CEOF$ac_eof _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim CCDEPMODE!$CCDEPMODE$ac_delim am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim CXXDEPMODE!$CXXDEPMODE$ac_delim am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim LIBUSB!$LIBUSB$ac_delim LIBCFITSIO!$LIBCFITSIO$ac_delim EXTRA_SUBDIR!$EXTRA_SUBDIR$ac_delim LIBSBIGUDRV!$LIBSBIGUDRV$ac_delim BSD_TRUE!$BSD_TRUE$ac_delim BSD_FALSE!$BSD_FALSE$ac_delim LINUX_TRUE!$LINUX_TRUE$ac_delim LINUX_FALSE!$LINUX_FALSE$ac_delim NULL_TRUE!$NULL_TRUE$ac_delim NULL_FALSE!$NULL_FALSE$ac_delim HAVE_LIBUSB_TRUE!$HAVE_LIBUSB_TRUE$ac_delim HAVE_LIBUSB_FALSE!$HAVE_LIBUSB_FALSE$ac_delim HAVE_V4L2_TRUE!$HAVE_V4L2_TRUE$ac_delim HAVE_V4L2_FALSE!$HAVE_V4L2_FALSE$ac_delim HAVE_LIBSBIGUDRV_TRUE!$HAVE_LIBSBIGUDRV_TRUE$ac_delim HAVE_LIBSBIGUDRV_FALSE!$HAVE_LIBSBIGUDRV_FALSE$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 25; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF :end s/|#_!!_#|//g CEOF$ac_eof _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF fi # test -n "$CONFIG_FILES" for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$ac_file_inputs $ac_f" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input="Generated from "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= case `sed -n '/datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' $ac_file_inputs` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s&@configure_input@&$configure_input&;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out"; rm -f "$tmp/out";; *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; esac ;; :H) # # CONFIG_HEADER # _ACEOF # Transform confdefs.h into a sed script `conftest.defines', that # substitutes the proper values into config.h.in to produce config.h. rm -f conftest.defines conftest.tail # First, append a space to every undef/define line, to ease matching. echo 's/$/ /' >conftest.defines # Then, protect against being on the right side of a sed subst, or in # an unquoted here document, in config.status. If some macros were # called several times there might be several #defines for the same # symbol, which is useless. But do not sort them, since the last # AC_DEFINE must be honored. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* # These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where # NAME is the cpp macro being defined, VALUE is the value it is being given. # PARAMS is the parameter list in the macro definition--in most cases, it's # just an empty string. ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' ac_dB='\\)[ (].*,\\1define\\2' ac_dC=' ' ac_dD=' ,' uniq confdefs.h | sed -n ' t rset :rset s/^[ ]*#[ ]*define[ ][ ]*// t ok d :ok s/[\\&,]/\\&/g s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p ' >>conftest.defines # Remove the space that was appended to ease matching. # Then replace #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. # (The regexp can be short, since the line contains either #define or #undef.) echo 's/ $// s,^[ #]*u.*,/* & */,' >>conftest.defines # Break up conftest.defines: ac_max_sed_lines=50 # First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" # Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" # Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" # et cetera. ac_in='$ac_file_inputs' ac_out='"$tmp/out1"' ac_nxt='"$tmp/out2"' while : do # Write a here document: cat >>$CONFIG_STATUS <<_ACEOF # First, check the format of the line: cat >"\$tmp/defines.sed" <<\\CEOF /^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def /^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def b :def _ACEOF sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail grep . conftest.tail >/dev/null || break rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines conftest.tail echo "ac_result=$ac_in" >>$CONFIG_STATUS cat >>$CONFIG_STATUS <<\_ACEOF if test x"$ac_file" != x-; then echo "/* $configure_input */" >"$tmp/config.h" cat "$ac_result" >>"$tmp/config.h" if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else rm -f $ac_file mv "$tmp/config.h" $ac_file fi else echo "/* $configure_input */" cat "$ac_result" fi rm -f "$tmp/out12" # Compute $ac_file's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $ac_file | $ac_file:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $ac_file" >`$as_dirname -- $ac_file || $as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X$ac_file : 'X\(//\)[^/]' \| \ X$ac_file : 'X\(//\)$' \| \ X$ac_file : 'X\(/\)' \| . 2>/dev/null || echo X$ac_file | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir=$dirpart/$fdir case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi indi-0.5/Doxyfile0000644000175000017500000003122210605175720011622 0ustar jrjr# Doxyfile 1.4.1-KDevelop #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- PROJECT_NAME = "Instrument Neutral Distributed Interface INDI" PROJECT_NUMBER = 0.5 OUTPUT_DIRECTORY = /home/slovin/Projects/doc CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English USE_WINDOWS_ENCODING = NO BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = NO STRIP_FROM_PATH = STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO INHERIT_DOCS = YES DISTRIBUTE_GROUP_DOC = NO TAB_SIZE = 8 ALIASES = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = NO EXTRACT_PRIVATE = NO EXTRACT_STATIC = NO EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = NO HIDE_UNDOC_MEMBERS = YES HIDE_UNDOC_CLASSES = YES HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_DIRECTORIES = YES FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = /home/slovin/Projects/indi/src FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.idl \ *.odl \ *.cs \ *.php \ *.php3 \ *.inc \ *.C \ *.H \ *.tlh \ *.diff \ *.patch \ *.moc \ *.xpm \ *.dox RECURSIVE = YES EXCLUDE = /home/slovin/Projects/indi/src/fli \ /home/slovin/Projects/indi/src/lzo \ /home/slovin/Projects/indi/src/webcam \ /home/slovin/Projects/indi/src/celestrongps.cpp \ /home/slovin/Projects/indi/src/celestrongps.h \ /home/slovin/Projects/indi/src/celestronprotocol.c \ /home/slovin/Projects/indi/src/celestronprotocol.h \ /home/slovin/Projects/indi/src/fli_ccd.c \ /home/slovin/Projects/indi/src/lx200_16.cpp \ /home/slovin/Projects/indi/src/lx200_16.h \ /home/slovin/Projects/indi/src/lx200autostar.cpp \ /home/slovin/Projects/indi/src/lx200autostar.h \ /home/slovin/Projects/indi/src/lx200classic.cpp \ /home/slovin/Projects/indi/src/lx200classic.h \ /home/slovin/Projects/indi/src/lx200driver.c \ /home/slovin/Projects/indi/src/lx200driver.h \ /home/slovin/Projects/indi/src/lx200generic.cpp \ /home/slovin/Projects/indi/src/lx200generic.h \ /home/slovin/Projects/indi/src/lx200gps.cpp \ /home/slovin/Projects/indi/src/lx200gps.h \ /home/slovin/Projects/indi/src/mount_simulation.c \ /home/slovin/Projects/indi/src/v4ldriver.cpp \ /home/slovin/Projects/indi/src/v4lphilips.cpp \ /home/slovin/Projects/indi/src/eventloop.c \ /home/slovin/Projects/indi/src/fitsrw.c \ /home/slovin/Projects/indi/src/indicom.c \ /home/slovin/Projects/indi/src/indidrivermain.c \ /home/slovin/Projects/indi/src/lilxml.c \ /home/slovin/Projects/indi/src/apogee \ /home/slovin/Projects/indi/src/apmount.cpp \ /home/slovin/Projects/indi/src/apmount.h \ /home/slovin/Projects/indi/src/apogee_ppi.cpp \ /home/slovin/Projects/indi/src/apogee_ppi.h \ /home/slovin/Projects/indi/src/base64.h \ /home/slovin/Projects/indi/src/fq.h \ /home/slovin/Projects/indi/src/indi_lpi.cpp \ /home/slovin/Projects/indi/src/indi_philips.cpp \ /home/slovin/Projects/indi/src/indi_v4l.cpp \ /home/slovin/Projects/indi/src/sbigccd.cpp \ /home/slovin/Projects/indi/src/sbigccd.h \ /home/slovin/Projects/indi/src/temmadriver.c \ /home/slovin/Projects/indi/src/temmadriver.h \ /home/slovin/Projects/indi/src/v4ldriver.cpp \ /home/slovin/Projects/indi/src/v4lphilips.cpp \ /home/slovin/Projects/indi/src/fli_wheel.c \ /home/slovin/Projects/indi/src/v4ldriver.h \ /home/slovin/Projects/indi/src/v4lphilips.h \ /home/slovin/Projects/indi/src/indiserver.c \ /home/slovin/Projects/indi/src/examples/tutorial_ccdpreview.c \ /home/slovin/Projects/indi/src/examples/tutorial_ccdpreview.c \ /home/slovin/Projects/indi/src/tools/compiler.c EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXAMPLE_PATH = EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = YES INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = YES COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = doc HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = NO LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = NO USE_PDFLATEX = NO LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml XML_SCHEMA = XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = MAX_DOT_GRAPH_WIDTH = 1024 MAX_DOT_GRAPH_HEIGHT = 1024 MAX_DOT_GRAPH_DEPTH = 1000 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO indi-0.5/src/0000755000175000017500000000000011017761434010704 5ustar jrjrindi-0.5/src/fli_ccd.c0000644000175000017500000010765710610474331012446 0ustar jrjr#if 0 FLI CCD INDI Interface for Finger Lakes Instruments CCDs Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fli/libfli.h" #include "cfitsio/fitsio.h" #include "indidevapi.h" #include "eventloop.h" #include "indicom.h" void ISInit(void); void getBasicData(void); void ISPoll(void *); void handleExposure(void *); void connectCCD(void); void getBasicData(void); void uploadFile(const char* filename); int writeFITS(const char* filename, char errmsg[]); int findcam(flidomain_t domain); int setImageArea(char errmsg[]); int manageDefaults(char errmsg[]); int grabImage(void); int checkPowerS(ISwitchVectorProperty *sp); int checkPowerN(INumberVectorProperty *np); int checkPowerT(ITextVectorProperty *tp); int getOnSwitch(ISwitchVectorProperty *sp); int isCCDConnected(void); void addFITSKeywords(fitsfile *fptr); double min(void); double max(void); extern char* me; extern int errno; #define mydev "FLI CCD" #define COMM_GROUP "Communication" #define EXPOSE_GROUP "Expose" #define IMAGE_GROUP "Image Settings" #define DATA_GROUP "Data Channel" #define MAX_CCD_TEMP 45 /* Max CCD temperature */ #define MIN_CCD_TEMP -55 /* Min CCD temperature */ #define MAX_X_BIN 16. /* Max Horizontal binning */ #define MAX_Y_BIN 16. /* Max Vertical binning */ #define MAX_PIXELS 4096 /* Max number of pixels in one dimension */ #define POLLMS 1000 /* Polling time (ms) */ #define TEMP_THRESHOLD .25 /* Differential temperature threshold (C)*/ #define NFLUSHES 1 /* Number of times a CCD array is flushed before an exposure */ #define FILENAMESIZ 2048 #define LIBVERSIZ 1024 #define PREFIXSIZ 64 #define PIPEBUFSIZ 8192 #define FRAME_ILEN 64 #define TEMPFILE_LEN 16 enum FLIFrames { LIGHT_FRAME = 0, BIAS_FRAME, DARK_FRAME, FLAT_FRAME }; typedef struct { flidomain_t domain; char *dname; char *name; char *model; long HWRevision; long FWRevision; double x_pixel_size; double y_pixel_size; long Array_Area[4]; long Visible_Area[4]; int width, height; double temperature; } cam_t; typedef struct { int width; int height; int frameType; int expose; unsigned short *img; } img_t; /*static int streamTimerID; Stream ID */ static flidev_t fli_dev; static cam_t *FLICam; static img_t *FLIImg; static int portSwitchIndex; long int Domains[] = { FLIDOMAIN_USB, FLIDOMAIN_SERIAL, FLIDOMAIN_PARALLEL_PORT, FLIDOMAIN_INET }; /*INDI controls */ /* Connect/Disconnect */ static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}}; static ISwitchVectorProperty PowerSP = { mydev, "CONNECTION" , "Connection", COMM_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0}; /* Types of Ports */ static ISwitch PortS[] = {{"USB", "", ISS_ON, 0, 0}, {"Serial", "", ISS_OFF, 0, 0}, {"Parallel", "", ISS_OFF, 0, 0}, {"INet", "", ISS_OFF, 0, 0}}; static ISwitchVectorProperty PortSP = { mydev, "Port Type", "", COMM_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, PortS, NARRAY(PortS), "", 0}; /* Types of Frames */ static ISwitch FrameTypeS[] = { {"FRAME_LIGHT", "Light", ISS_ON, 0, 0}, {"FRAME_BIAS", "Bias", ISS_OFF, 0, 0}, {"FRAME_DARK", "Dark", ISS_OFF, 0, 0}, {"FRAME_FLAT", "Flat Field", ISS_OFF, 0, 0}}; static ISwitchVectorProperty FrameTypeSP = { mydev, "CCD_FRAME_TYPE", "Frame Type", EXPOSE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, FrameTypeS, NARRAY(FrameTypeS), "", 0}; /* Frame coordinates. Full frame is default */ static INumber FrameN[] = { { "X", "X", "%.0f", 0., MAX_PIXELS, 1., 0., 0, 0, 0}, { "Y", "Y", "%.0f", 0., MAX_PIXELS, 1., 0., 0, 0, 0}, { "WIDTH", "Width", "%.0f", 0., MAX_PIXELS, 1., 0., 0, 0, 0}, { "HEIGHT", "Height", "%.0f",0., MAX_PIXELS, 1., 0., 0, 0, 0}}; static INumberVectorProperty FrameNP = { mydev, "CCD_FRAME", "Frame", IMAGE_GROUP, IP_RW, 60, IPS_IDLE, FrameN, NARRAY(FrameN), "", 0}; /* Binning */ static INumber BinningN[] = { { "HOR_BIN", "X", "%0.f", 1., MAX_X_BIN, 1., 1., 0, 0, 0}, { "VER_BIN", "Y", "%0.f", 1., MAX_Y_BIN, 1., 1., 0, 0, 0}}; static INumberVectorProperty BinningNP = { mydev, "CCD_BINNING", "Binning", IMAGE_GROUP, IP_RW, 60, IPS_IDLE, BinningN, NARRAY(BinningN), "", 0}; /* Exposure time */ static INumber ExposeTimeN[] = {{ "EXPOSE_DURATION", "Duration (s)", "%5.2f", 0., 36000., .5, 1., 0, 0, 0}}; static INumberVectorProperty ExposeTimeNP = { mydev, "CCD_EXPOSE_DURATION", "Expose", EXPOSE_GROUP, IP_RW, 60, IPS_IDLE, ExposeTimeN, NARRAY(ExposeTimeN), "", 0}; /* Temperature control */ static INumber TemperatureN[] = { {"TEMPERATURE", "Temperature", "%+06.2f", MIN_CCD_TEMP, MAX_CCD_TEMP, .2, 0., 0, 0, 0}}; static INumberVectorProperty TemperatureNP = { mydev, "CCD_TEMPERATURE", "Temperature (C)", EXPOSE_GROUP, IP_RW, 60, IPS_IDLE, TemperatureN, NARRAY(TemperatureN), "", 0}; /* Pixel size (µm) */ static INumber PixelSizeN[] = { { "Width", "", "%.0f", 0. , 0., 0., 0., 0, 0, 0}, { "Height", "", "%.0f", 0. , 0., 0., 0., 0, 0, 0}}; static INumberVectorProperty PixelSizeNP = { mydev, "Pixel Size (µm)", "", DATA_GROUP, IP_RO, 0, IPS_IDLE, PixelSizeN, NARRAY(PixelSizeN), "", 0}; /* BLOB for sending image */ static IBLOB imageB = {"CCD1", "Feed", "", 0, 0, 0, 0, 0, 0, 0}; static IBLOBVectorProperty imageBP = {mydev, "Video", "Video", COMM_GROUP, IP_RO, 0, IPS_IDLE, &imageB, 1, "", 0}; /* send client definitions of all properties */ void ISInit() { static int isInit=0; if (isInit) return; /* USB by default {USB, SERIAL, PARALLEL, INET} */ portSwitchIndex = 0; FLIImg = malloc (sizeof(img_t)); if (FLIImg == NULL) { IDMessage(mydev, "Error: unable to initialize driver. Low memory."); IDLog("Error: unable to initialize driver. Low memory."); return; } IEAddTimer (POLLMS, ISPoll, NULL); isInit = 1; } void ISGetProperties (const char *dev) { ISInit(); if (dev && strcmp (mydev, dev)) return; /* COMM_GROUP */ IDDefSwitch(&PowerSP, NULL); IDDefSwitch(&PortSP, NULL); IDDefBLOB(&imageBP, NULL); /* Expose */ IDDefSwitch(&FrameTypeSP, NULL); IDDefNumber(&ExposeTimeNP, NULL); IDDefNumber(&TemperatureNP, NULL); /* Image Group */ IDDefNumber(&FrameNP, NULL); IDDefNumber(&BinningNP, NULL); } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n) { dev=dev;name=name;sizes=sizes;blobs=blobs;formats=formats;names=names;n=n; } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { long err; int i; ISwitch *sp; /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; ISInit(); /* Port type */ if (!strcmp (name, PortSP.name)) { PortSP.s = IPS_IDLE; IUResetSwitches(&PortSP); IUUpdateSwitches(&PortSP, states, names, n); portSwitchIndex = getOnSwitch(&PortSP); PortSP.s = IPS_OK; IDSetSwitch(&PortSP, NULL); return; } /* Connection */ if (!strcmp (name, PowerSP.name)) { IUResetSwitches(&PowerSP); IUUpdateSwitches(&PowerSP, states, names, n); connectCCD(); return; } /* Frame Type */ if (!strcmp(FrameTypeSP.name, name)) { if (checkPowerS(&FrameTypeSP)) return; FrameTypeSP.s = IPS_IDLE; for (i = 0; i < n ; i++) { sp = IUFindSwitch(&FrameTypeSP, names[i]); if (!sp) { IDSetSwitch(&FrameTypeSP, "Unknown error. %s is not a member of %s property.", names[0], name); return; } /* NORMAL, BIAS, or FLAT */ if ( (sp == &FrameTypeS[LIGHT_FRAME] || sp == &FrameTypeS[FLAT_FRAME]) && states[i] == ISS_ON) { if (sp == &FrameTypeS[LIGHT_FRAME]) FLIImg->frameType = LIGHT_FRAME; else FLIImg->frameType = FLAT_FRAME; if ((err = FLISetFrameType(fli_dev, FLI_FRAME_TYPE_NORMAL) )) { IUResetSwitches(&FrameTypeSP); FrameTypeS[LIGHT_FRAME].s = ISS_ON; IDSetSwitch(&FrameTypeSP, "FLISetFrameType() failed. %s.\n", strerror((int)-err)); IDLog("FLISetFrameType() failed. %s.\n", strerror((int)-err)); return; } IUResetSwitches(&FrameTypeSP); sp->s = ISS_ON; FrameTypeSP.s = IPS_OK; IDSetSwitch(&FrameTypeSP, NULL); break; } /* DARK AND BIAS */ else if ( (sp == &FrameTypeS[DARK_FRAME] || sp == &FrameTypeS[BIAS_FRAME]) && states[i] == ISS_ON) { if (sp == &FrameTypeS[DARK_FRAME]) FLIImg->frameType = DARK_FRAME; else FLIImg->frameType = BIAS_FRAME; if ((err = FLISetFrameType(fli_dev, FLI_FRAME_TYPE_DARK) )) { IUResetSwitches(&FrameTypeSP); FrameTypeS[LIGHT_FRAME].s = ISS_ON; IDSetSwitch(&FrameTypeSP, "FLISetFrameType() failed. %s.\n", strerror((int)-err)); IDLog("FLISetFrameType() failed. %s.\n", strerror((int)-err)); return; } IUResetSwitches(&FrameTypeSP); sp->s = ISS_ON; FrameTypeSP.s = IPS_OK; IDSetSwitch(&FrameTypeSP, NULL); break; } } /* For loop */ return; } } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { ISInit(); /* ignore if not ours */ if (dev && strcmp (mydev, dev)) return; /* suppress warning */ n=n; dev=dev; name=name; names=names; texts=texts; } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { long err; int i; INumber *np; char errmsg[ERRMSG_SIZE]; /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; ISInit(); /* Exposure time */ if (!strcmp (ExposeTimeNP.name, name)) { if (checkPowerN(&ExposeTimeNP)) return; if (ExposeTimeNP.s == IPS_BUSY) { if ( (err = FLICancelExposure(fli_dev))) { ExposeTimeNP.s = IPS_IDLE; IDSetNumber(&ExposeTimeNP, "FLICancelExposure() failed. %s.", strerror((int)-err)); IDLog("FLICancelExposure() failed. %s.\n", strerror((int)-err)); return; } ExposeTimeNP.s = IPS_IDLE; ExposeTimeN[0].value = 0; IDSetNumber(&ExposeTimeNP, "Exposure cancelled."); IDLog("Exposure Cancelled.\n"); return; } ExposeTimeNP.s = IPS_IDLE; np = IUFindNumber(&ExposeTimeNP, names[0]); if (!np) { IDSetNumber(&ExposeTimeNP, "Error: %s is not a member of %s property.", names[0], name); return; } np->value = values[0]; FLIImg->expose = (int) (values[0] * 1000.); /* Set duration */ if ( (err = FLISetExposureTime(fli_dev, np->value * 1000.) )) { IDSetNumber(&ExposeTimeNP, "FLISetExposureTime() failed. %s.\n", strerror((int)-err)); IDLog("FLISetExposureTime() failed. %s.\n", strerror((int)-err)); return; } IDLog("Exposure Time (ms) is: %g\n", np->value * 1000.); handleExposure(NULL); return; } if (!strcmp(TemperatureNP.name, name)) { if (checkPowerN(&TemperatureNP)) return; TemperatureNP.s = IPS_IDLE; np = IUFindNumber(&TemperatureNP, names[0]); if (!np) { IDSetNumber(&TemperatureNP, "Unknown error. %s is not a member of %s property.", names[0], name); return; } if (values[0] < MIN_CCD_TEMP || values[0] > MAX_CCD_TEMP) { IDSetNumber(&TemperatureNP, "Error: valid range of temperature is from %d to %d", MIN_CCD_TEMP, MAX_CCD_TEMP); return; } if ( (err = FLISetTemperature(fli_dev, values[0]))) { IDSetNumber(&TemperatureNP, "FLISetTemperature() failed. %s.", strerror((int)-err)); IDLog("FLISetTemperature() failed. %s.", strerror((int)-err)); return; } FLICam->temperature = values[0]; TemperatureNP.s = IPS_BUSY; IDSetNumber(&TemperatureNP, "Setting CCD temperature to %+06.2f C", values[0]); IDLog("Setting CCD temperature to %+06.2f C\n", values[0]); return; } if (!strcmp(FrameNP.name, name)) { int nset=0; if (checkPowerN(&FrameNP)) return; FrameNP.s = IPS_IDLE; for (i=0; i < n ; i++) { np = IUFindNumber(&FrameNP, names[i]); if (!np) { IDSetNumber(&FrameNP, "Unknown error. %s is not a member of %s property.", names[0], name); return; } /* X or Width */ if (np == &FrameN[0] || np==&FrameN[2]) { if (values[i] < 0 || values[i] > FLICam->width) break; nset++; np->value = values[i]; } /* Y or height */ else if (np == &FrameN[1] || np==&FrameN[3]) { if (values[i] < 0 || values[i] > FLICam->height) break; nset++; np->value = values[i]; } } if (nset < 4) { IDSetNumber(&FrameNP, "Invalid range. Valid range is (0,0) - (%0d,%0d)", FLICam->width, FLICam->height); IDLog("Invalid range. Valid range is (0,0) - (%0d,%0d)", FLICam->width, FLICam->height); return; } if (setImageArea(errmsg)) { IDSetNumber(&FrameNP, "%s", errmsg); return; } FrameNP.s = IPS_OK; /* Adjusting image width and height */ FLIImg->width = FrameN[2].value; FLIImg->height = FrameN[3].value; IDSetNumber(&FrameNP, NULL); } /* end FrameNP */ if (!strcmp(BinningNP.name, name)) { if (checkPowerN(&BinningNP)) return; BinningNP.s = IPS_IDLE; for (i=0 ; i < n ; i++) { np = IUFindNumber(&BinningNP, names[i]); if (!np) { IDSetNumber(&BinningNP, "Unknown error. %s is not a member of %s property.", names[0], name); return; } /* X binning */ if (np == &BinningN[0]) { if (values[i] < 1 || values[i] > MAX_X_BIN) { IDSetNumber(&BinningNP, "Error: Valid X bin values are from 1 to %g", MAX_X_BIN); IDLog("Error: Valid X bin values are from 1 to %g", MAX_X_BIN); return; } if ( (err = FLISetHBin(fli_dev, values[i]))) { IDSetNumber(&BinningNP, "FLISetHBin() failed. %s.", strerror((int)-err)); IDLog("FLISetHBin() failed. %s.", strerror((int)-err)); return; } np->value = values[i]; } else if (np == &BinningN[1]) { if (values[i] < 1 || values[i] > MAX_Y_BIN) { IDSetNumber(&BinningNP, "Error: Valid Y bin values are from 1 to %g", MAX_Y_BIN); IDLog("Error: Valid X bin values are from 1 to %g", MAX_Y_BIN); return; } if ( (err = FLISetVBin(fli_dev, values[i]))) { IDSetNumber(&BinningNP, "FLISetVBin() failed. %s.", strerror((int)-err)); IDLog("FLISetVBin() failed. %s.", strerror((int)-err)); return; } np->value = values[i]; } } /* end for */ if (setImageArea(errmsg)) { IDSetNumber(&BinningNP, errmsg, NULL); IDLog("%s", errmsg); return; } BinningNP.s = IPS_OK; IDLog("Binning is: %.0f x %.0f\n", BinningN[0].value, BinningN[1].value); IDSetNumber(&BinningNP, NULL); return; } } void ISPoll(void *p) { long err; long timeleft; double ccdTemp; if (!isCCDConnected()) { IEAddTimer (POLLMS, ISPoll, NULL); return; } /*IDLog("In Poll.\n");*/ switch (ExposeTimeNP.s) { case IPS_IDLE: break; case IPS_OK: break; case IPS_BUSY: if ( (err = FLIGetExposureStatus(fli_dev, &timeleft))) { ExposeTimeNP.s = IPS_IDLE; ExposeTimeN[0].value = 0; IDSetNumber(&ExposeTimeNP, "FLIGetExposureStatus() failed. %s.", strerror((int)-err)); IDLog("FLIGetExposureStatus() failed. %s.\n", strerror((int)-err)); break; } /*ExposeProgressN[0].value = (timeleft / 1000.);*/ if (timeleft > 0) { ExposeTimeN[0].value = timeleft / 1000.; IDSetNumber(&ExposeTimeNP, NULL); break; } /*{ IDSetNumber(&ExposeProgressNP, NULL); break; }*/ /* We're done exposing */ ExposeTimeNP.s = IPS_IDLE; ExposeTimeN[0].value = 0; /*ExposeProgressNP.s = IPS_IDLE;*/ IDSetNumber(&ExposeTimeNP, "Exposure done, downloading image..."); IDLog("Exposure done, downloading image...\n"); /*IDSetNumber(&ExposeProgressNP, NULL);*/ /* grab and save image */ if (grabImage()) break; /* Multiple image exposure if ( imagesLeft > 0) { IDMessage(mydev, "Image #%d will be taken in %0.f seconds.", imageCount+1, DelayN[0].value); IDLog("Image #%d will be taken in %0.f seconds.", imageCount+1, DelayN[0].value); IEAddTimer (DelayN[0].value * 1000., handleExposure, NULL); }*/ break; case IPS_ALERT: break; } switch (TemperatureNP.s) { case IPS_IDLE: case IPS_OK: if ( (err = FLIGetTemperature(fli_dev, &ccdTemp))) { TemperatureNP.s = IPS_IDLE; IDSetNumber(&TemperatureNP, "FLIGetTemperature() failed. %s.", strerror((int)-err)); IDLog("FLIGetTemperature() failed. %s.", strerror((int)-err)); return; } if (fabs(TemperatureN[0].value - ccdTemp) >= TEMP_THRESHOLD) { TemperatureN[0].value = ccdTemp; IDSetNumber(&TemperatureNP, NULL); } break; case IPS_BUSY: if ((err = FLIGetTemperature(fli_dev, &ccdTemp))) { TemperatureNP.s = IPS_ALERT; IDSetNumber(&TemperatureNP, "FLIGetTemperature() failed. %s.", strerror((int)-err)); IDLog("FLIGetTemperature() failed. %s.", strerror((int)-err)); return; } if (fabs(FLICam->temperature - ccdTemp) <= TEMP_THRESHOLD) TemperatureNP.s = IPS_OK; TemperatureN[0].value = ccdTemp; IDSetNumber(&TemperatureNP, NULL); break; case IPS_ALERT: break; } p=p; IEAddTimer (POLLMS, ISPoll, NULL); } /* Sets the Image area that the CCD will scan and download. We compensate for binning. */ int setImageArea(char errmsg[]) { long x_1, y_1, x_2, y_2; long err; /* Add the X and Y offsets */ x_1 = FrameN[0].value + FLICam->Visible_Area[0]; y_1 = FrameN[1].value + FLICam->Visible_Area[1]; x_2 = x_1 + (FrameN[2].value / BinningN[0].value); y_2 = y_1 + (FrameN[3].value / BinningN[1].value); if (x_2 > FLICam->Visible_Area[2]) x_2 = FLICam->Visible_Area[2]; if (y_2 > FLICam->Visible_Area[3]) y_2 = FLICam->Visible_Area[3]; IDLog("The Final image area is (%ld, %ld), (%ld, %ld)\n", x_1, y_1, x_2, y_2); FLIImg->width = x_2 - x_1; FLIImg->height = y_2 - y_1; if ( (err = FLISetImageArea(fli_dev, x_1, y_1, x_2, y_2) )) { snprintf(errmsg, ERRMSG_SIZE, "FLISetImageArea() failed. %s.\n", strerror((int)-err)); IDLog("%s", errmsg); return -1; } return 0; } /* Downloads the image from the CCD row by row and store them in a raw file. N.B. No processing is done on the image */ int grabImage() { long err; int img_size,i, fd; char errmsg[ERRMSG_SIZE]; char filename[TEMPFILE_LEN] = "/tmp/fitsXXXXXX"; if ((fd = mkstemp(filename)) < 0) { IDMessage(mydev, "Error making temporary filename."); IDLog("Error making temporary filename.\n"); return -1; } close(fd); img_size = FLIImg->width * FLIImg->height * sizeof(unsigned short); FLIImg->img = malloc (img_size); if (FLIImg->img == NULL) { IDMessage(mydev, "Not enough memory to store image."); IDLog("Not enough memory to store image.\n"); return -1; } for (i=0; i < FLIImg->height ; i++) { if ( (err = FLIGrabRow(fli_dev, &FLIImg->img[i * FLIImg->width], FLIImg->width))) { free(FLIImg->img); IDMessage(mydev, "FLIGrabRow() failed at row %d. %s.", i, strerror((int)-err)); IDLog("FLIGrabRow() failed at row %d. %s.\n", i, strerror((int)-err)); return -1; } } IDMessage(mydev, "Download complete.\n"); /*err = (ImageFormatS[0].s == ISS_ON) ? writeFITS(FileNameT[0].text, errmsg) : writeRAW(FileNameT[0].text, errmsg);*/ err = writeFITS(filename, errmsg); if (err) { free(FLIImg->img); IDMessage(mydev, errmsg, NULL); return -1; } free(FLIImg->img); return 0; } int writeFITS(const char* filename, char errmsg[]) { int i=0, j=0; fitsfile *fptr; /* pointer to the FITS file; defined in fitsio.h */ int status; long fpixel = 1, naxis = 2, nelements; long naxes[2]; char filename_rw[TEMPFILE_LEN+1]; naxes[0] = FLIImg->width; naxes[1] = FLIImg->height; /* Append ! to file name to over write it.*/ snprintf(filename_rw, TEMPFILE_LEN+1, "!%s", filename); status = 0; /* initialize status before calling fitsio routines */ fits_create_file(&fptr, filename_rw, &status); /* create new file */ /* Create the primary array image (16-bit short integer pixels */ fits_create_img(fptr, USHORT_IMG, naxis, naxes, &status); addFITSKeywords(fptr); nelements = naxes[0] * naxes[1]; /* number of pixels to write */ /* Write the array of integers to the image */ fits_write_img(fptr, TUSHORT, fpixel, nelements, FLIImg->img, &status); fits_close_file(fptr, &status); /* close the file */ fits_report_error(stderr, status); /* print out any error messages */ /* Success */ ExposeTimeNP.s = IPS_OK; IDSetNumber(&ExposeTimeNP, NULL); uploadFile(filename); unlink(filename); return status; } void addFITSKeywords(fitsfile *fptr) { int status=0; char binning_s[32]; char frame_s[32]; double min_val, max_val; /*pixel_size = (float) PixelSizeN[0].value; min_val = min(); max_val = max(); temp = (float) TemperatureN[0].value; expose = (float) FLIImg->expose;*/ snprintf(binning_s, 32, "(%g x %g)", BinningN[0].value, BinningN[1].value); switch (FLIImg->frameType) { case LIGHT_FRAME: strcpy(frame_s, "Light"); break; case BIAS_FRAME: strcpy(frame_s, "Bias"); break; case FLAT_FRAME: strcpy(frame_s, "Flat Field"); break; case DARK_FRAME: strcpy(frame_s, "Dark"); break; } fits_update_key(fptr, TDOUBLE, "CCD-TEMP", &(TemperatureN[0].value), "CCD Temperature (Celcius)", &status); fits_update_key(fptr, TDOUBLE, "EXPOSURE", &(FLIImg->expose), "Total Exposure Time (ms)", &status); fits_update_key(fptr, TDOUBLE, "PIX-SIZ", &(PixelSizeN[0].value), "Pixel Size (microns)", &status); fits_update_key(fptr, TSTRING, "BINNING", binning_s, "Binning HOR x VER", &status); fits_update_key(fptr, TSTRING, "FRAME", frame_s, "Frame Type", &status); fits_update_key(fptr, TDOUBLE, "DATAMIN", &min_val, "Minimum value", &status); fits_update_key(fptr, TDOUBLE, "DATAMAX", &max_val, "Maximum value", &status); fits_update_key(fptr, TSTRING, "INSTRUME", "Finger Lakes Instruments", "CCD Name", &status); fits_write_date(fptr, &status); } void uploadFile(const char* filename) { FILE * fitsFile; unsigned char *fitsData, *compressedData; int r=0; unsigned int i =0, nr = 0; uLongf compressedBytes=0; uLong totalBytes; struct stat stat_p; if ( -1 == stat (filename, &stat_p)) { IDLog(" Error occurred attempting to stat file.\n"); return; } totalBytes = stat_p.st_size; fitsData = (unsigned char *) malloc (sizeof(unsigned char) * totalBytes); compressedData = (unsigned char *) malloc (sizeof(unsigned char) * totalBytes + totalBytes / 64 + 16 + 3); if (fitsData == NULL || compressedData == NULL) { if (fitsData) free(fitsData); if (compressedData) free(compressedData); IDLog("Error! low memory. Unable to initialize fits buffers.\n"); return; } fitsFile = fopen(filename, "r"); if (fitsFile == NULL) return; /* #1 Read file from disk */ for (i=0; i < totalBytes; i+= nr) { nr = fread(fitsData + i, 1, totalBytes - i, fitsFile); if (nr <= 0) { IDLog("Error reading temporary FITS file.\n"); return; } } fclose(fitsFile); compressedBytes = sizeof(char) * totalBytes + totalBytes / 64 + 16 + 3; /* #2 Compress it */ r = compress2(compressedData, &compressedBytes, fitsData, totalBytes, 9); if (r != Z_OK) { /* this should NEVER happen */ IDLog("internal error - compression failed: %d\n", r); return; } /* #3 Send it */ imageB.blob = compressedData; imageB.bloblen = compressedBytes; imageB.size = totalBytes; strcpy(imageB.format, ".fits.z"); imageBP.s = IPS_OK; IDSetBLOB (&imageBP, NULL); free (fitsData); free (compressedData); } /* Initiates the exposure procedure */ void handleExposure(void *p) { long err; /* no warning */ p=p; /* BIAS frame is the same as DARK but with minimum period. i.e. readout from camera electronics. */ if (FLIImg->frameType == BIAS_FRAME) { if ((err = FLISetExposureTime(fli_dev, 50))) { ExposeTimeNP.s = IPS_IDLE; IDSetNumber(&ExposeTimeNP, "FLISetExposureTime() failed. %s.\n", strerror((int)-err)); IDLog("FLISetExposureTime() failed. %s.\n", strerror((int)-err)); return; } } if ((err = FLIExposeFrame(fli_dev))) { ExposeTimeNP.s = IPS_IDLE; IDSetNumber(&ExposeTimeNP, "FLIExposeFrame() failed. %s.", strerror((int)-err)); IDLog("FLIExposeFrame() failed. %s.\n", strerror((int)-err)); return; } ExposeTimeNP.s = IPS_BUSY; IDSetNumber(&ExposeTimeNP, "Taking a %g seconds frame...", FLIImg->expose / 1000.); IDLog("Taking a frame...\n"); } /* Retrieves basic data from the CCD upon connection like temperature, array size, firmware..etc */ void getBasicData() { char buff[2048]; long err; IDLog("In getBasicData()\n"); if ((err = FLIGetModel (fli_dev, buff, 2048))) { IDMessage(mydev, "FLIGetModel() failed. %s.", strerror((int)-err)); IDLog("FLIGetModel() failed. %s.\n", strerror((int)-err)); return; } else { if ( (FLICam->model = malloc (sizeof(char) * 2048)) == NULL) { IDMessage(mydev, "malloc() failed."); IDLog("malloc() failed."); return; } strcpy(FLICam->model, buff); } if (( err = FLIGetHWRevision(fli_dev, &FLICam->HWRevision))) { IDMessage(mydev, "FLIGetHWRevision() failed. %s.", strerror((int)-err)); IDLog("FLIGetHWRevision() failed. %s.\n", strerror((int)-err)); return; } if (( err = FLIGetFWRevision(fli_dev, &FLICam->FWRevision))) { IDMessage(mydev, "FLIGetFWRevision() failed. %s.", strerror((int)-err)); IDLog("FLIGetFWRevision() failed. %s.\n", strerror((int)-err)); return; } if (( err = FLIGetPixelSize(fli_dev, &FLICam->x_pixel_size, &FLICam->y_pixel_size))) { IDMessage(mydev, "FLIGetPixelSize() failed. %s.", strerror((int)-err)); IDLog("FLIGetPixelSize() failed. %s.\n", strerror((int)-err)); return; } FLICam->x_pixel_size *= 1e6; FLICam->y_pixel_size *= 1e6; if (( err = FLIGetArrayArea(fli_dev, &FLICam->Array_Area[0], &FLICam->Array_Area[1], &FLICam->Array_Area[2], &FLICam->Array_Area[3]))) { IDMessage(mydev, "FLIGetArrayArea() failed. %s.", strerror((int)-err)); IDLog("FLIGetArrayArea() failed. %s.\n", strerror((int)-err)); return; } if (( err = FLIGetVisibleArea( fli_dev, &FLICam->Visible_Area[0], &FLICam->Visible_Area[1], &FLICam->Visible_Area[2], &FLICam->Visible_Area[3]))) { IDMessage(mydev, "FLIGetVisibleArea() failed. %s.", strerror((int)-err)); IDLog("FLIGetVisibleArea() failed. %s.\n", strerror((int)-err)); } if (( err = FLIGetTemperature(fli_dev, &FLICam->temperature))) { IDMessage(mydev, "FLIGetTemperature() failed. %s.", strerror((int)-err)); IDLog("FLIGetTemperature() failed. %s.\n", strerror((int)-err)); return; } IDLog("The CCD Temperature is %f.\n", FLICam->temperature); PixelSizeN[0].value = FLICam->x_pixel_size; /* Pixel width (um) */ PixelSizeN[1].value = FLICam->y_pixel_size; /* Pixel height (um) */ TemperatureN[0].value = FLICam->temperature; /* CCD chip temperatre (degrees C) */ FrameN[0].value = 0; /* X */ FrameN[1].value = 0; /* Y */ FrameN[2].value = FLICam->Visible_Area[2] - FLICam->Visible_Area[0]; /* Frame Width */ FrameN[3].value = FLICam->Visible_Area[3] - FLICam->Visible_Area[1]; /* Frame Height */ FLICam->width = FLIImg->width = FrameN[2].value; FLICam->height = FLIImg->width = FrameN[3].value; BinningN[0].value = BinningN[1].value = 1; IDLog("The Camera Width is %d ---- %d\n", (int) FLICam->width, (int) FrameN[2].value); IDLog("The Camera Height is %d ---- %d\n", (int) FLICam->height, (int) FrameN[3].value); IDSetNumber(&PixelSizeNP, NULL); IDSetNumber(&TemperatureNP, NULL); IDSetNumber(&FrameNP, NULL); IDSetNumber(&BinningNP, NULL); IDLog("Exiting getBasicData()\n"); } int manageDefaults(char errmsg[]) { long err; int exposeTimeMS; exposeTimeMS = (int) (ExposeTimeN[0].value * 1000.); IDLog("Setting default exposure time of %d ms.\n", exposeTimeMS); if ( (err = FLISetExposureTime(fli_dev, exposeTimeMS) )) { snprintf(errmsg, ERRMSG_SIZE, "FLISetExposureTime() failed. %s.\n", strerror((int)-err)); IDLog(errmsg, NULL); return -1; } /* Default frame type is NORMAL */ if ( (err = FLISetFrameType(fli_dev, FLI_FRAME_TYPE_NORMAL) )) { snprintf(errmsg, ERRMSG_SIZE, "FLISetFrameType() failed. %s.\n", strerror((int)-err)); IDLog(errmsg, NULL); return -1; } /* X horizontal binning */ if ( (err = FLISetHBin(fli_dev, BinningN[0].value) )) { snprintf(errmsg, ERRMSG_SIZE, "FLISetBin() failed. %s.\n", strerror((int)-err)); IDLog(errmsg, NULL); return -1; } /* Y vertical binning */ if ( (err = FLISetVBin(fli_dev, BinningN[1].value) )) { snprintf(errmsg, ERRMSG_SIZE, "FLISetVBin() failed. %s.\n", strerror((int)-err)); IDLog(errmsg, NULL); return -1; } IDLog("Setting default binning %f x %f.\n", BinningN[0].value, BinningN[1].value); FLISetNFlushes(fli_dev, NFLUSHES); /* Set image area */ if (setImageArea(errmsg)) return -1; /* Success */ return 0; } int getOnSwitch(ISwitchVectorProperty *sp) { int i=0; for (i=0; i < sp->nsp ; i++) { /*IDLog("Switch %s is %s\n", sp->sp[i].name, sp->sp[i].s == ISS_ON ? "On" : "Off");*/ if (sp->sp[i].s == ISS_ON) return i; } return -1; } int checkPowerS(ISwitchVectorProperty *sp) { if (PowerSP.s != IPS_OK) { if (!strcmp(sp->label, "")) IDMessage (mydev, "Cannot change property %s while the CCD is offline.", sp->name); else IDMessage (mydev, "Cannot change property %s while the CCD is offline.", sp->label); sp->s = IPS_IDLE; IDSetSwitch(sp, NULL); return -1; } return 0; } int checkPowerN(INumberVectorProperty *np) { if (PowerSP.s != IPS_OK) { if (!strcmp(np->label, "")) IDMessage (mydev, "Cannot change property %s while the CCD is offline.", np->name); else IDMessage (mydev, "Cannot change property %s while the CCD is offline.", np->label); np->s = IPS_IDLE; IDSetNumber(np, NULL); return -1; } return 0; } int checkPowerT(ITextVectorProperty *tp) { if (PowerSP.s != IPS_OK) { if (!strcmp(tp->label, "")) IDMessage (mydev, "Cannot change property %s while the CCD is offline.", tp->name); else IDMessage (mydev, "Cannot change property %s while the CCD is offline.", tp->label); tp->s = IPS_IDLE; IDSetText(tp, NULL); return -1; } return 0; } void connectCCD() { long err; char errmsg[ERRMSG_SIZE]; IDLog ("In ConnectCCD\n"); /* USB by default {USB, SERIAL, PARALLEL, INET} */ switch (PowerS[0].s) { case ISS_ON: IDLog("Current portSwitch is %d\n", portSwitchIndex); IDLog("Attempting to find the camera in domain %ld\n", Domains[portSwitchIndex]); if (findcam(Domains[portSwitchIndex])) { PowerSP.s = IPS_IDLE; PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch(&PowerSP, "Error: no cameras were detected."); IDLog("Error: no cameras were detected.\n"); return; } if ((err = FLIOpen(&fli_dev, FLICam->name, FLIDEVICE_CAMERA | FLICam->domain))) { PowerSP.s = IPS_IDLE; PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch(&PowerSP, "Error: FLIOpen() failed. %s.", strerror( (int) -err)); IDLog("Error: FLIOpen() failed. %s.\n", strerror( (int) -err)); return; } /* Sucess! */ PowerS[0].s = ISS_ON; PowerS[1].s = ISS_OFF; PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "CCD is online. Retrieving basic data."); IDLog("CCD is online. Retrieving basic data.\n"); getBasicData(); if (manageDefaults(errmsg)) { IDMessage(mydev, errmsg, NULL); IDLog("%s", errmsg); return; } break; case ISS_OFF: PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_IDLE; if ((err = FLIClose(fli_dev))) { PowerSP.s = IPS_IDLE; PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch(&PowerSP, "Error: FLIClose() failed. %s.", strerror( (int) -err)); IDLog("Error: FLIClose() failed. %s.\n", strerror( (int) -err)); return; } IDSetSwitch(&PowerSP, "CCD is offline."); break; } } /* isCCDConnected: return 1 if we have a connection, 0 otherwise */ int isCCDConnected(void) { return ((PowerS[0].s == ISS_ON) ? 1 : 0); } int findcam(flidomain_t domain) { char **tmplist; long err; IDLog("In find Camera, the domain is %ld\n", domain); if (( err = FLIList(domain | FLIDEVICE_CAMERA, &tmplist))) { IDLog("FLIList() failed. %s\n", strerror((int)-err)); return -1; } if (tmplist != NULL && tmplist[0] != NULL) { int i; IDLog("Trying to allocate memory to FLICam\n"); if ((FLICam = malloc (sizeof (cam_t))) == NULL) { IDLog("malloc() failed.\n"); return -1; } for (i = 0; tmplist[i] != NULL; i++) { int j; for (j = 0; tmplist[i][j] != '\0'; j++) if (tmplist[i][j] == ';') { tmplist[i][j] = '\0'; break; } } FLICam->domain = domain; switch (domain) { case FLIDOMAIN_PARALLEL_PORT: FLICam->dname = strdup("parallel port"); break; case FLIDOMAIN_USB: FLICam->dname = strdup("USB"); break; case FLIDOMAIN_SERIAL: FLICam->dname = strdup("serial"); break; case FLIDOMAIN_INET: FLICam->dname = strdup("inet"); break; default: FLICam->dname = strdup("Unknown domain"); } FLICam->name = strdup(tmplist[0]); if ((err = FLIFreeList(tmplist))) { IDLog("FLIFreeList() failed. %s.\n", strerror((int)-err)); return -1; } } /* end if */ else { if ((err = FLIFreeList(tmplist))) { IDLog("FLIFreeList() failed. %s.\n", strerror((int)-err)); return -1; } return -1; } IDLog("Findcam() finished successfully.\n"); return 0; } double min() { double lmin = FLIImg->img[0]; int ind=0, i, j; for (i= 0; i < FLIImg->height ; i++) for (j= 0; j < FLIImg->width; j++) { ind = (i * FLIImg->width) + j; if (FLIImg->img[ind] < lmin) lmin = FLIImg->img[ind]; } return lmin; } double max() { double lmax = FLIImg->img[0]; int ind=0, i, j; for (i= 0; i < FLIImg->height ; i++) for (j= 0; j < FLIImg->width; j++) { ind = (i * FLIImg->width) + j; if (FLIImg->img[ind] > lmax) lmax = FLIImg->img[ind]; } return lmax; } indi-0.5/src/lx200autostar.cpp0000644000175000017500000001314410610474326014042 0ustar jrjr/* LX200 Autostar Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "lx200autostar.h" #include "lx200driver.h" #define FirmwareGroup "Firmware data" #define FOCUS_GROUP "Focus Control" extern LX200Generic *telescope; extern int MaxReticleFlashRate; extern ITextVectorProperty Time; extern INumberVectorProperty SDTime; extern INumberVectorProperty eqNum; extern INumberVectorProperty FocusTimerNP; extern ISwitchVectorProperty ParkSP; extern ISwitchVectorProperty PowerSP; extern ISwitchVectorProperty FocusMotionSw; static IText VersionT[] ={{ "Date", "", 0, 0, 0, 0} , { "Time", "", 0, 0, 0, 0} , { "Number", "", 0, 0, 0 ,0} , { "Full", "", 0, 0, 0, 0} , { "Name", "" ,0 ,0 ,0 ,0}}; static ITextVectorProperty VersionInfo = {mydev, "Firmware Info", "", FirmwareGroup, IP_RO, 0, IPS_IDLE, VersionT, NARRAY(VersionT), "" ,0}; // Focus Control static INumber FocusSpeedN[] = {{"SPEED", "Speed", "%0.f", 0.0, 4.0, 1.0, 0.0, 0, 0, 0}}; static INumberVectorProperty FocusSpeedNP = {mydev, "FOCUS_SPEED", "Speed", FOCUS_GROUP, IP_RW, 0, IPS_IDLE, FocusSpeedN, NARRAY(FocusSpeedN), "", 0}; void changeLX200AutostarDeviceName(const char *newName) { strcpy(VersionInfo.device, newName); strcpy(FocusSpeedNP.device, newName); } LX200Autostar::LX200Autostar() : LX200Generic() { } void LX200Autostar::ISGetProperties (const char *dev) { if (dev && strcmp (thisDevice, dev)) return; LX200Generic::ISGetProperties(dev); IDDefText (&VersionInfo, NULL); IDDefNumber (&FocusSpeedNP, NULL); // For Autostar, we have a different focus speed method // Therefore, we don't need the classical one IDDelete(thisDevice, "FOCUS_MODE", NULL); } void LX200Autostar::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { // ignore if not ours // if (strcmp (dev, thisDevice)) return; // suppress warning n=n; LX200Generic::ISNewText (dev, name, texts, names, n); } void LX200Autostar::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { // ignore if not ours if (strcmp (dev, thisDevice)) return; // Focus speed if (!strcmp (name, FocusSpeedNP.name)) { if (checkPower(&FocusSpeedNP)) return; if (IUUpdateNumbers(&FocusSpeedNP, values, names, n) < 0) return; setGPSFocuserSpeed(fd, ( (int) FocusSpeedN[0].value)); FocusSpeedNP.s = IPS_OK; IDSetNumber(&FocusSpeedNP, NULL); return; } LX200Generic::ISNewNumber (dev, name, values, names, n); } void LX200Autostar::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { int index=0, err=0; if (!strcmp(name, ParkSP.name)) { if (checkPower(&ParkSP)) return; ParkSP.s = IPS_IDLE; if (eqNum.s == IPS_BUSY) { abortSlew(fd); // sleep for 200 mseconds usleep(200000); } slewToPark(fd); ParkSP.s = IPS_OK; eqNum.s = IPS_IDLE; PowerSP.s = IPS_IDLE; PowerSP.sp[0].s = ISS_OFF; PowerSP.sp[1].s = ISS_ON; IDSetNumber(&eqNum, NULL); IDSetSwitch(&ParkSP, "The telescope is slewing to park position. Turn off the telescope after park is complete. Disconnecting..."); IDSetSwitch(&PowerSP, NULL); return; } // Focus Motion if (!strcmp (name, FocusMotionSw.name)) { if (checkPower(&FocusMotionSw)) return; IUResetSwitches(&FocusMotionSw); // If speed is "halt" if (FocusSpeedN[0].value == 0) { FocusMotionSw.s = IPS_IDLE; IDSetSwitch(&FocusMotionSw, NULL); return; } IUUpdateSwitches(&FocusMotionSw, states, names, n); index = getOnSwitch(&FocusMotionSw); if ( ( err = setFocuserMotion(fd, index) < 0) ) { handleError(&FocusMotionSw, err, "Setting focuser speed"); return; } FocusMotionSw.s = IPS_BUSY; // with a timer if (FocusTimerNP.np[0].value > 0) { FocusTimerNP.s = IPS_BUSY; IDLog("Starting Focus Timer BUSY\n"); IEAddTimer(50, LX200Generic::updateFocusTimer, this); } IDSetSwitch(&FocusMotionSw, NULL); return; } LX200Generic::ISNewSwitch (dev, name, states, names, n); } void LX200Autostar::ISPoll () { LX200Generic::ISPoll(); } void LX200Autostar::getBasicData() { VersionInfo.tp[0].text = new char[64]; getVersionDate(fd, VersionInfo.tp[0].text); VersionInfo.tp[1].text = new char[64]; getVersionTime(fd, VersionInfo.tp[1].text); VersionInfo.tp[2].text = new char[64]; getVersionNumber(fd, VersionInfo.tp[2].text); VersionInfo.tp[3].text = new char[128]; getFullVersion(fd, VersionInfo.tp[3].text); VersionInfo.tp[4].text = new char[128]; getProductName(fd, VersionInfo.tp[4].text); IDSetText(&VersionInfo, NULL); // process parent LX200Generic::getBasicData(); } indi-0.5/src/fli_wheel.c0000644000175000017500000003755310610474331013016 0ustar jrjr#if 0 FLI WHEEL INDI Interface for Finger Lakes Instruments Filter Wheels Copyright (C) 2005 Gaetano Vocca (yagvoc-web AT yahoo DOT it) Based on fli_ccd by Jasem Mutlaq (mutlaqja AT ikarustech DOT com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fli/libfli.h" #include "indidevapi.h" #include "eventloop.h" #include "indicom.h" void ISInit(void); void getBasicData(void); void ISPoll(void *); void handleExposure(void *); void connectFilter(void); int findwheel(flidomain_t domain); int manageDefaults(char errmsg[]); int checkPowerS(ISwitchVectorProperty *sp); int checkPowerN(INumberVectorProperty *np); int checkPowerT(ITextVectorProperty *tp); int getOnSwitch(ISwitchVectorProperty *sp); int isFilterConnected(void); double min(void); double max(void); extern char* me; extern int errno; #define mydev "FLI Wheel" #define MAIN_GROUP "Main Control" #define LAST_FILTER 14 /* Max slot index */ #define FIRST_FILTER 0 /* Min slot index */ #define currentFilter FilterN[0].value #define POLLMS 1000 #define LIBVERSIZ 1024 #define PREFIXSIZ 64 #define PIPEBUFSIZ 8192 #define FRAME_ILEN 64 typedef struct { flidomain_t domain; char *dname; char *name; char *model; long HWRevision; long FWRevision; long current_filter; long filter_count; long home; } cam_t; static flidev_t fli_dev; static cam_t *FLIWheel; static int portSwitchIndex; static int simulation; static int targetFilter; long int Domains[] = { FLIDOMAIN_USB, FLIDOMAIN_SERIAL, FLIDOMAIN_PARALLEL_PORT, FLIDOMAIN_INET }; /*INDI controls */ /* Connect/Disconnect */ static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}}; static ISwitchVectorProperty PowerSP = { mydev, "CONNECTION" , "Connection", MAIN_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0}; /* Types of Ports */ static ISwitch PortS[] = {{"USB", "", ISS_ON, 0, 0}, {"Serial", "", ISS_OFF, 0, 0}, {"Parallel", "", ISS_OFF, 0, 0}, {"INet", "", ISS_OFF, 0, 0}}; static ISwitchVectorProperty PortSP = { mydev, "Port Type", "", MAIN_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, PortS, NARRAY(PortS), "", 0}; /* Filter control */ static INumber FilterN[] = { {"SLOT", "Active Filter", "%2.0f", FIRST_FILTER, LAST_FILTER, 1, 0, 0, 0, 0}}; static INumberVectorProperty FilterNP = { mydev, "FILTER_SLOT", "Filter", MAIN_GROUP, IP_RW, 0, IPS_IDLE, FilterN, NARRAY(FilterN), "", 0}; /* send client definitions of all properties */ void ISInit() { static int isInit=0; if (isInit) return; /* USB by default {USB, SERIAL, PARALLEL, INET} */ portSwitchIndex = 0; targetFilter = 0; /* No Simulation by default */ simulation = 0; /* Enable the following for simulation mode */ /*simulation = 1; IDLog("WARNING: Simulation is on\n");*/ IEAddTimer (POLLMS, ISPoll, NULL); isInit = 1; } void ISGetProperties (const char *dev) { ISInit(); if (dev && strcmp (mydev, dev)) return; /* Main Control */ IDDefSwitch(&PowerSP, NULL); IDDefSwitch(&PortSP, NULL); IDDefNumber(&FilterNP, NULL); } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n) { dev=dev;name=name;sizes=sizes;blobs=blobs;formats=formats;names=names;n=n; } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; ISInit(); /* Port type */ if (!strcmp (name, PortSP.name)) { PortSP.s = IPS_IDLE; IUResetSwitches(&PortSP); IUUpdateSwitches(&PortSP, states, names, n); portSwitchIndex = getOnSwitch(&PortSP); PortSP.s = IPS_OK; IDSetSwitch(&PortSP, NULL); return; } /* Connection */ if (!strcmp (name, PowerSP.name)) { IUResetSwitches(&PowerSP); IUUpdateSwitches(&PowerSP, states, names, n); connectFilter(); return; } } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { ISInit(); /* ignore if not ours */ if (dev && strcmp (mydev, dev)) return; /* suppress warning */ n=n; dev=dev; name=name; names=names; texts=texts; } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { long err; INumber *np; long newFilter; n = n; /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; ISInit(); if (!strcmp(FilterNP.name, name)) { if (simulation) { targetFilter = values[0]; FilterNP.s = IPS_BUSY; IDSetNumber(&FilterNP, "Setting current filter to slot %d", targetFilter); IDLog("Setting current filter to slot %d\n", targetFilter); return; } if (!isFilterConnected()) { IDMessage(mydev, "Device not connected."); FilterNP.s = IPS_IDLE; IDSetNumber(&FilterNP, NULL); return; } targetFilter = values[0]; np = IUFindNumber(&FilterNP, names[0]); if (!np) { FilterNP.s = IPS_ALERT; IDSetNumber(&FilterNP, "Unknown error. %s is not a member of %s property.", names[0], name); return; } if (targetFilter < FIRST_FILTER || targetFilter > FLIWheel->filter_count - 1) { FilterNP.s = IPS_ALERT; IDSetNumber(&FilterNP, "Error: valid range of filter is from %d to %d", FIRST_FILTER, LAST_FILTER); return; } FilterNP.s = IPS_BUSY; IDSetNumber(&FilterNP, "Setting current filter to slot %d", targetFilter); IDLog("Setting current filter to slot %d\n", targetFilter); if ( (err = FLISetFilterPos(fli_dev, targetFilter))) { FilterNP.s = IPS_ALERT; IDSetNumber(&FilterNP, "FLISetFilterPos() failed. %s.", strerror((int)-err)); IDLog("FLISetFilterPos() failed. %s.", strerror((int)-err)); return; } /* Check current filter position */ if (( err = FLIGetFilterPos(fli_dev, &newFilter))) { FilterNP.s = IPS_ALERT; IDSetNumber(&FilterNP, "FLIGetFilterPos() failed. %s.", strerror((int)-err)); IDLog("FLIGetFilterPos() failed. %s.\n", strerror((int)-err)); return; } if (newFilter == targetFilter) { FLIWheel->current_filter = targetFilter; FilterN[0].value = FLIWheel->current_filter; FilterNP.s = IPS_OK; IDSetNumber(&FilterNP, "Filter set to slot #%d", targetFilter); return; } return; } } /* Retrieves basic data from the Wheel upon connection like temperature, array size, firmware..etc */ void getBasicData() { char buff[2048]; long err; if ((err = FLIGetModel (fli_dev, buff, 2048))) { IDMessage(mydev, "FLIGetModel() failed. %s.", strerror((int)-err)); IDLog("FLIGetModel() failed. %s.\n", strerror((int)-err)); return; } else { if ( (FLIWheel->model = malloc (sizeof(char) * 2048)) == NULL) { IDMessage(mydev, "malloc() failed."); IDLog("malloc() failed."); return; } strcpy(FLIWheel->model, buff); } if (( err = FLIGetHWRevision(fli_dev, &FLIWheel->HWRevision))) { IDMessage(mydev, "FLIGetHWRevision() failed. %s.", strerror((int)-err)); IDLog("FLIGetHWRevision() failed. %s.\n", strerror((int)-err)); return; } if (( err = FLIGetFWRevision(fli_dev, &FLIWheel->FWRevision))) { IDMessage(mydev, "FLIGetFWRevision() failed. %s.", strerror((int)-err)); IDLog("FLIGetFWRevision() failed. %s.\n", strerror((int)-err)); return; } if (( err = FLIGetFilterCount(fli_dev, &FLIWheel->filter_count))) { IDMessage(mydev, "FLIGetFilterCount() failed. %s.", strerror((int)-err)); IDLog("FLIGetFilterCount() failed. %s.\n", strerror((int)-err)); return; } IDLog("The filter count is %ld\n", FLIWheel->filter_count); FilterN[0].max = FLIWheel->filter_count - 1; FilterNP.s = IPS_OK; IUUpdateMinMax(&FilterNP); IDSetNumber(&FilterNP, "Setting basic data"); IDLog("Exiting getBasicData()\n"); } int manageDefaults(char errmsg[]) { long err; /*IDLog("Resetting filter wheel to slot %d\n", 0); FLIWheel->home = 0; if (( err = FLISetFilterPos(fli_dev, 0))) { IDMessage(mydev, "FLISetFilterPos() failed. %s.", strerror((int)-err)); IDLog("FLISetFilterPos() failed. %s.\n", strerror((int)-err)); return (int)-err; }*/ if (( err = FLIGetFilterPos(fli_dev, &FLIWheel->current_filter))) { IDMessage(mydev, "FLIGetFilterPos() failed. %s.", strerror((int)-err)); IDLog("FLIGetFilterPos() failed. %s.\n", strerror((int)-err)); return (int)-err; } IDLog("The current filter is %ld\n", FLIWheel->current_filter); FilterN[0].value = FLIWheel->current_filter; IDSetNumber(&FilterNP, "Storing defaults"); /* Success */ return 0; } void ISPoll(void *p) { static int simMTC = 5; if (!isFilterConnected()) { IEAddTimer (POLLMS, ISPoll, NULL); return; } switch (FilterNP.s) { case IPS_IDLE: case IPS_OK: break; case IPS_BUSY: /* Simulate that it takes 5 seconds to change slot */ if (simulation) { simMTC--; if (simMTC == 0) { simMTC = 5; currentFilter = targetFilter; FilterNP.s = IPS_OK; IDSetNumber(&FilterNP, "Filter set to slot #%2.0f", currentFilter); break; } IDSetNumber(&FilterNP, NULL); break; } /*if (( err = FLIGetFilterPos(fli_dev, ¤tFilter))) { FilterNP.s = IPS_ALERT; IDSetNumber(&FilterNP, "FLIGetFilterPos() failed. %s.", strerror((int)-err)); IDLog("FLIGetFilterPos() failed. %s.\n", strerror((int)-err)); return; } if (targetFilter == currentFilter) { FLIWheel->current_filter = currentFilter; FilterNP.s = IPS_OK; IDSetNumber(&FilterNP, "Filter set to slot #%2.0f", currentFilter); return; } IDSetNumber(&FilterNP, NULL);*/ break; case IPS_ALERT: break; } IEAddTimer (POLLMS, ISPoll, NULL); } int getOnSwitch(ISwitchVectorProperty *sp) { int i=0; for (i=0; i < sp->nsp ; i++) { /*IDLog("Switch %s is %s\n", sp->sp[i].name, sp->sp[i].s == ISS_ON ? "On" : "Off");*/ if (sp->sp[i].s == ISS_ON) return i; } return -1; } int checkPowerS(ISwitchVectorProperty *sp) { if (simulation) return 0; if (PowerSP.s != IPS_OK) { if (!strcmp(sp->label, "")) IDMessage (mydev, "Cannot change property %s while the wheel is offline.", sp->name); else IDMessage (mydev, "Cannot change property %s while the wheel is offline.", sp->label); sp->s = IPS_IDLE; IDSetSwitch(sp, NULL); return -1; } return 0; } int checkPowerN(INumberVectorProperty *np) { if (simulation) return 0; if (PowerSP.s != IPS_OK) { if (!strcmp(np->label, "")) IDMessage (mydev, "Cannot change property %s while the wheel is offline.", np->name); else IDMessage (mydev, "Cannot change property %s while the wheel is offline.", np->label); np->s = IPS_IDLE; IDSetNumber(np, NULL); return -1; } return 0; } int checkPowerT(ITextVectorProperty *tp) { if (simulation) return 0; if (PowerSP.s != IPS_OK) { if (!strcmp(tp->label, "")) IDMessage (mydev, "Cannot change property %s while the wheel is offline.", tp->name); else IDMessage (mydev, "Cannot change property %s while the wheel is offline.", tp->label); tp->s = IPS_IDLE; IDSetText(tp, NULL); return -1; } return 0; } void connectFilter() { long err; char errmsg[ERRMSG_SIZE]; /* USB by default {USB, SERIAL, PARALLEL, INET} */ switch (PowerS[0].s) { case ISS_ON: if (simulation) { /* Success! */ PowerS[0].s = ISS_ON; PowerS[1].s = ISS_OFF; PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "Simulation Wheel is online."); IDLog("Simulation Wheel is online.\n"); return; } IDLog("Current portSwitch is %d\n", portSwitchIndex); IDLog("Attempting to find the device in domain %ld\n", Domains[portSwitchIndex]); if (findwheel(Domains[portSwitchIndex])) { PowerSP.s = IPS_IDLE; PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch(&PowerSP, "Error: no wheels were detected."); IDLog("Error: no wheels were detected.\n"); return; } if ((err = FLIOpen(&fli_dev, FLIWheel->name, FLIWheel->domain | FLIDEVICE_FILTERWHEEL))) { PowerSP.s = IPS_IDLE; PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch(&PowerSP, "Error: FLIOpen() failed. %s.", strerror( (int) -err)); IDLog("Error: FLIOpen() failed. %s.\n", strerror( (int) -err)); return; } /* Success! */ PowerS[0].s = ISS_ON; PowerS[1].s = ISS_OFF; PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "Wheel is online. Retrieving basic data."); IDLog("Wheel is online. Retrieving basic data.\n"); getBasicData(); if (manageDefaults(errmsg)) { IDMessage(mydev, errmsg, NULL); IDLog("%s", errmsg); return; } break; case ISS_OFF: if (simulation) { PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_IDLE; IDSetSwitch(&PowerSP, "Wheel is offline."); return; } PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_IDLE; if ((err = FLIClose(fli_dev))) { PowerSP.s = IPS_ALERT; IDSetSwitch(&PowerSP, "Error: FLIClose() failed. %s.", strerror( (int) -err)); IDLog("Error: FLIClose() failed. %s.\n", strerror( (int) -err)); return; } IDSetSwitch(&PowerSP, "Wheel is offline."); break; } } /* isFilterConnected: return 1 if we have a connection, 0 otherwise */ int isFilterConnected(void) { if (simulation) return 1; return ((PowerS[0].s == ISS_ON) ? 1 : 0); } int findwheel(flidomain_t domain) { char **devlist; long err; IDLog("In find Camera, the domain is %ld\n", domain); if (( err = FLIList(domain | FLIDEVICE_FILTERWHEEL, &devlist))) { IDLog("FLIList() failed. %s\n", strerror((int)-err)); return -1; } if (devlist != NULL && devlist[0] != NULL) { int i; IDLog("Trying to allocate memory to FLIWheel\n"); if ((FLIWheel = malloc (sizeof (cam_t))) == NULL) { IDLog("malloc() failed.\n"); return -1; } for (i = 0; devlist[i] != NULL; i++) { int j; for (j = 0; devlist[i][j] != '\0'; j++) if (devlist[i][j] == ';') { devlist[i][j] = '\0'; break; } } FLIWheel->domain = domain; /* Each driver handles _only_ one camera for now */ switch (domain) { case FLIDOMAIN_PARALLEL_PORT: FLIWheel->dname = strdup("parallel port"); break; case FLIDOMAIN_USB: FLIWheel->dname = strdup("USB"); break; case FLIDOMAIN_SERIAL: FLIWheel->dname = strdup("serial"); break; case FLIDOMAIN_INET: FLIWheel->dname = strdup("inet"); break; default: FLIWheel->dname = strdup("Unknown domain"); } IDLog("Domain set OK\n"); FLIWheel->name = strdup(devlist[0]); if ((err = FLIFreeList(devlist))) { IDLog("FLIFreeList() failed. %s.\n", strerror((int)-err)); return -1; } } /* end if */ else { if ((err = FLIFreeList(devlist))) { IDLog("FLIFreeList() failed. %s.\n", strerror((int)-err)); return -1; } return -1; } IDLog("Findcam() finished successfully.\n"); return 0; } indi-0.5/src/lx200_16.h0000644000175000017500000000276010610474336012235 0ustar jrjr#ifndef LX200_16_H #define LX200_16_H /* LX200 16" Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "lx200autostar.h" class LX200_16 : public LX200Autostar { public: LX200_16(); ~LX200_16() {} void ISGetProperties (const char *dev); void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n); void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); void ISPoll (); void getBasicData(); void handleAltAzSlew(); private: double currentAlt; double currentAz; double targetAlt; double targetAz; }; void changeLX200_16DeviceName(const char * newName); #endif indi-0.5/src/robofocusdriver.h0000644000175000017500000000164410610474336014277 0ustar jrjr #if 0 Robofocus driver Copyright (C) 2006 Markus Wildi, markus.wildi@datacomm.ch This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #define BACKLASH_READOUT 99999 #define MAXTRAVEL_READOUT 99999 #define RF_TIMEOUT 5 indi-0.5/src/indi_v4l.cpp0000644000175000017500000000377610610474326013134 0ustar jrjr#if 0 V4L INDI Driver INDI Interface for V4L devices Copyright (C) 2003-2005 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include "v4ldriver.h" V4L_Driver *MainCam = NULL; /* Main and only camera */ /* send client definitions of all properties */ void ISInit() { if (MainCam == NULL) { MainCam = new V4L_Driver(); MainCam->initProperties("Video4Linux Generic Device"); MainCam->initCamBase(); } } void ISGetProperties (const char *dev) { ISInit(); MainCam->ISGetProperties(dev); } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { ISInit(); MainCam->ISNewSwitch(dev, name, states, names, n); } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { ISInit(); MainCam->ISNewText(dev, name, texts, names, n); } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { ISInit(); MainCam->ISNewNumber(dev, name, values, names, n); } void ISNewBLOB (const char */*dev*/, const char */*name*/, int */*sizes[]*/, char **/*blobs[]*/, char **/*formats[]*/, char **/*names[]*/, int /*n*/) { // We use this if we're receiving binary data from the client. Most likely we won't for this driver. } indi-0.5/src/temmadriver.c0000644000175000017500000005015510610474331013370 0ustar jrjr#if 0 Temma INDI driver Copyright (C) 2004 Francois Meyer (dulle @ free.fr) Remi Petitdemange for the temma protocol Reference site is http://dulle.free.fr/alidade/indi.php This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include #include #include #include #include #include #include #include "indicom.h" #include "indidevapi.h" #include "eventloop.h" #include "indicom.h" #include "temmadriver.h" char errormes[][128]={ "I/O Timeout", "Error reading from io port", "Error writing to io port", "Unrecognized message" }; char answer[32]; int fd; int read_ret, write_ret; unsigned char buffer[256]; unsigned char buffer2[256]; #if 1 /* Initlization routine */ static void mountInit() { static int inited; /* set once mountInit is called */ if (inited) return; /* setting default comm port */ PortT->text = realloc(PortT->text, 10); TemmaNoteT[0].text = realloc( TemmaNoteT[0].text, 64); TemmaNoteT[1].text = realloc( TemmaNoteT[1].text, 64); if (!PortT->text || !TemmaNoteT[0].text || !TemmaNoteT[1].text){ fprintf(stderr,"Memory allocation error"); return; } strcpy(PortT->text, "/dev/ttyS0"); strcpy(TemmaNoteT[0].text, "Experimental Driver"); strcpy(TemmaNoteT[1].text, "http://dulle.free.fr/alidade/indi.php"); inited = 1; } #endif void ISGetProperties (const char *dev) { if (dev && strcmp (mydev, dev)) return; mountInit(); IDDefSwitch (&powSw, NULL); IDDefNumber (&eqTemma, NULL); IDDefNumber (&eqNum, NULL); IDDefSwitch (&OnCoordSetSw, NULL); IDDefSwitch (&abortSlewSw, NULL); IDDefText (&TemmaNoteTP, NULL); IDDefSwitch (&RAmotorSw, NULL); IDDefSwitch (&trackmodeSw, NULL); IDDefText (&Port, NULL); IDDefText (&TemmaVersion, NULL); IDDefNumber (&Time, NULL); IDDefNumber (&SDTime, NULL); IDDefNumber (&cometNum, NULL); IDDefNumber (&geoNum, NULL); } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n) { dev=dev;name=name;sizes=sizes;blobs=blobs;formats=formats;names=names;n=n; } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { /*IText *tp;*/ if (strcmp (dev, mydev)) return; if (!strcmp (name, Port.name)) { IUSaveText(PortT, texts[0]); Port.s = IPS_OK; IDSetText (&Port, NULL); } return; } /* client is sending us a new value for a Numeric vector property */ void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { /* ignore if not ours */ if (strcmp (dev, mydev)) return; if (!strcmp (name, eqNum.name)) { /* new equatorial target coords */ /*double newra = 0, newdec = 0;*/ int i, nset; /* Check power, if it is off, then return */ if (power[0].s != ISS_ON) { eqNum.s = IPS_IDLE; IDSetNumber(&eqNum, "Power is off"); return; } for (nset = i = 0; i < n; i++) { /* Find numbers with the passed names in the eqNum property */ INumber *eqp = IUFindNumber (&eqNum, names[i]); /* If the number found is Right ascension (eq[0]) then process it */ if (eqp == &eq[0]) { currentRA = (values[i]); nset += currentRA >= 0 && currentRA <= 24; } /* Otherwise, if the number found is Declination (eq[1]) then process it */ else if (eqp == &eq[1]) { currentDec = (values[i]); nset += currentDec >= -90 && currentDec <= 90; } } /* end for */ /* Did we process the two numbers? */ if (nset == 2) { /*char r[32], d[32];*/ /* Set the mount state to BUSY */ eqNum.s = IPS_BUSY; if (SLEWSW==ISS_ON || TRACKSW==ISS_ON){ IDSetNumber(&eqNum, "Moving to RA Dec %f %f", currentRA, currentDec); do_TemmaGOTO(); } if (SYNCSW==ISS_ON){ IDSetNumber(&eqNum, "Syncing to RA Dec %f %f", currentRA, currentDec); set_TemmaCurrentpos(); } eqNum.s = IPS_OK; IDSetNumber(&eqNum, "Synced"); } /* We didn't process the two number correctly, report an error */ else { /* Set property state to idle */ eqNum.s = IPS_IDLE; IDSetNumber(&eqNum, "RA or Dec absent or bogus."); } return; } } /* client is sending us a new value for a Switch property */ void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { ISwitch *sp; /* ignore if not ours */ if (strcmp (dev, mydev)) return; if (!strcmp (name, powSw.name)) { sp = IUFindSwitch (&powSw, names[0]); if (!sp) return; fprintf(stderr,"new state %s\n",names[0]); sp->s = states[0]; if (!strcmp(names[0],"CONNECT")) { connectMount(); } if (!strcmp(names[0],"DISCONNECT")) { disconnectMount(); } } if (!strcmp (name, abortSlewSw.name)) { if (POWSW){ TemmaabortSlew(); IDSetSwitch (&abortSlewSw, "Abort slew"); } else { IDSetSwitch (&abortSlewSw, "Power is off"); } } if (!strcmp (name, RAmotorSw.name)) { if (POWSW){ sp = IUFindSwitch (&RAmotorSw, names[0]); if (!sp) return; fprintf(stderr,"new state %s\n",names[0]); sp->s = states[0]; RAmotorSw.s = IPS_BUSY; if (!strcmp(names[0],"RUN")) { set_TemmaStandbyState(0); } if (!strcmp(names[0],"STOP")) { set_TemmaStandbyState(1); } if(get_TemmaStandbyState(buffer)){ RAmotorSw.s = IPS_IDLE; IDSetSwitch (&RAmotorSw, "Error writing to port"); return; } } else { IDSetSwitch (&RAmotorSw, "Power is off"); } } if (!strcmp (name, OnCoordSetSw.name)) { if (POWSW){ IUResetSwitches(&OnCoordSetSw); sp = IUFindSwitch (&OnCoordSetSw, names[0]); if (!sp) return; fprintf(stderr,"new state %s\n",names[0]); sp->s = states[0]; IUResetSwitches(&OnCoordSetSw); IUUpdateSwitches(&OnCoordSetSw, states, names, n); /* currentSet = getOnSwitch(&OnCoordSetSw); */ OnCoordSetSw.s = IPS_OK; IDSetSwitch(&OnCoordSetSw, NULL); } else { IDSetSwitch (&OnCoordSetSw, "Power is off"); } } } double calcLST(char *strlst){ time_t computertime; struct tm gmt; double jd, gmst; double lst; /*int a,b;*/ time(&computertime); gmtime_r(&computertime, &gmt); gmt.tm_mon+=1; gmt.tm_year+=1900; currentUTC=(double)gmt.tm_hour+(double)gmt.tm_min/60+(double)gmt.tm_sec/3600; jd=UTtoJD(&gmt); gmst=JDtoGMST(jd); lst=(gmst-longitude)/15; lst=(lst/24-(int)(lst/24))*24; if(lst>=24) lst-=24; sprintf(strlst,"%.2d%.2d%.2d", (int)lst, ((int)(lst*60))%60, ((int)(lst*3600))%60); currentLST=lst; IDSetNumber (&SDTime, NULL); IDSetNumber (&Time, NULL); return 0; } #if 1 /* update the mount over time */ void readMountcurrentpos (void *p) { char result[32]; if(POWSW){ get_TemmaCurrentpos(result); calcLST(result); /* This is a temporary workaround to allow clients with only one eq property to work */ currentRA=temmaRA; currentDec=temmaDec; /* again */ IEAddTimer (POLLMS, readMountcurrentpos, NULL); } } #endif static void connectMount () { fprintf(stderr,"opening mount port %s\n",PortT->text); if (power[0].s == ISS_ON){ if (Port.s != IPS_OK){ powSw.s = IPS_IDLE; power[0].s = ISS_OFF; IDSetSwitch (&powSw, "Port not set."); return; } else { if (TemmaConnect(PortT->text)==0){ IDSetText (&Port, "Port is opened."); if( !get_TemmaVERSION(buffer)){ powSw.s = IPS_OK; power[0].s = ISS_ON; power[1].s = ISS_OFF; snprintf(buffer2,sizeof( buffer2 ),"%s",buffer+4); IDSetText(&TemmaVersion , "Temma version set"); TemmaVersionT->text = realloc(TemmaVersionT->text, strlen(buffer2)+1); if (!TemmaVersionT->text){ fprintf(stderr,"Memory allocation error"); return; } IDSetSwitch (&powSw, "Mount is ready"); IDSetSwitch (&powSw, VERSION); strcpy(TemmaVersionT->text, buffer2); TemmaVersion.s = IPS_OK; IDSetText (&TemmaVersion, NULL); IDLog("%s", buffer2); /* start timer to read mount coords */ IEAddTimer (POLLMS, readMountcurrentpos, NULL); } else { powSw.s = IPS_IDLE; power[0].s = ISS_OFF; power[1].s = ISS_ON; IDSetText(&Port , "Com error"); IDSetSwitch (&powSw, "Port not set."); } if(get_TemmaStandbyState(answer)){ IDSetSwitch (&RAmotorSw, "Error writing to port"); return; } } else { powSw.s = IPS_IDLE; power[0].s = ISS_OFF; power[1].s = ISS_ON; IDSetSwitch (&powSw, "Failed to open port."); } } } } static void disconnectMount () { fprintf(stderr,"closing mount port %s\n",PortT->text); if (power[1].s == ISS_ON){ if (Port.s != IPS_OK){ powSw.s = IPS_IDLE; power[0].s = ISS_OFF; IDSetSwitch (&powSw, "Port not set."); return; } else { TemmaDisconnect(); powSw.s = IPS_IDLE; power[0].s = ISS_OFF; IDSetSwitch (&powSw, "Port is closed."); } } else { fprintf(stderr, "Already disconnected \n"); } } int TemmaConnect(const char *device) { fprintf(stderr, "Connecting to device %s\n", device); if (openPort(device) < 0){ fprintf(stderr, "Error connecting to device %s\n", device); return -1; } else{ return 0; } } int TemmaDisconnect() { fprintf(stderr, "Disconnected.\n"); close(fd); return 0; } int set_CometTracking(int RArate, int DECrate){ #if 0 Set Comet Tracking LM+/-99999,+/-9999 RA : Adjust Sidereal time by seconds per Day DEC : Adjust DEC tracking by Minutes Per Day valeur DEC min=-600 /max=+600 (+/-10 deg / jour) Example: LM+120,+30 would slow the RA speed by 86164/86284 and the Dec would track at 30 Minutes a day. To stop tracking either send a LM0,0 (or a PS sauf erreur on constate en faite l inverse en RA retour Vsideral => LM0,0 ou LM+0,+0 #endif char local_buffer[16]; if (RArate<-21541){ RArate=-21541; } if (RArate>21541){ RArate=21541; } if (DECrate<-600){ DECrate=-600; } if (DECrate>600){ DECrate=600; } snprintf(local_buffer, sizeof( local_buffer ), "%+6d,%+5d", RArate, DECrate); set_TemmaCometTracking(local_buffer); return 0; } int TemmaabortSlew() { if (portWrite("PS") < 0) return -1; return 0; } int do_TemmaGOTO() { /* Temma Sync */ char command[16]; char sign; double dec; calcLST(buffer); set_TemmaLST(buffer); dec=fabs(currentDec); if (currentDec>0){ sign='+'; } else { sign='-'; } snprintf(buffer, sizeof(buffer),"%.2d%.2d%.2d%c%.2d%.2d%.1d", (int)currentRA,(int)(currentRA*(double)60)%60,((int)(currentRA*(double)6000))%100,sign, (int)dec,(int)(dec*(double)60)%60,((int)(dec*(double)600))%10); fprintf(stderr,"Goto %s\n", buffer); snprintf(command,14,"P%s",buffer); buffer[14]=0; fprintf(stderr,"Goto command:%s\n", command); portWrite(command); portRead(buffer,-1,TEMMA_TIMEOUT); if(command[0]=='R'){ return 0; } else return -1; } int extractRA(char *buf){ int r,h,m,s; /*double dra;*/ r=atoi(buf); h=r/10000; m=r/100-100*h; s=(r%100)*.6; temmaRA=((double)h+((double)m + (double)s/60)/60); IDSetNumber (&eqTemma, NULL); /* fprintf(stderr,"extractRA: %s %d %d %d %d %lf\n",buf,r,h,m,s,dra);*/ return 0; } int extractDEC(char *buf){ int dec,d,m,s; /*double ddec;*/ dec=atoi(buf+1); d=dec/1000; m=dec/10-100*d; s=(dec%10)*6; temmaDec=((double)d+((double)m + (double)s/60)/60); if (*buf=='-') temmaDec*=-1; IDSetNumber (&eqTemma, NULL); /* fprintf(stderr,"extractDEC: %s %d %d %d %d %lf\n",buf,dec,d,m,s,ddec);*/ return 0; } int get_TemmaCurrentpos(char *local_buffer){ char buf[16]; if (portWrite("E") < 0) return -1; if(portRead(local_buffer,-1,TEMMA_TIMEOUT)==SUCCESS){ if(strstr(local_buffer, "E")==local_buffer){ strncpy(buf,local_buffer+1,6); buf[6]=0; extractRA(buf); strncpy(buf,local_buffer+7,6); buf[6]=0; extractDEC(buf); return 0; } else { return -1; } } return 0; } int set_TemmaCurrentpos(void) { /* Temma Sync */ char buf[16], sign; double dec; calcLST(buf); set_TemmaLST(buf); portWrite("Z"); calcLST(buf); set_TemmaLST(buf); dec=fabs(currentDec); if (currentDec>0){ sign='+'; } else { sign='-'; } sprintf(buffer,"%.2d%.2d%.2d%c%.2d%.2d%.1d", (int)currentRA,(int)(currentRA*(double)60)%60,((int)(currentRA*(double)6000))%100,sign, (int)dec,(int)(dec*(double)60)%60,((int)(dec*(double)600))%10); fprintf(stderr,"sync to %s %f %f\n", buffer,currentRA,dec); snprintf(buf, sizeof(buf), "D%s",buffer); buf[13]=0; portWrite(buf); *buffer=0; portRead(buffer,-1,TEMMA_TIMEOUT); if(buffer[0]=='R'){ return 0; } else{ return -1; } } int do_TemmaSLEW(char mode){ /*char command[16];*/ sprintf(buffer,"M%c",mode); /* see bit definition in Temmadriver.h */ if (portWrite(buffer) < 0) return -1; return 0; } int get_TemmaVERSION(char *local_buffer){ int err; if ((err=portWrite("v")) < 0){ return err; } portRead(local_buffer,-1,TEMMA_TIMEOUT); if(strstr(local_buffer, "ver")==local_buffer){ return 0; } else return EREAD; } int get_TemmaGOTOstatus(char *local_buffer){ /* 0 no ongoing goto 1 ongoing Goto -1 error */ if (portWrite("s") < 0) return -1; portRead(local_buffer,-1,TEMMA_TIMEOUT); if(strstr(local_buffer, "s")==local_buffer){ return 0; } else return -1; } int get_TemmaBOTHcorrspeed(char *local_buffer){ if (portWrite("lg") < 0) return -1; portRead(local_buffer,-1,TEMMA_TIMEOUT); if(strstr(local_buffer, "lg")==local_buffer){ return 0; } else return -1; } int get_TemmaDECcorrspeed(char *local_buffer){ if (portWrite("lb") < 0) return -1; portRead(local_buffer,-1,TEMMA_TIMEOUT); if(strstr(local_buffer, "lb")==local_buffer){ return 0; } else return -1; } int set_TemmaDECcorrspeed(char *local_buffer){ char command[16]; snprintf(command, 4, "LB%s",local_buffer); if (portWrite(command) < 0) return -1; return 0; } int get_TemmaRAcorrspeed(char *local_buffer){ if (portWrite("la") < 0) return -1; portRead(local_buffer,-1,TEMMA_TIMEOUT); if(strstr(local_buffer, "la")==local_buffer){ return 0; } else return -1; } int set_TemmaRAcorrspeed(char *local_buffer){ char command[16]; snprintf(command, 4,"LA%s",local_buffer); if (portWrite(command) < 0) return -1; return 0; } int get_TemmaLatitude(char *local_buffer){ if (portWrite("i") < 0) return -1; portRead(local_buffer,-1,TEMMA_TIMEOUT); if(local_buffer[0]=='i'){ return 0; } else return -1; } int set_TemmaLatitude(char *local_buffer){ char command[16]; double lat; char sign; lat=fabs(latitude); if (latitude>0){ sign='+'; } else { sign='-'; } sprintf(command,"I%c%.2d%.2d%.1d", sign, (int)lat, (int)(lat*(double)60)%60, ((int)(lat*(double)600))%10); if (portWrite(command) < 0) return -1; return 0; } int get_TemmaLST(char *local_buffer){ if (portWrite("g") < 0) return -1; portRead(local_buffer,-1,TEMMA_TIMEOUT); if(local_buffer[0]=='g'){ return 0; } else return -1; } int set_TemmaLST(char *local_buffer){ char command[16]; snprintf(command,7,"T%s",local_buffer); if (portWrite(command) < 0) return -1; return 0; } int get_TemmaCometTracking(char *local_buffer){ if (portWrite("lm") < 0) return -1; portRead(local_buffer,-1,TEMMA_TIMEOUT); if(strstr(local_buffer, "lm")==local_buffer){ return 0; } else return -1; } int set_TemmaStandbyState(int on){ if (on){ return portWrite("STN-ON"); } else{ return portWrite("STN-OFF"); } return 0; } int get_TemmaStandbyState(unsigned char *local_buffer){ int nb; int status; if ((nb=portWrite("STN-COD")) < 0){ IDSetSwitch (&RAmotorSw, "I/O error when asking RAmotor status"); return -1; } if((status=portRead(local_buffer,-1,TEMMA_TIMEOUT)==SUCCESS)){ if(strstr(local_buffer, "stn")==local_buffer){ local_buffer[7]=0; if (strstr(local_buffer,"on")){ /* stanby on */ RAmotorSw.s = IPS_OK; RAmotor[0].s = ISS_OFF; RAmotor[1].s = ISS_ON; IDSetSwitch (&RAmotorSw, "RA motor is off."); } else{ if (strstr(local_buffer,"off")){ /* stanby off */ RAmotorSw.s = IPS_OK; RAmotor[0].s = ISS_ON; RAmotor[1].s = ISS_OFF; IDSetSwitch (&RAmotorSw, "RA motor is on."); } else { RAmotorSw.s = IPS_OK; IDSetSwitch (&RAmotorSw, "I/O error when getting RAmotor status"); } } } return 0; } if (status<=ETIMEOUT && status >=ECOMMAND){ IDSetSwitch(&RAmotorSw, "%s", errormes[ETIMEOUT - status]); } return -1; } int set_TemmaCometTracking(char *local_buffer){ char command[16]; snprintf(command,15,"LM%s",local_buffer); if (portWrite(command) < 0) return -1; return 0; } int set_TemmaSolarRate(void){ if (portWrite("LK") < 0) return -1; return 0; } int set_TemmaStellarRate(void){ if (portWrite("LL") < 0) return -1; return 0; } int switch_Temmamountside(void){ if (portWrite("PT") < 0) return -1; return 0; } /********************************************************************** * Comm **********************************************************************/ int openPort(const char *portID) { struct termios ttyOptions; if ( (fd = open(portID, O_RDWR)) == -1) return -1; memset(&ttyOptions, 0, sizeof(ttyOptions)); tcgetattr(fd, &ttyOptions); /* 8 bit, enable read */ ttyOptions.c_cflag |= CS8; /* parity */ ttyOptions.c_cflag |= PARENB; ttyOptions.c_cflag &= ~PARODD; ttyOptions.c_cflag &= ~CSTOPB; ttyOptions.c_cflag |= CRTSCTS; /* set baud rate */ cfsetispeed(&ttyOptions, B19200); cfsetospeed(&ttyOptions, B19200); /* set input/output flags */ ttyOptions.c_iflag = IGNBRK; /* Read at least one byte */ ttyOptions.c_cc[VMIN] = 1; ttyOptions.c_cc[VTIME] = 5; /* Misc. */ ttyOptions.c_lflag = 0; ttyOptions.c_oflag = 0; /* set attributes */ tcsetattr(fd, TCSANOW, &ttyOptions); /* flush the channel */ tcflush(fd, TCIOFLUSH); return (fd); } int portWrite(char * buf) { int nbytes=strlen(buf); /*, totalBytesWritten;*/ int bytesWritten = 0; /*int retry=10;*/ bytesWritten = write(fd, buf, nbytes); bytesWritten += write(fd, "\r\n", 2); /*fprintf(stderr,"portwrite :%d octets %s\n", bytesWritten, buf);*/ if (bytesWritten!=nbytes+2){ perror("write error: "); IDLog("Error writing to port"); return EWRITE; } return (bytesWritten); } int portRead(char *buf, int nbytes, int timeout) { /* A very basic finite state machine monitors the bytes read ; state 0 : read regular bytes state 1 : just read a \n, waiting for a \r state 2 : read a \n and a \r, command is over. Not sure it is useful here but I use a more sophisticated version of this with a GPS receiver and it is robust and reliable We return a null terminated string. */ int bytesRead = 0, state=0, /*i=0,*/ current=0; /*int totalBytesRead = 0;*/ int err; if ( (err = TemmareadOut(timeout)) ){ switch (err){ case ETIMEOUT: IDLog("Error: timeout while reading"); return err; } } while (read(fd,buf+bytesRead,1)==1){ /* fprintf(stderr,"%c",buf[bytesRead]); */ fflush(NULL); switch (state) { case 0: if(buf[bytesRead]==13) state=1; break; case 1: if(buf[bytesRead]==10) state=2; else if(buf[bytesRead]==13) state=1; else state=0; break; } ++current; if (state==2){ /*process(buf);*/ buf[bytesRead+1]=0; state=current=0; return SUCCESS; } bytesRead=current; } return state; } int TemmareadOut(int timeout) { struct timeval tv; fd_set readout; int retval; FD_ZERO(&readout); FD_SET(fd, &readout); /* wait for 'timeout' seconds */ tv.tv_sec = timeout; tv.tv_usec = 0; /* Wait till we have a change in the fd status */ retval = select (fd+1, &readout, NULL, NULL, &tv); /* Return 0 on successful fd change */ if (retval > 0) return 0; /* Return -1 due to an error */ else if (retval == EREAD) return retval; /* Return -2 if time expires before anything interesting happens */ else { return ETIMEOUT; } } indi-0.5/src/lilxml.c0000644000175000017500000004423610610525553012360 0ustar jrjr#if 0 liblilxml Copyright (C) 2003 Elwood C. Downey This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif /* little DOM-style XML parser. * only handles elements, attributes and pcdata content. * and are silently ignored. * pcdata is collected into one string, sans leading whitespace first line. * * #define MAIN_TST to create standalone test program */ #include #include #include #include "lilxml.h" /* used to efficiently manage growing malloced string space */ typedef struct { char *s; /* malloced memory for string */ int sl; /* string length, sans trailing \0 */ int sm; /* total malloced bytes */ } String; #define MINMEM 64 /* starting string length */ static int oneXMLchar (LilXML *lp, int c, char errmsg[]); static void initParser(LilXML *lp); static void pushXMLEle(LilXML *lp); static void popXMLEle(LilXML *lp); static void resetEndTag(LilXML *lp); static XMLAtt *growAtt(XMLEle *e); static void freeAtt (XMLAtt *a); static int isTokenChar (int start, int c); static void growString (String *sp, int c); static void appendString (String *sp, char *str); static void freeString (String *sp); static void newString (String *sp); static void *moremem (void *old, int n); typedef enum { LOOK4START = 0, /* looking for first element start */ LOOK4TAG, /* looking for element tag */ INTAG, /* reading tag */ LOOK4ATTRN, /* looking for attr name, > or / */ INATTRN, /* reading attr name */ LOOK4ATTRV, /* looking for attr value */ SAWSLASH, /* saw / in element opening */ INATTRV, /* in attr value */ LOOK4CON, /* skipping leading content whitespc */ INCON, /* reading content */ SAWLTINCON, /* saw < in content */ LOOK4CLOSETAG, /* looking for closing tag after < */ INCLOSETAG /* reading closing tag */ } State; /* parsing states */ /* maintain state while parsing */ struct _LilXML { State cs; /* current state */ int ln; /* line number for diags */ XMLEle *ce; /* current element being built */ String endtag; /* to check for match with opening tag*/ int delim; /* attribute value delimiter */ int lastc; /* last char (just used wiht skipping)*/ int skipping; /* in comment or declaration */ }; /* internal representation of a (possibly nested) XML element */ struct _xml_ele { String tag; /* element tag */ struct _xml_ele *pe; /* parent element, or NULL if root */ XMLAtt **at; /* list of attributes */ int nat; /* number of attributes */ int ait; /* used to iterate over at[] */ struct _xml_ele **el; /* list of child elements */ int nel; /* number of child elements */ int eit; /* used to iterate over el[] */ String pcdata; /* character data in this element */ }; /* internal representation of an attribute */ struct _xml_att { String name; /* name */ String valu; /* value */ struct _xml_ele *ce; /* containing element */ }; /* default memory managers, override with indi_xmlMalloc() */ static void *(*mymalloc)(size_t size) = malloc; static void *(*myrealloc)(void *ptr, size_t size) = realloc; static void (*myfree)(void *ptr) = free; /* install new version of malloc/realloc/free. * N.B. don't call after first use of any other lilxml function */ void indi_xmlMalloc (void *(*newmalloc)(size_t size), void *(*newrealloc)(void *ptr, size_t size), void (*newfree)(void *ptr)) { mymalloc = newmalloc; myrealloc = newrealloc; myfree = newfree; } /* pass back a fresh handle for use with our other functions */ LilXML * newLilXML () { LilXML *lp = (LilXML *) moremem (NULL, sizeof(LilXML)); memset (lp, 0, sizeof(LilXML)); initParser(lp); return (lp); } /* discard */ void delLilXML (LilXML *lp) { /* benign if NULL */ if (!lp) return; freeString(&lp->endtag); (*myfree) (lp); } /* delete ep and all its children */ void delXMLEle (XMLEle *ep) { int i; /* benign if NULL */ if (!ep) return; /* delete all parts of ep */ freeString (&ep->tag); freeString (&ep->pcdata); if (ep->at) { for (i = 0; i < ep->nat; i++) freeAtt (ep->at[i]); (*myfree) (ep->at); } if (ep->el) { for (i = 0; i < ep->nel; i++) delXMLEle (ep->el[i]); (*myfree) (ep->el); } /* delete ep itself */ (*myfree) (ep); } /* process one more character of an XML file. * when find closure with outter element return root of complete tree. * when find error return NULL with reason in errmsg[]. * when need more return NULL with errmsg[0] = '\0'. * N.B. it is up to the caller to delete any tree returned with delXMLEle(). */ XMLEle * readXMLEle (LilXML *lp, int newc, char errmsg[]) { XMLEle *root; int s; /* start optimistic */ errmsg[0] = '\0'; /* EOF? */ if (newc == 0) { sprintf (errmsg, "Line %d: early XML EOF", lp->ln); initParser(lp); return (NULL); } /* new line? */ if (newc == '\n') lp->ln++; /* skip comments and declarations. requires 1 char history */ if (!lp->skipping && lp->lastc == '<' && (newc == '?' || newc == '!')) { lp->skipping = 1; lp->lastc = newc; return (NULL); } if (lp->skipping) { if (newc == '>') lp->skipping = 0; lp->lastc = newc; return (NULL); } if (newc == '<') { lp->lastc = '<'; return (NULL); } /* do a pending '<' first then newc */ if (lp->lastc == '<') { if (oneXMLchar (lp, '<', errmsg) < 0) { initParser(lp); return (NULL); } /* N.B. we assume '<' will never result in closure */ } /* process newc (at last!) */ s = oneXMLchar (lp, newc, errmsg); if (s == 0) { lp->lastc = newc; return (NULL); } if (s < 0) { initParser(lp); return (NULL); } /* Ok! return ce and we start over. * N.B. up to caller to call delXMLEle with what we return. */ root = lp->ce; lp->ce = NULL; initParser(lp); return (root); } /* search ep for an attribute with given name. * return NULL if not found. */ XMLAtt * findXMLAtt (XMLEle *ep, const char *name) { int i; for (i = 0; i < ep->nat; i++) if (!strcmp (ep->at[i]->name.s, name)) return (ep->at[i]); return (NULL); } /* search ep for an element with given tag. * return NULL if not found. */ XMLEle * findXMLEle (XMLEle *ep, const char *tag) { int tl = strlen (tag); int i; for (i = 0; i < ep->nel; i++) { String *sp = &ep->el[i]->tag; if (sp->sl == tl && !strcmp (sp->s, tag)) return (ep->el[i]); } return (NULL); } /* iterate over each child element of ep. * call first time with first set to 1, then 0 from then on. * returns NULL when no more or err */ XMLEle * nextXMLEle (XMLEle *ep, int init) { int eit; if (init) ep->eit = 0; eit = ep->eit++; if (eit < 0 || eit >= ep->nel) return (NULL); return (ep->el[eit]); } /* iterate over each attribute of ep. * call first time with first set to 1, then 0 from then on. * returns NULL when no more or err */ XMLAtt * nextXMLAtt (XMLEle *ep, int init) { int ait; if (init) ep->ait = 0; ait = ep->ait++; if (ait < 0 || ait >= ep->nat) return (NULL); return (ep->at[ait]); } /* return parent of given XMLEle */ XMLEle * parentXMLEle (XMLEle *ep) { return (ep->pe); } /* return parent element of given XMLAtt */ XMLEle * parentXMLAtt (XMLAtt *ap) { return (ap->ce); } /* access functions */ /* return the tag name of the given element */ char * tagXMLEle (XMLEle *ep) { return (ep->tag.s); } /* return the pcdata portion of the given element */ char * pcdataXMLEle (XMLEle *ep) { return (ep->pcdata.s); } /* return the number of characters in the pcdata portion of the given element */ int pcdatalenXMLEle (XMLEle *ep) { return (ep->pcdata.sl); } /* return the nanme of the given attribute */ char * nameXMLAtt (XMLAtt *ap) { return (ap->name.s); } /* return the value of the given attribute */ char * valuXMLAtt (XMLAtt *ap) { return (ap->valu.s); } /* return the number of child elements of the given element */ int nXMLEle (XMLEle *ep) { return (ep->nel); } /* return the number of attributes in the given element */ int nXMLAtt (XMLEle *ep) { return (ep->nat); } /* search ep for an attribute with the given name and return its value. * return "" if not found. */ char * findXMLAttValu (XMLEle *ep, const char *name) { XMLAtt *a = findXMLAtt (ep, name); return (a ? a->valu.s : ""); } /* handy wrapper to read one xml file. * return root element else NULL with report in errmsg[] */ XMLEle * readXMLFile (FILE *fp, LilXML *lp, char errmsg[]) { int c; while ((c = fgetc(fp)) != EOF) { XMLEle *root = readXMLEle (lp, c, errmsg); if (root || errmsg[0]) return (root); } return (NULL); } /* add an attribute to the given XML element */ void addXMLAtt (XMLEle *ep, const char *name, char *valu) { XMLAtt *ap = growAtt (ep); appendString (&ap->name, name); appendString (&ap->valu, valu); } /* remove the named attribute from ep, if any */ void rmXMLAtt (XMLEle *ep, const char *name) { int i; for (i = 0; i < ep->nat; i++) { if (strcmp (ep->at[i]->name.s, name) == 0) { freeAtt (ep->at[i]); memmove (&ep->at[i],&ep->at[i+1],(--ep->nat-i)*sizeof(XMLAtt*)); return; } } } /* sample print ep to fp * N.B. set level = 0 on first call */ #define PRINDENT 4 /* sample print indent each level */ void prXMLEle (FILE *fp, XMLEle *ep, int level) { int indent = level*PRINDENT; int i; fprintf (fp, "%*s<%s", indent, "", ep->tag.s); for (i = 0; i < ep->nat; i++) fprintf (fp, " %s=\"%s\"", ep->at[i]->name.s, ep->at[i]->valu.s); if (ep->nel > 0) { fprintf (fp, ">\n"); for (i = 0; i < ep->nel; i++) prXMLEle (fp, ep->el[i], level+1); } if (ep->pcdata.sl > 0) { char *nl; if (ep->nel == 0) fprintf (fp, ">\n"); /* indent if none or one line */ nl = strpbrk (ep->pcdata.s, "\n\r"); if (!nl || nl == &ep->pcdata.s[ep->pcdata.sl-1]) fprintf (fp, "%*s", indent+PRINDENT, ""); fprintf (fp, "%s", ep->pcdata.s); if (!nl) fprintf (fp, "\n"); } if (ep->nel > 0 || ep->pcdata.sl > 0) fprintf (fp, "%*s\n", indent, "", ep->tag.s); else fprintf (fp, "/>\n"); } /* process one more char in XML file. * if find final closure, return 1 and tree is in ce. * if need more, return 0. * if real trouble, return -1 and put reason in errmsg. */ static int oneXMLchar (LilXML *lp, int c, char errmsg[]) { switch (lp->cs) { case LOOK4START: /* looking for first element start */ if (c == '<') { pushXMLEle(lp); lp->cs = LOOK4TAG; } /* silently ignore until resync */ break; case LOOK4TAG: /* looking for element tag */ if (isTokenChar (1, c)) { growString (&lp->ce->tag, c); lp->cs = INTAG; } else if (!isspace(c)) { sprintf (errmsg, "Line %d: Bogus tag char %c", lp->ln, c); return (-1); } break; case INTAG: /* reading tag */ if (isTokenChar (0, c)) growString (&lp->ce->tag, c); else if (c == '>') lp->cs = LOOK4CON; else if (c == '/') lp->cs = SAWSLASH; else lp->cs = LOOK4ATTRN; break; case LOOK4ATTRN: /* looking for attr name, > or / */ if (c == '>') lp->cs = LOOK4CON; else if (c == '/') lp->cs = SAWSLASH; else if (isTokenChar (1, c)) { XMLAtt *ap = growAtt(lp->ce); growString (&ap->name, c); lp->cs = INATTRN; } else if (!isspace(c)) { sprintf (errmsg, "Line %d: Bogus leading attr name char: %c", lp->ln, c); return (-1); } break; case SAWSLASH: /* saw / in element opening */ if (c == '>') { if (!lp->ce->pe) return(1); /* root has no content */ popXMLEle(lp); lp->cs = LOOK4CON; } else { sprintf (errmsg, "Line %d: Bogus char %c before >", lp->ln, c); return (-1); } break; case INATTRN: /* reading attr name */ if (isTokenChar (0, c)) growString (&lp->ce->at[lp->ce->nat-1]->name, c); else if (isspace(c) || c == '=') lp->cs = LOOK4ATTRV; else { sprintf (errmsg, "Line %d: Bogus attr name char: %c", lp->ln,c); return (-1); } break; case LOOK4ATTRV: /* looking for attr value */ if (c == '\'' || c == '"') { lp->delim = c; lp->cs = INATTRV; } else if (!(isspace(c) || c == '=')) { sprintf (errmsg, "Line %d: No value for attribute %s", lp->ln, lp->ce->at[lp->ce->nat-1]->name.s); return (-1); } break; case INATTRV: /* in attr value */ if (c == lp->delim) lp->cs = LOOK4ATTRN; else if (!iscntrl(c)) growString (&lp->ce->at[lp->ce->nat-1]->valu, c); break; case LOOK4CON: /* skipping leading content whitespace*/ if (c == '<') lp->cs = SAWLTINCON; else if (!isspace(c)) { growString (&lp->ce->pcdata, c); lp->cs = INCON; } break; case INCON: /* reading content */ if (c == '<') { /* if text contains a nl trim trailing blanks. * chomp trailing nl if it's the only one. */ char *nl = strpbrk (lp->ce->pcdata.s, "\n\r"); if (nl) while (lp->ce->pcdata.sl > 0 && lp->ce->pcdata.s[lp->ce->pcdata.sl-1] == ' ') lp->ce->pcdata.s[--(lp->ce->pcdata.sl)] = '\0'; if (nl == &lp->ce->pcdata.s[lp->ce->pcdata.sl-1]) lp->ce->pcdata.s[--(lp->ce->pcdata.sl)] = '\0';/*safe!*/ lp->cs = SAWLTINCON; } else { growString (&lp->ce->pcdata, c); } break; case SAWLTINCON: /* saw < in content */ if (c == '/') { resetEndTag(lp); lp->cs = LOOK4CLOSETAG; } else { pushXMLEle(lp); if (isTokenChar(1,c)) { growString (&lp->ce->tag, c); lp->cs = INTAG; } else lp->cs = LOOK4TAG; } break; case LOOK4CLOSETAG: /* looking for closing tag after < */ if (isTokenChar (1, c)) { growString (&lp->endtag, c); lp->cs = INCLOSETAG; } else if (!isspace(c)) { sprintf (errmsg, "Line %d: Bogus preend tag char %c", lp->ln,c); return (-1); } break; case INCLOSETAG: /* reading closing tag */ if (isTokenChar(0, c)) growString (&lp->endtag, c); else if (c == '>') { if (strcmp (lp->ce->tag.s, lp->endtag.s)) { sprintf (errmsg,"Line %d: closing tag %s does not match %s", lp->ln, lp->endtag.s, lp->ce->tag.s); return (-1); } else if (lp->ce->pe) { popXMLEle(lp); lp->cs = LOOK4CON; /* back to content after nested elem */ } else return (1); /* yes! */ } else if (!isspace(c)) { sprintf (errmsg, "Line %d: Bogus end tag char %c", lp->ln, c); return (-1); } break; } return (0); } /* set up for a fresh start again */ static void initParser(LilXML *lp) { delXMLEle (lp->ce); freeString (&lp->endtag); memset (lp, 0, sizeof(*lp)); newString (&lp->endtag); lp->cs = LOOK4START; lp->ln = 1; } /* start a new XMLEle. * point ce to a new XMLEle. * if ce already set up, add to its list of child elements too. * endtag no longer valid. */ static void pushXMLEle(LilXML *lp) { XMLEle *newe = (XMLEle *) moremem (NULL, sizeof(XMLEle)); XMLEle *ce = lp->ce; memset (newe, 0, sizeof(*newe)); newString (&newe->tag); newString (&newe->pcdata); newe->pe = ce; lp->ce = newe; resetEndTag(lp); if (ce) { ce->el = (XMLEle **) moremem (ce->el, (ce->nel+1)*sizeof(XMLEle *)); ce->el[ce->nel++] = newe; } } /* point ce to parent of current ce. * endtag no longer valid. */ static void popXMLEle(LilXML *lp) { lp->ce = lp->ce->pe; resetEndTag(lp); } /* add room for and return one new XMLAtt to the given element */ static XMLAtt * growAtt(XMLEle *ep) { XMLAtt *newa = (XMLAtt *) moremem (NULL, sizeof(XMLAtt)); memset (newa, 0, sizeof(*newa)); newString(&newa->name); newString(&newa->valu); newa->ce = ep; ep->at = (XMLAtt **) moremem (ep->at, (ep->nat+1)*sizeof(XMLAtt *)); ep->at[ep->nat++] = newa; return (newa); } /* free a and all it holds */ static void freeAtt (XMLAtt *a) { if (!a) return; freeString (&a->name); freeString (&a->valu); (*myfree)(a); } /* reset endtag */ static void resetEndTag(LilXML *lp) { freeString (&lp->endtag); newString (&lp->endtag); } /* 1 if c is a valid token character, else 0. * it can be alpha or '_' or numeric unless start. */ static int isTokenChar (int start, int c) { return (isalpha(c) || c == '_' || (!start && isdigit(c))); } /* grow the String storage at *sp to append c */ static void growString (String *sp, int c) { int l = sp->sl + 2; /* need room for '\0' plus c */ if (l > sp->sm) { if (!sp->s) newString (sp); else sp->s = (char *) moremem (sp->s, sp->sm *= 2); } sp->s[--l] = '\0'; sp->s[--l] = (char)c; sp->sl++; } /* append str to the String storage at *sp */ static void appendString (String *sp, char *str) { int strl = strlen (str); int l = sp->sl + strl + 1; /* need room for '\0' */ if (l > sp->sm) { if (!sp->s) newString (sp); if (l > sp->sm) sp->s = (char *) moremem (sp->s, (sp->sm = l)); } strcpy (&sp->s[sp->sl], str); sp->sl += strl; } /* init a String with a malloced string containing just \0 */ static void newString(String *sp) { sp->s = (char *)moremem(NULL, MINMEM); sp->sm = MINMEM; *sp->s = '\0'; sp->sl = 0; } /* free memory used by the given String */ static void freeString (String *sp) { if (sp->s) (*myfree) (sp->s); sp->s = NULL; sp->sl = 0; sp->sm = 0; } /* like malloc but knows to use realloc if already started */ static void * moremem (void *old, int n) { return (old ? (*myrealloc)(old, n) : (*mymalloc)(n)); } #if defined(MAIN_TST) int main (int ac, char *av[]) { LilXML *lp = newLilXML(); char errmsg[1024]; XMLEle *root; root = readXMLFile (stdin, lp, errmsg); if (root) { fprintf (stderr, "::::::::::::: %s\n", tagXMLEle(root)); prXMLEle (stdout, root, 0); delXMLEle (root); } else if (errmsg[0]) { fprintf (stderr, "Error: %s\n", errmsg); } delLilXML (lp); return (0); } #endif indi-0.5/src/celestronprotocol.h0000644000175000017500000000760110610474336014641 0ustar jrjr/* * Header File for the Telescope Control protocols for the Meade LX200 * Author: John Kielkopf (kielkopf@louisville.edu) * * This file contains header information used in common with xmtel. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 15 May 2003 -- Version 2.00 * */ #ifndef CELESTRON_PROTOCOL_H #define CELESTRON_PROTOCOL_H /* These are user defined quantities that set the limits over which it */ /* is safe to operate the telescope. */ /* LOWER is the number of degrees from the zenith that you will allow. */ /* Use 80, for example, to keep the eyepiece end out of the fork arm space */ /* of an LX200 telescope. */ #define LOWER 90. /* HIGHER is the horizon. 0 is an unobstructed horizon in every direction. */ /* Use 10, for example, to limit sighting below 10 degrees above the horizon. */ #define HIGHER 0. /* Set this if a slew to the north sends the telescope south. */ #define REVERSE_NS 0 /* 1 for reverse; 0 for normal. */ /* Set this for maximum slew rate allowed in degree/sec. */ #define MAXSLEWRATE 4 /* 2 for safety; 4 for 16-inch; 8 otherwise. */ /* The following parameters are used internally to set speed and direction. */ /* Do not change these values. */ #define SLEW 0 #define FIND 1 #define CENTER 2 #define GUIDE 3 #if REVERSE_NS > 0 #define NORTH 3 #define SOUTH 0 #else #define NORTH 0 #define SOUTH 3 #endif #define EAST 2 #define WEST 1 /* Slew speed defines */ # define SLEWRATE8 8 /* should be 8 degrees per second (not 16-inch) */ # define SLEWRATE4 4 /* should be 4 degrees per second */ # define SLEWRATE3 3 /* should be 3 degrees per second */ # define SLEWRATE2 2 /* should be 2 degrees per second */ /* Reticle defines */ #define BRIGHTER 16 /* increase */ #define DIMMER 8 /* decrease */ #define BLINK0 0 /* no blinking */ #define BLINK1 1 /* blink rate 1 */ #define BLINK2 2 /* blink rate 2 */ #define BLINK3 4 /* blink rate 3 */ /* Focus defines */ #define FOCUSOUT 8 /* positive voltage output */ #define FOCUSIN 4 /* negative voltage output */ #define FOCUSSTOP 0 /* no output */ #define FOCUSSLOW 1 /* half voltage */ #define FOCUSFAST 2 /* full voltage */ /* Rotator defines */ #define ROTATORON 1 /* image rotator on */ #define ROTATOROFF 0 /* image rotator off */ /* Fan defines */ #define FANON 1 /* cooling fan on */ #define FANOFF 0 /* cooling fan off */ #ifdef __cplusplus extern "C" { #endif int ConnectTel(char *port); void DisconnectTel(void); int CheckConnectTel(void); void SetRate(int newRate); void SetLimits(double limitLower, double limitHigher); void StartSlew(int direction); void StopSlew(int direction); double GetRA(void); double GetDec(void); int SlewToCoords(double newRA, double newDec); int SyncToCoords(double newRA, double newDec); int CheckCoords(double desRA, double desDec, double tolRA, double tolDEC); void StopNSEW(void); int SetSlewRate(void); int SyncLST(double newTime); int SyncLocalTime(); void Reticle(int reticle); void Focus(int focus); void Derotator(int rotate); void Fan(int fan); #ifdef __cplusplus } #endif #endif indi-0.5/src/observer.h0000755000175000017500000000466210610474336012717 0ustar jrjr#if 0 INDI Copyright (C) 2006 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Changelog: 2006-09-23: Start (JM) #endif #ifndef OBSERVER_H #define OBSERVER_H #include "lilxml.h" typedef enum { IDS_DEFINED, IDS_UPDATED, IDS_DELETED, IDS_DIED } IDState; /* Property state in observer pattern */ typedef enum { IDT_VALUE, IDT_STATE, IDT_ALL } IDType; /* Notification type */ typedef enum { IPT_SWITCH, IPT_TEXT, IPT_NUMBER, IPT_LIGHT, IPT_BLOB } IPType; /* Property type */ /* Generic function pointer */ typedef void (*fpt)(); /* Switch Property Callback */ typedef void (CBSP) (const char *dev, const char *name, IDState driver_state, ISState *states, char *names[], int n); /* Text Property Callback */ typedef void (CBTP) (const char *dev, const char *name, IDState driver_state, char *texts[], char *names[], int n); /* Number Property Callback */ typedef void (CBNP) (const char *dev, const char *name, IDState driver_state, double values[], char *names[], int n); /* Light Property Callback */ typedef void (CBLP) (const char *dev, const char *name, IDState driver_state, ISState *states, char *names[], int n); /* Blob Property Callback */ typedef void (CBBP) (const char *dev, const char *name, IDState driver_state, int sizes[], char *blobs[], char *formats[], char *names[], int n); #ifdef __cplusplus extern "C" { #endif void IOSubscribeProperty(const char *dev, const char *name, IPType property_type, IDType notification_type, fpt fp); void IOUnsubscribeProperty(const char *dev, const char *name); int processObservers(XMLEle *root); const char * idtypeStr(IDType type); int crackObserverState(char *stateStr); int crackPropertyState(char *pstateStr); #ifdef __cplusplus } #endif #endif indi-0.5/src/lx200classic.h0000644000175000017500000000272210610474336013267 0ustar jrjr/* LX200 Classic Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef LX200CLASSIC_H #define LX200CLASSIC_H #include "lx200generic.h" class LX200Classic : public LX200Generic { public: LX200Classic(); ~LX200Classic() {} void ISGetProperties (const char *dev); void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n); void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); void ISPoll (); void getBasicData(); private: int currentCatalog; int currentSubCatalog; }; void changeLX200ClassicDeviceName(const char *newName); #endif indi-0.5/src/skycommander.c0000644000175000017500000001104110610474331013534 0ustar jrjr#if 0 Sky Commander INDI driver Copyright (C) 2005 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include "config.h" #include #include #include #include #include #include #include #include "indidevapi.h" #include "indicom.h" #include "lx200driver.h" #define mydev "Sky Commander" #define BASIC_GROUP "Main Control" #define POLLMS 1000 #define currentRA eq[0].value #define currentDEC eq[1].value static void ISPoll(void *); static void ISInit(void); static void connectTelescope(void); int fd; static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}}; ISwitchVectorProperty PowerSP = { mydev, "CONNECTION" , "Connection", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0}; static IText PortT[] = {{"PORT", "Port", 0, 0, 0, 0}}; static ITextVectorProperty PortTP = { mydev, "DEVICE_PORT", "Ports", BASIC_GROUP, IP_RW, 0, IPS_IDLE, PortT, NARRAY(PortT), "", 0}; /* equatorial position */ INumber eq[] = { {"RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0., 0, 0, 0}, {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}, }; INumberVectorProperty eqNum = { mydev, "EQUATORIAL_EOD_COORD", "Equatorial JNow", BASIC_GROUP, IP_RO, 0, IPS_IDLE, eq, NARRAY(eq), "", 0}; void ISInit(void) { static int isInit=0; if (isInit) return; isInit = 1; fd = -1; IEAddTimer (POLLMS, ISPoll, NULL); } void ISGetProperties (const char *dev) { ISInit(); dev=dev; IDDefSwitch(&PowerSP, NULL); IDDefText(&PortTP, NULL); IDDefNumber(&eqNum, NULL); } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { ISInit(); dev = dev; if (!strcmp(name, PowerSP.name)) { IUResetSwitches(&PowerSP); IUUpdateSwitches(&PowerSP, states, names, n); connectTelescope(); return; } } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { ISInit(); dev=dev; names=names; n=n; if (!strcmp(name, PortTP.name)) { IUSaveText(&PortT[0], texts[0]); PortTP.s = IPS_OK; IDSetText(&PortTP, NULL); return; } } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { dev=dev;name=name;values=values;names=names;n=n; } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n) { dev=dev;name=name;sizes=sizes;blobs=blobs;formats=formats;names=names;n=n; } void ISPoll (void *p) { p=p; if (PowerS[0].s == ISS_ON) { switch (eqNum.s) { case IPS_IDLE: case IPS_OK: case IPS_BUSY: if (updateSkyCommanderCoord(fd, ¤tRA, ¤tDEC) < 0) { eqNum.s = IPS_ALERT; IDSetNumber(&eqNum, "Unknown error while reading telescope coordinates"); IDLog("Unknown error while reading telescope coordinates\n"); break; } IDSetNumber(&eqNum, NULL); break; case IPS_ALERT: break; } } IEAddTimer(POLLMS, ISPoll, NULL); } void connectTelescope(void) { switch (PowerS[0].s) { case ISS_ON: if (tty_connect(PortT[0].text, 9600, 8, 0, 1, &fd) != TTY_OK) { PowerSP.s = IPS_ALERT; IUResetSwitches(&PowerSP); IDSetSwitch(&PowerSP, "Error connecting to port %s", PortT[0].text); return; } PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "Sky Commander is online."); break; case ISS_OFF: tty_disconnect(fd); IUResetSwitches(&PowerSP); eqNum.s = PortTP.s = PowerSP.s = IPS_IDLE; IDSetSwitch(&PowerSP, "Sky Commander is offline."); IDSetText(&PortTP, NULL); IDSetNumber(&eqNum, NULL); break; } } indi-0.5/src/v4lphilips.cpp0000644000175000017500000004172610610474326013517 0ustar jrjr/* Phlips webcam INDI driver Copyright (C) 2003-2005 by Jasem Mutlaq This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 2005.04.29 JM: There is no need for this file for Video 4 Linux 2. It is kept for V4L 1 compatibility. */ #include "v4lphilips.h" #include "webcam/pwc-ioctl.h" V4L_Philips::V4L_Philips() : V4L_Driver() { } V4L_Philips::~V4L_Philips() { } void V4L_Philips::initCamBase() { #ifdef HAVE_LINUX_VIDEODEV2_H v4l_base = new V4L2_Base(); #else v4l_pwc = new V4L1_PWC(); v4l_base = (V4L1_Base *) v4l_pwc; #endif } void V4L_Philips::initProperties(const char *dev) { // Call parent V4L_Driver::initProperties(dev); IUFillSwitch(&BackLightS[0], "ON", "", ISS_OFF); IUFillSwitch(&BackLightS[1], "OFF", "", ISS_ON); IUFillSwitchVector(&BackLightSP, BackLightS, NARRAY(BackLightS), dev, "Back Light", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0 , IPS_IDLE); IUFillSwitch(&AntiFlickerS[0], "ON", "", ISS_OFF); IUFillSwitch(&AntiFlickerS[1], "OFF", "", ISS_ON); IUFillSwitchVector(&AntiFlickerSP, AntiFlickerS, NARRAY(AntiFlickerS), dev, "Anti Flicker", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0 , IPS_IDLE); IUFillSwitch(&NoiseReductionS[0], "None", "", ISS_ON); IUFillSwitch(&NoiseReductionS[1], "Low", "", ISS_OFF); IUFillSwitch(&NoiseReductionS[2], "Medium", "", ISS_OFF); IUFillSwitch(&NoiseReductionS[3], "High", "", ISS_OFF); IUFillSwitchVector(&NoiseReductionSP, NoiseReductionS, NARRAY(NoiseReductionS), dev, "Noise Reduction", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0, IPS_IDLE); IUFillSwitch(&CamSettingS[0], "Save", "", ISS_OFF); IUFillSwitch(&CamSettingS[1], "Restore", "", ISS_OFF); IUFillSwitch(&CamSettingS[2], "Factory", "", ISS_OFF); IUFillSwitchVector(&CamSettingSP, CamSettingS, NARRAY(CamSettingS), dev, "Settings", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0, IPS_IDLE); IUFillSwitch(&WhiteBalanceModeS[0], "Auto" , "", ISS_ON); IUFillSwitch(&WhiteBalanceModeS[1], "Manual" , "", ISS_OFF); IUFillSwitch(&WhiteBalanceModeS[2], "Indoor" , "", ISS_OFF); IUFillSwitch(&WhiteBalanceModeS[3], "Outdoor" , "", ISS_OFF); IUFillSwitch(&WhiteBalanceModeS[4], "Fluorescent" , "", ISS_OFF); IUFillSwitchVector(&WhiteBalanceModeSP, WhiteBalanceModeS, NARRAY(WhiteBalanceModeS), dev, "White Balance Mode", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0, IPS_IDLE); IUFillNumber(&WhiteBalanceN[0], "Manual Red", "", "%0.f", 0., 256., 1., 0.); IUFillNumber(&WhiteBalanceN[1], "Manual Blue", "", "%0.f", 0., 256., 1., 0.); IUFillNumberVector(&WhiteBalanceNP, WhiteBalanceN, NARRAY(WhiteBalanceN), dev, "White Balance", "", IMAGE_CONTROL, IP_RW, 60, IPS_IDLE); IUFillNumber(&ShutterSpeedN[0], "Speed", "", "%0.f", 0., 65535., 100., 0.); IUFillNumberVector(&ShutterSpeedNP, ShutterSpeedN, NARRAY(ShutterSpeedN), dev, "Shutter Speed", "", COMM_GROUP, IP_RW, 60, IPS_IDLE); } void V4L_Philips::ISGetProperties (const char *dev) { if (dev && strcmp (device_name, dev)) return; #ifdef HAVE_LINUX_VIDEODEV2_H V4L_Driver::ISGetProperties(dev); return; #endif /* COMM_GROUP */ IDDefSwitch(&PowerSP, NULL); IDDefText(&PortTP, NULL); IDDefText(&camNameTP, NULL); IDDefSwitch(&StreamSP, NULL); IDDefNumber(&FrameRateNP, NULL); IDDefNumber(&ExposeTimeNP, NULL); IDDefNumber(&ShutterSpeedNP, NULL); IDDefBLOB(&imageBP, NULL); /* Image Groups */ IDDefSwitch(&CompressSP, NULL); IDDefSwitch(&ImageTypeSP, NULL); IDDefNumber(&FrameNP, NULL); IDDefNumber(&ImageAdjustNP, NULL); /* Image Control */ IDDefSwitch(&WhiteBalanceModeSP, NULL); IDDefNumber(&WhiteBalanceNP, NULL); IDDefSwitch(&BackLightSP, NULL); IDDefSwitch(&AntiFlickerSP, NULL); IDDefSwitch(&NoiseReductionSP, NULL); IDDefSwitch(&CamSettingSP, NULL); } void V4L_Philips::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { char errmsg[ERRMSG_SIZE]; int index=0; /* ignore if not ours */ if (dev && strcmp (device_name, dev)) return; /* Connection */ if (!strcmp (name, PowerSP.name)) { IUResetSwitches(&PowerSP); IUUpdateSwitches(&PowerSP, states, names, n); connectCamera(); return; } #ifndef HAVE_LINUX_VIDEODEV2_H /* Anti Flicker control */ if (!strcmp (AntiFlickerSP.name, name)) { if (checkPowerS(&AntiFlickerSP)) return; AntiFlickerSP.s = IPS_IDLE; IUResetSwitches(&AntiFlickerSP); IUUpdateSwitches(&AntiFlickerSP, states, names, n); if (AntiFlickerS[0].s == ISS_ON) { if (v4l_pwc->setFlicker(true, errmsg) < 0) { AntiFlickerS[0].s = ISS_OFF; AntiFlickerS[1].s = ISS_ON; IDSetSwitch(&AntiFlickerSP, "%s", errmsg); return; } AntiFlickerSP.s = IPS_OK; IDSetSwitch(&AntiFlickerSP, NULL); } else { if (v4l_pwc->setFlicker(false, errmsg) < 0) { AntiFlickerS[0].s = ISS_ON; AntiFlickerS[1].s = ISS_OFF; IDSetSwitch(&AntiFlickerSP, "%s", errmsg); return; } IDSetSwitch(&AntiFlickerSP, NULL); } return; } /* Back light compensation */ if (!strcmp (BackLightSP.name, name)) { if (checkPowerS(&BackLightSP)) return; BackLightSP.s = IPS_IDLE; IUResetSwitches(&BackLightSP); IUUpdateSwitches(&BackLightSP, states, names, n); if (BackLightS[0].s == ISS_ON) { if (v4l_pwc->setBackLight(true, errmsg) < 0) { BackLightS[0].s = ISS_OFF; BackLightS[1].s = ISS_ON; IDSetSwitch(&BackLightSP, "%s", errmsg); return; } BackLightSP.s = IPS_OK; IDSetSwitch(&BackLightSP, NULL); } else { if (v4l_pwc->setBackLight(false, errmsg) < 0) { BackLightS[0].s = ISS_ON; BackLightS[1].s = ISS_OFF; IDSetSwitch(&BackLightSP, "%s", errmsg); return; } IDSetSwitch(&BackLightSP, NULL); } return; } /* Noise reduction control */ if (!strcmp (NoiseReductionSP.name, name)) { if (checkPowerS(&NoiseReductionSP)) return; NoiseReductionSP.s = IPS_IDLE; IUResetSwitches(&NoiseReductionSP); IUUpdateSwitches(&NoiseReductionSP, states, names, n); for (int i=0; i < 4; i++) if (NoiseReductionS[i].s == ISS_ON) { index = i; break; } if (v4l_pwc->setNoiseRemoval(index, errmsg) < 0) { IUResetSwitches(&NoiseReductionSP); NoiseReductionS[0].s = ISS_ON; IDSetSwitch(&NoiseReductionSP, "%s", errmsg); return; } NoiseReductionSP.s = IPS_OK; IDSetSwitch(&NoiseReductionSP, NULL); return; } /* White balace mode */ if (!strcmp (WhiteBalanceModeSP.name, name)) { if (checkPowerS(&WhiteBalanceModeSP)) return; WhiteBalanceModeSP.s = IPS_IDLE; IUResetSwitches(&WhiteBalanceModeSP); IUUpdateSwitches(&WhiteBalanceModeSP, states, names, n); for (int i=0; i < 5; i++) if (WhiteBalanceModeS[i].s == ISS_ON) { index = i; break; } switch (index) { // Auto case 0: if (v4l_pwc->setWhiteBalanceMode(PWC_WB_AUTO, errmsg) < 0) { IUResetSwitches(&WhiteBalanceModeSP), WhiteBalanceModeS[0].s = ISS_ON; IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg); return; } break; // Manual case 1: if (v4l_pwc->setWhiteBalanceMode(PWC_WB_MANUAL, errmsg) < 0) { IUResetSwitches(&WhiteBalanceModeSP), WhiteBalanceModeS[0].s = ISS_ON; IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg); return; } break; // Indoor case 2: if (v4l_pwc->setWhiteBalanceMode(PWC_WB_INDOOR, errmsg) < 0) { IUResetSwitches(&WhiteBalanceModeSP), WhiteBalanceModeS[0].s = ISS_ON; IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg); return; } break; // Outdoor case 3: if (v4l_pwc->setWhiteBalanceMode(PWC_WB_OUTDOOR, errmsg) < 0) { IUResetSwitches(&WhiteBalanceModeSP), WhiteBalanceModeS[0].s = ISS_ON; IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg); return; } break; // Flurescent case 4: if (v4l_pwc->setWhiteBalanceMode(PWC_WB_FL, errmsg) < 0) { IUResetSwitches(&WhiteBalanceModeSP), WhiteBalanceModeS[0].s = ISS_ON; IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg); return; } break; } WhiteBalanceModeSP.s = IPS_OK; IDSetSwitch(&WhiteBalanceModeSP, NULL); return; } /* Camera setttings */ if (!strcmp (CamSettingSP.name, name)) { if (checkPowerS(&CamSettingSP)) return; CamSettingSP.s = IPS_IDLE; IUResetSwitches(&CamSettingSP); IUUpdateSwitches(&CamSettingSP, states, names, n); if (CamSettingS[0].s == ISS_ON) { if (v4l_pwc->saveSettings(errmsg) < 0) { IUResetSwitches(&CamSettingSP); IDSetSwitch(&CamSettingSP, "%s", errmsg); return; } CamSettingSP.s = IPS_OK; IDSetSwitch(&CamSettingSP, "Settings saved."); return; } if (CamSettingS[1].s == ISS_ON) { v4l_pwc->restoreSettings(); IUResetSwitches(&CamSettingSP); CamSettingSP.s = IPS_OK; IDSetSwitch(&CamSettingSP, "Settings restored."); updateV4L1Controls(); return; } if (CamSettingS[2].s == ISS_ON) { v4l_pwc->restoreFactorySettings(); IUResetSwitches(&CamSettingSP); CamSettingSP.s = IPS_OK; IDSetSwitch(&CamSettingSP, "Factory settings restored."); updateV4L1Controls(); return; } } #endif // Call parent V4L_Driver::ISNewSwitch(dev, name, states, names, n); } void V4L_Philips::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { V4L_Driver::ISNewText(dev, name, texts, names, n); } void V4L_Philips::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { // Nothing for V4L 2 to do here #ifndef HAVE_LINUX_VIDEODEV2_H char errmsg[ERRMSGSIZ]; /* Frame rate */ if (!strcmp (FrameRateNP.name, name)) { if (checkPowerN(&FrameRateNP)) return; FrameRateNP.s = IPS_IDLE; int oldFP = (int) FrameRateN[0].value; if (IUUpdateNumbers(&FrameRateNP, values, names, n) < 0) return; if (v4l_pwc->setFrameRate( (int) FrameRateN[0].value, errmsg) < 0) { FrameRateN[0].value = oldFP; IDSetNumber(&FrameRateNP, "%s", errmsg); return; } FrameRateNP.s = IPS_OK; IDSetNumber(&FrameRateNP, NULL); return; } if (!strcmp (ShutterSpeedNP.name, name)) { if (checkPowerN(&ShutterSpeedNP)) return; ShutterSpeedNP.s = IPS_IDLE; if (v4l_pwc->setExposure( (int) values[0], errmsg) < 0) { IDSetNumber(&ShutterSpeedNP, "%s", errmsg); return; } ShutterSpeedN[0].value = values[0]; ShutterSpeedNP.s = IPS_OK; IDSetNumber(&ShutterSpeedNP, NULL); return; } /* White balance */ if (!strcmp (WhiteBalanceNP.name, name)) { if (checkPowerN(&WhiteBalanceNP)) return; WhiteBalanceNP.s = IPS_IDLE; int oldBalance[2]; oldBalance[0] = (int) WhiteBalanceN[0].value; oldBalance[1] = (int) WhiteBalanceN[1].value; if (IUUpdateNumbers(&WhiteBalanceNP, values, names, n) < 0) return; if (v4l_pwc->setWhiteBalanceRed( (int) WhiteBalanceN[0].value * 256, errmsg)) { WhiteBalanceN[0].value = oldBalance[0]; WhiteBalanceN[1].value = oldBalance[1]; IDSetNumber(&WhiteBalanceNP, "%s", errmsg); return; } if (v4l_pwc->setWhiteBalanceBlue( (int) WhiteBalanceN[1].value * 256, errmsg)) { WhiteBalanceN[0].value = oldBalance[0]; WhiteBalanceN[1].value = oldBalance[1]; IDSetNumber(&WhiteBalanceNP, "%s", errmsg); return; } IUResetSwitches(&WhiteBalanceModeSP); WhiteBalanceModeS[1].s = ISS_ON; WhiteBalanceModeSP.s = IPS_OK; WhiteBalanceNP.s = IPS_OK; IDSetSwitch(&WhiteBalanceModeSP, NULL); IDSetNumber(&WhiteBalanceNP, NULL); return; } #endif // Call parent V4L_Driver::ISNewNumber(dev, name, values, names, n); } void V4L_Philips::connectCamera() { char errmsg[ERRMSGSIZ]; switch (PowerS[0].s) { case ISS_ON: #ifdef HAVE_LINUX_VIDEODEV2_H if (v4l_base->connectCam(PortT[0].text, errmsg, V4L2_PIX_FMT_YUV420) < 0) #else if (v4l_base->connectCam(PortT[0].text, errmsg) < 0) #endif { PowerSP.s = IPS_IDLE; PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch(&PowerSP, "Error: unable to open device"); IDLog("Error: %s\n", errmsg); return; } /* Sucess! */ PowerS[0].s = ISS_ON; PowerS[1].s = ISS_OFF; PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "Philips Webcam is online. Retrieving basic data."); v4l_base->registerCallback(newFrame, this); V4LFrame->compressedFrame = (unsigned char *) malloc (sizeof(unsigned char) * 1); IDLog("Philips Webcam is online. Retrieving basic data.\n"); getBasicData(); break; case ISS_OFF: PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_IDLE; free(V4LFrame->compressedFrame); V4LFrame->compressedFrame = NULL; v4l_base->disconnectCam(); IDSetSwitch(&PowerSP, "Philips Webcam is offline."); break; } } #ifndef HAVE_LINUX_VIDEODEV2_H /* Retrieves basic data from the device upon connection.*/ void V4L_Philips::getBasicData() { char errmsg[ERRMSGSIZ]; bool result; int xmax, ymax, xmin, ymin, index; v4l_pwc->getMaxMinSize(xmax, ymax, xmin, ymin); IDLog("X (%d,%d), Y (%d,%d)\n", xmin, xmax, ymin, ymax); /* Width */ FrameN[2].value = v4l_pwc->getWidth(); FrameN[2].min = xmin; FrameN[2].max = xmax; /* Height */ FrameN[3].value = v4l_pwc->getHeight(); FrameN[3].min = ymin; FrameN[3].max = ymax; IDSetNumber(&FrameNP, NULL); IUUpdateMinMax(&FrameNP); IUSaveText(&camNameT[0], v4l_pwc->getDeviceName()); IDSetText(&camNameTP, NULL); IDLog("Raw values\n Contrast: %d \n Brightness %d \n Color %d \n Sharpness %d \n Gain %d \n Gamma %d \n", v4l_pwc->getContrast(), v4l_pwc->getBrightness(), v4l_pwc->getColor(), v4l_pwc->getSharpness(), v4l_pwc->getGain(), v4l_pwc->getGama()); updateV4L1Controls(); if (v4l_pwc->setFrameRate( (int) FrameRateN[0].value, errmsg) < 0) { FrameRateNP.s = IPS_ALERT; IDSetNumber(&FrameRateNP, "%s", errmsg); } else { FrameRateNP.s = IPS_OK; IDSetNumber(&FrameRateNP, NULL); } result = v4l_pwc->getBackLight(); if (result) { BackLightS[0].s = ISS_ON; BackLightS[1].s = ISS_OFF; } else { BackLightS[0].s = ISS_OFF; BackLightS[1].s = ISS_ON; } IDSetSwitch(&BackLightSP, NULL); result = v4l_pwc->getFlicker(); if (result) { AntiFlickerS[0].s = ISS_ON; AntiFlickerS[1].s = ISS_OFF; } else { AntiFlickerS[0].s = ISS_OFF; AntiFlickerS[1].s = ISS_ON; } IDSetSwitch(&AntiFlickerSP, NULL); index = v4l_pwc->getNoiseRemoval(); IUResetSwitches(&NoiseReductionSP); NoiseReductionS[index].s = ISS_ON; IDSetSwitch(&NoiseReductionSP, NULL); index = v4l_pwc->getWhiteBalance(); IUResetSwitches(&WhiteBalanceModeSP); switch (index) { case PWC_WB_AUTO: WhiteBalanceModeS[0].s = ISS_ON; break; case PWC_WB_MANUAL: WhiteBalanceModeS[1].s = ISS_ON; break; case PWC_WB_INDOOR: WhiteBalanceModeS[2].s = ISS_ON; break; case PWC_WB_OUTDOOR: WhiteBalanceModeS[3].s = ISS_ON; break; case PWC_WB_FL: WhiteBalanceModeS[3].s = ISS_ON; break; } IDSetSwitch(&WhiteBalanceModeSP, NULL); } #endif #ifndef HAVE_LINUX_VIDEODEV2_H void V4L_Philips::updateV4L1Controls() { int index =0; ImageAdjustN[0].value = v4l_pwc->getContrast() / 256.; ImageAdjustN[1].value = v4l_pwc->getBrightness() / 256.; ImageAdjustN[2].value = v4l_pwc->getColor() / 256.; index = v4l_pwc->getSharpness(); if (index < 0) ImageAdjustN[3].value = -1; else ImageAdjustN[3].value = v4l_pwc->getSharpness() / 256.; ImageAdjustN[4].value = v4l_pwc->getGain() / 256.; ImageAdjustN[5].value = v4l_pwc->getGama() / 256.; ImageAdjustNP.s = IPS_OK; IDSetNumber(&ImageAdjustNP, NULL); } #endif indi-0.5/src/sbigcam.h0000644000175000017500000005313010610474336012464 0ustar jrjr//============================================================================= #if 0 File name : sbigcam.h Driver type: SBIG CCD Camera INDI Driver Copyright (C) 2005-2006 Jan Soldan (jsoldan AT asu DOT cas DOT cz) 251 65 Ondrejov-236, Czech Republic Acknowledgement: Jasem Mutlaq (mutlaqja AT ikarustech DOT com) Matt Longmire (matto AT sbig DOT com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #endif //============================================================================= #ifndef _SBIG_CAM_ #define _SBIG_CAM_ #include #include #include #include #include #include "sbigudrv.h" // Define INDI if INDI driver should be generated, otherwise only SbigCam class without // INDI support will be generated. #define INDI #define USE_CCD_FRAME_STANDARD_PROPERTY //#define USE_CCD_BINNING_STANDARD_PROPERTY #define USE_BLOB_COMPRESS #ifdef INDI #include #include #include #include #include #include #include #include #include /* FIXME use CFITSIO #include "fitsrw.h" */ #include "cfitsio/fitsio.h" #include "indidevapi.h" #include "eventloop.h" #include "indicom.h" #include "lilxml.h" #include "base64.h" #endif using std::string; /* How to use SBIG CFW-10 SA under Linux: 1) If you have a RS-232 port on you computer, localize its serial device. It may look like this one: /dev/ttyS0 In the case you use an USB to RS-232 adapter, the device may be located at: /dev/ttyUSB0 2) Make a symbolic link to this device with the following name: ln -s /dev/ttyUSB0 ~/kdeedu/kstars/kstars/indi/sbigcfw Please note that the SBIG CFW-10 SA _always_ uses device named sbigcfw. 3) Change mode of this device: chmod a+rw /dev/ttyUSB0 4) Inside KStars: a) Open CFW panel b) Set CFW Type to CFW-10 SA c) Press Connect button d) The CFW's detection may take a few seconds due to its internal initialization. */ //============================================================================= const int INVALID_HANDLE_VALUE = -1; // for file operations //============================================================================= // SBIG temperature constants: const double T0 = 25.000; const double MAX_AD = 4096.000; const double R_RATIO_CCD = 2.570; const double R_BRIDGE_CCD = 10.000; const double DT_CCD = 25.000; const double R0 = 3.000; const double R_RATIO_AMBIENT = 7.791; const double R_BRIDGE_AMBIENT = 3.000; const double DT_AMBIENT = 45.000; //============================================================================= // SBIG CCD camera port definitions: #define SBIG_USB0 "sbigusb0" #define SBIG_USB1 "sbigusb1" #define SBIG_USB2 "sbigusb2" #define SBIG_USB3 "sbigusb3" #define SBIG_LPT0 "sbiglpt0" #define SBIG_LPT1 "sbiglpt1" #define SBIG_LPT2 "sbiglpt2" //============================================================================= # ifdef INDI // DEVICE: #define DEVICE_NAME "SBIG" // GROUP: #define CAMERA_GROUP "Camera" #define CFW_GROUP "CFW" #define TEMPERATURE_GROUP "Temperature" #define FRAME_GROUP "Frame" #define EXPOSURE_GROUP "Exposure" // PRODUCT: #define PRODUCT_NAME_T "NAME" #define PRODUCT_LABEL_T "Name" #define PRODUCT_ID_NAME_T "ID" #define PRODUCT_ID_LABEL_T "ID" #define CCD_PRODUCT_NAME_TP "CCD_PRODUCT" #define CCD_PRODUCT_LABEL_TP "Product" #define CFW_PRODUCT_NAME_TP "CFW_PRODUCT" #define CFW_PRODUCT_LABEL_TP "Product" // CONNECT & DISCONNECT: #define CONNECT_NAME_S "CONNECT" #define CONNECT_LABEL_S "Connect" #define DISCONNECT_NAME_S "DISCONNECT" #define DISCONNECT_LABEL_S "Disconnect" #define CCD_CONNECTION_NAME_SP "CONNECTION" #define CCD_CONNECTION_LABEL_SP "Connection" #define CFW_CONNECTION_NAME_SP "CFW_CONNECTION" #define CFW_CONNECTION_LABEL_SP "Connection" // DEVICE PORT: #define PORT_NAME_T "PORT" #define PORT_LABEL_T "Port" #define CCD_DEVICE_PORT_NAME_TP "DEVICE_PORT" #define CCD_DEVICE_PORT_LABEL_TP "Device" // CCD FAN: #define CCD_FAN_ON_NAME_S "ON" #define CCD_FAN_ON_LABEL_S "On" #define CCD_FAN_OFF_NAME_S "OFF" #define CCD_FAN_OFF_LABEL_S "Off" #define CCD_FAN_NAME_SP "CCD_FAN" #define CCD_FAN_LABEL_SP "Fan" // CCD REQUESTS: #define CCD_IMAGING_NAME_S "IMAGING" #define CCD_IMAGING_LABEL_S "Imaging" #define CCD_TRACKING_NAME_S "TRACKING" #define CCD_TRACKING_LABEL_S "Tracking" #define CCD_EXT_TRACKING_NAME_S "EXT_TRACKING" #define CCD_EXT_TRACKING_LABEL_S "Ext.Tracking" #define CCD_REQUEST_NAME_SP "CCD_REQUEST" #define CCD_REQUEST_LABEL_SP "CCD" // CCD COOLER: #define CCD_COOLER_NAME_N "COOLER" #define CCD_COOLER_LABEL_N "[%]" #define CCD_COOLER_NAME_NP "CCD_COOLER" #define CCD_COOLER_LABEL_NP "Cooler" const double CCD_COOLER_THRESHOLD = 95.0; // CCD TEMPERATURE: #define CCD_TEMPERATURE_NAME_N "TEMPERATURE" #define CCD_TEMPERATURE_LABEL_N "[C]" #define CCD_TEMPERATURE_NAME_NP "CCD_TEMPERATURE" #define CCD_TEMPERATURE_LABEL_NP "Temperature" const double MIN_CCD_TEMP = -70.0; const double MAX_CCD_TEMP = 40.0; const double CCD_TEMP_STEP = 0.1; const double DEF_CCD_TEMP = 0.0; const double TEMP_DIFF = 0.5; // CCD TEMPERATURE POOLING: #define CCD_TEMPERATURE_POLLING_NAME_N "TEMPERATURE_POLLING" #define CCD_TEMPERATURE_POLLING_LABEL_N "[sec]" #define CCD_TEMPERATURE_POLLING_NAME_NP "CCD_TEMPERATURE_POLLING" #define CCD_TEMPERATURE_POLLING_LABEL_NP "Polling Time" const double MIN_POLLING_TIME = 1.0; const double MAX_POLLING_TIME = 3600.0; const double STEP_POLLING_TIME = 1.0; const double CUR_POLLING_TIME = 10.0; // CCD TEMPERATURE MSG: #define CCD_TEMPERATURE_MSG_YES_NAME_S "TEMPERATURE_MSG_YES" #define CCD_TEMPERATURE_MSG_YES_LABEL_S "Yes" #define CCD_TEMPERATURE_MSG_NO_NAME_S "TEMPERATURE_MSG_NO" #define CCD_TEMPERATURE_MSG_NO_LABEL_S "No" #define CCD_TEMPERATURE_MSG_NAME_SP "CCD_TEMPERATURE_MSG" #define CCD_TEMPERATURE_MSG_LABEL_SP "Send MSG" // CCD FRAME TYPES: #define CCD_FRAME_LIGHT_NAME_N "FRAME_LIGHT" #define CCD_FRAME_DARK_NAME_N "FRAME_DARK" #define CCD_FRAME_FLAT_NAME_N "FRAME_FLAT" #define CCD_FRAME_BIAS_NAME_N "FRAME_BIAS" #define CCD_FRAME_LIGHT_LABEL_N "Light" #define CCD_FRAME_DARK_LABEL_N "Dark" #define CCD_FRAME_FLAT_LABEL_N "Flat" #define CCD_FRAME_BIAS_LABEL_N "Bias" #define CCD_FRAME_TYPE_NAME_NP "CCD_FRAME_TYPE" #define CCD_FRAME_TYPE_LABEL_NP "Type" // CCD BINNING: const int CCD_BIN_1x1_I = 0; const int CCD_BIN_2x2_I = 1; const int CCD_BIN_3x3_I = 2; const int CCD_BIN_9x9_I = 9; const int CCD_BIN_2x2_E = 7; const int CCD_BIN_3x3_E = 8; #ifdef USE_CCD_BINNING_STANDARD_PROPERTY #define CCD_HOR_BIN_NAME_N "HOR_BIN" #define CCD_HOR_BIN_LABEL_N "Horizontal" #define CCD_VER_BIN_NAME_N "VER_BIN" #define CCD_VER_BIN_LABEL_N "Vertical" #define CCD_BINNING_NAME_NP "CCD_BINNING" #define CCD_BINNING_LABEL_NP "Binning" #define CCD_MIN_BIN 1 #define CCD_MAX_BIN 3 #else #define CCD_BIN_1x1_I_NAME_S "CCD_BIN_1x1_I" #define CCD_BIN_1x1_I_LABEL_S "1x1 On Chip" #define CCD_BIN_2x2_I_NAME_S "CCD_BIN_2x2_I" #define CCD_BIN_2x2_I_LABEL_S "2x2 On Chip" #define CCD_BIN_3x3_I_NAME_S "CCD_BIN_3x3_I" #define CCD_BIN_3x3_I_LABEL_S "3x3 On Chip" #define CCD_BIN_9x9_I_NAME_S "CCD_BIN_9x9_I" #define CCD_BIN_9x9_I_LABEL_S "9x9 On Chip" #define CCD_BIN_2x2_E_NAME_S "CCD_BIN_2x2_E" #define CCD_BIN_2x2_E_LABEL_S "2x2 Off Chip" #define CCD_BIN_3x3_E_NAME_S "CCD_BIN_3x3_E" #define CCD_BIN_3x3_E_LABEL_S "3x3 Off Chip" #define CCD_BINNING_MODE_NAME_SP "CCD_BINNING_MODE" #define CCD_BINNING_MODE_LABEL_SP "Binning" #endif // CCD PIXEL INFO: #define CCD_PIXEL_WIDTH_NAME_N "PIXEL_WIDTH" #define CCD_PIXEL_WIDTH_LABEL_N "Width" #define CCD_PIXEL_HEIGHT_NAME_N "PIXEL_HEIGHT" #define CCD_PIXEL_HEIGHT_LABEL_N "Height" #define CCD_PIXEL_INFO_NAME_NP "CCD_PIXEL_INFO" #define CCD_PIXEL_INFO_LABEL_NP "Pixel Size [um]" // CCD FRAME #ifdef USE_CCD_FRAME_STANDARD_PROPERTY #define CCD_FRAME_X_NAME_N "X" #define CCD_FRAME_X_LABEL_N "Left" #define CCD_FRAME_Y_NAME_N "Y" #define CCD_FRAME_Y_LABEL_N "Top" #define CCD_FRAME_W_NAME_N "WIDTH" #define CCD_FRAME_W_LABEL_N "Width" #define CCD_FRAME_H_NAME_N "HEIGHT" #define CCD_FRAME_H_LABEL_N "Height" #define CCD_FRAME_NAME_NP "CCD_FRAME" #define CCD_FRAME_LABEL_NP "Position" #else // CCD FRAME X: #define CCD_FRAME_X_NAME_N "FRAME_X" #define CCD_FRAME_X_LABEL_N "left" #define CCD_FRAME_X_NAME_NP "CCD_FRAME_X" #define CCD_FRAME_X_LABEL_NP "Position" // CCD FRAME Y: #define CCD_FRAME_Y_NAME_N "FRAME_Y" #define CCD_FRAME_Y_LABEL_N "Top" #define CCD_FRAME_Y_NAME_NP "CCD_FRAME_Y" #define CCD_FRAME_Y_LABEL_NP "Position" // CCD FRAME W: #define CCD_FRAME_W_NAME_N "FRAME_W" #define CCD_FRAME_W_LABEL_N "Width" #define CCD_FRAME_W_NAME_NP "CCD_FRAME_W" #define CCD_FRAME_W_LABEL_NP "Size" // CCD FRAME H: #define CCD_FRAME_H_NAME_N "FRAME_H" #define CCD_FRAME_H_LABEL_N "Height" #define CCD_FRAME_H_NAME_NP "CCD_FRAME_H" #define CCD_FRAME_H_LABEL_NP "Size" #endif // CCD EXPOSE DURATION [s]: #define CCD_EXPOSE_DURATION_NAME_N "EXPOSE_DURATION" #define CCD_EXPOSE_DURATION_LABEL_N "[sec]" #define CCD_EXPOSE_DURATION_NAME_NP "CCD_EXPOSE_DURATION" #define CCD_EXPOSE_DURATION_LABEL_NP "Time" const double MIN_EXP_TIME = 0.0; const double MAX_EXP_TIME = 3600.0; const double EXP_TIME_STEP = 0.01; const double DEF_EXP_TIME = 1.0; // BLOB: #define BLOB_NAME_B "FITS_BLOB" #define BLOB_LABEL_B "FITS" #define BLOB_NAME_BP "CCD_FITS_BLOB" #define BLOB_LABEL_BP "BLOB" #ifdef USE_BLOB_COMPRESS #define BLOB_FORMAT_B ".fits.z" #else #define BLOB_FORMAT_B ".fits" #endif // FITS file name: #define FITS_NAME_T "NAME" #define FITS_LABEL_T "Name" #define FITS_NAME_TP "FITS_NAME" #define FITS_LABEL_TP "FITS" // CFW TYPES: #define CFW1_NAME_S "CFW1" #define CFW1_LABEL_S "CFW-2" #define CFW2_NAME_S "CFW2" #define CFW2_LABEL_S "CFW-5" #define CFW3_NAME_S "CFW3" #define CFW3_LABEL_S "CFW-6A" #define CFW4_NAME_S "CFW4" #define CFW4_LABEL_S "CFW-8" #define CFW5_NAME_S "CFW5" #define CFW5_LABEL_S "CFW-402" #define CFW6_NAME_S "CFW6" #define CFW6_LABEL_S "CFW-10" #define CFW7_NAME_S "CFW7" #define CFW7_LABEL_S "CFW-10 SA" #define CFW8_NAME_S "CFW8" #define CFW8_LABEL_S "CFW-L" #ifdef USE_CFW_AUTO #define CFW9_NAME_S "CFW9" #define CFW9_LABEL_S "CFW-Auto" const int MAX_CFW_TYPES = 9; #else const int MAX_CFW_TYPES = 8; #endif #define CFW_TYPE_NAME_SP "CFW_TYPE" #define CFW_TYPE_LABEL_SP "Type" // CFW SLOTS: #define CFW_SLOT_NAME_N "SLOT" #define CFW_SLOT_LABEL_N "Slot" #define CFW_SLOT_NAME_NP "FILTER_SLOT" #define CFW_SLOT_LABEL_NP "Goto" const int MIN_FILTER_SLOT = 1; const int MAX_FILTER_SLOT = 10; const int FILTER_SLOT_STEP = 1; const int DEF_FILTER_SLOT = 1; // Auxiliary: #define UNKNOWN_LABEL "Unknown" // INDI timeout: const double INDI_TIMEOUT = 5.0; const int POLL_TEMPERATURE_MS = 10000; // Temperature polling time (ms) const int POLL_EXPOSURE_MS = 1000; // Exposure polling time (ms) // Define byte order: #define GET_BIG_ENDIAN(p) ( ((p & 0xff) << 8) | (p >> 8)) //(((p << 8) & 0xff00) | ((p >> 8) & 0xff)) #endif // INDI //============================================================================= typedef enum { CCD_THERMISTOR, AMBIENT_THERMISTOR }THERMISTOR_TYPE; //============================================================================= class SbigCam { protected: int m_fd; CAMERA_TYPE m_camera_type; int m_drv_handle; bool m_link_status; char m_dev_name[PATH_MAX]; string m_start_exposure_timestamp; #ifdef INDI // CAMERA GROUP: IText m_icam_product_t[2]; ITextVectorProperty m_icam_product_tp; IText m_icam_device_port_t[1]; ITextVectorProperty m_icam_device_port_tp; ISwitch m_icam_connection_s[2]; ISwitchVectorProperty m_icam_connection_sp; // TEMPERATURE GROUP: ISwitch m_icam_fan_state_s[2]; ISwitchVectorProperty m_icam_fan_state_sp; INumber m_icam_temperature_n[1]; INumberVectorProperty m_icam_temperature_np; double m_icam_temperature; INumber m_icam_cooler_n[1]; INumberVectorProperty m_icam_cooler_np; INumber m_icam_temperature_polling_n[1]; INumberVectorProperty m_icam_temperature_polling_np; ISwitch m_icam_temperature_msg_s[2]; ISwitchVectorProperty m_icam_temperature_msg_sp; // FRAME GROUP: ISwitch m_icam_frame_type_s[4]; ISwitchVectorProperty m_icam_frame_type_sp; ISwitch m_icam_ccd_request_s[3]; ISwitchVectorProperty m_icam_ccd_request_sp; #ifdef USE_CCD_BINNING_STANDARD_PROPERTY INumber m_icam_ccd_binning_n[2]; INumberVectorProperty m_icam_ccd_binning_np; #else ISwitch m_icam_binning_mode_s[6]; ISwitchVectorProperty m_icam_binning_mode_sp; #endif INumber m_icam_ccd_info_n[1]; INumberVectorProperty m_icam_ccd_info_np; INumber m_icam_pixel_size_n[2]; INumberVectorProperty m_icam_pixel_size_np; #ifdef USE_CCD_FRAME_STANDARD_PROPERTY INumber m_icam_ccd_frame_n[4]; INumberVectorProperty m_icam_ccd_frame_np; #else INumber m_icam_frame_x_n[1]; INumberVectorProperty m_icam_frame_x_np; INumber m_icam_frame_y_n[1]; INumberVectorProperty m_icam_frame_y_np; INumber m_icam_frame_w_n[1]; INumberVectorProperty m_icam_frame_w_np; INumber m_icam_frame_h_n[1]; INumberVectorProperty m_icam_frame_h_np; #endif // CFW GROUP: IText m_icfw_product_t[2]; ITextVectorProperty m_icfw_product_tp; ISwitch m_icfw_type_s[MAX_CFW_TYPES]; ISwitchVectorProperty m_icfw_type_sp; ISwitch m_icfw_connection_s[2]; ISwitchVectorProperty m_icfw_connection_sp; INumber m_icfw_slot_n[1]; INumberVectorProperty m_icfw_slot_np; // EXPOSURE GROUP: INumber m_icam_expose_time_n[1]; INumberVectorProperty m_icam_expose_time_np; double m_icam_expose_time; // INDI BLOBs: IBLOB m_icam_fits_b; IBLOBVectorProperty m_icam_fits_bp; // FITS file name: IText m_icam_fits_name_t[1]; ITextVectorProperty m_icam_fits_name_tp; #endif // INDI public: SbigCam(); SbigCam(const char* device_name); virtual ~SbigCam(); inline int GetFileDescriptor(){return(m_fd);} inline void SetFileDescriptor(int val = -1){m_fd = val;} inline bool IsDeviceOpen(){return((m_fd == -1) ? false : true);} inline CAMERA_TYPE GetCameraType(){return(m_camera_type);} inline void SetCameraType(CAMERA_TYPE val = NO_CAMERA){m_camera_type = val;} inline int GetDriverHandle(){return(m_drv_handle);} inline void SetDriverHandle(int val = INVALID_HANDLE_VALUE){m_drv_handle = val;} inline bool GetLinkStatus(){return(m_link_status);} inline void SetLinkStatus(bool val = false){m_link_status = val;} inline char *GetDeviceName(){return(m_dev_name);} int SetDeviceName(const char*); inline string GetStartExposureTimestamp(){return(m_start_exposure_timestamp);} inline void SetStartExposureTimestamp(const char *p) { m_start_exposure_timestamp = p; } // Driver Related Commands: int GetCfwSelType(); int OpenDevice(const char *name); int CloseDevice(); int GetDriverInfo(GetDriverInfoParams *, void *); int SetDriverHandle(SetDriverHandleParams *); int GetDriverHandle(GetDriverHandleResults *); // Exposure Related Commands: int StartExposure(StartExposureParams *); int EndExposure(EndExposureParams *); int StartReadout(StartReadoutParams *); int ReadoutLine(ReadoutLineParams *, unsigned short *results, bool subtract); int DumpLines(DumpLinesParams *); int EndReadout(EndReadoutParams *); // Temperature Related Commands: int SetTemperatureRegulation(SetTemperatureRegulationParams *); int SetTemperatureRegulation(double temp, bool enable = true); int QueryTemperatureStatus(QueryTemperatureStatusResults *); int QueryTemperatureStatus(bool &enabled, double &ccdTemp, double &setpointT, double &power); // External Control Commands: int ActivateRelay(ActivateRelayParams *); int PulseOut(PulseOutParams *); int TxSerialBytes(TXSerialBytesParams *, TXSerialBytesResults *); int GetSerialStatus(GetSerialStatusResults *); int AoTipTilt(AOTipTiltParams *); int AoSetFocus(AOSetFocusParams *); int AoDelay(AODelayParams *); int Cfw(CFWParams *, CFWResults *); // General Purpose Commands: int EstablishLink(); int GetCcdInfo(GetCCDInfoParams *, void *); int QueryCommandStatus( QueryCommandStatusParams *, QueryCommandStatusResults *); int MiscellaneousControl(MiscellaneousControlParams *); int ReadOffset(ReadOffsetParams *, ReadOffsetResults *); int GetLinkStatus(GetLinkStatusResults *); string GetErrorString(int err); int SetDriverControl(SetDriverControlParams *); int GetDriverControl(GetDriverControlParams *, GetDriverControlResults *); int UsbAdControl(USBADControlParams *); int QueryUsb(QueryUSBResults *); int RwUsbI2c(RWUSBI2CParams *); int BitIo(BitIOParams *, BitIOResults *); // SBIG's software interface to the Universal Driver Library function: int SBIGUnivDrvCommand(PAR_COMMAND, void *, void *); // High level functions: bool CheckLink(); string GetCameraName(); string GetCameraID(); int GetCcdSizeInfo( int ccd, int rm, int &frmW, int &frmH, double &pixW, double &pixH); int GetNumOfCcdChips(); bool IsFanControlAvailable(); #ifdef INDI void ISGetProperties(); void ISNewSwitch( const char *name, ISState *states, char *names[], int num); void ISNewText( const char *name, char *texts[], char *names[], int num); void ISNewNumber(const char *name, double values[], char *names[], int num); int UpdateCcdFrameProperties(bool bUpdateClient = false); int GetCcdTemperaturePoolingTime(); int UpdateProperties(); int UpdateCfwProperties(); int StartExposure(); int StopExposure(); bool CheckConnection(ISwitchVectorProperty *sp); bool CheckConnection(INumberVectorProperty *np); bool CheckConnection(ITextVectorProperty *tp); int GetSelectedCcdChip(int &ccd_request); int GetSelectedCcdBinningMode(int &binning); int GetSelectedCcdFrameType(string &frame_type); int GetCcdShutterMode(int &shutter, int ccd_request); int CfwConnect(); int CfwDisconnect(); int CfwOpenDevice(CFWResults *); int CfwCloseDevice(CFWResults *); int CfwInit(CFWResults *); int CfwGetInfo(CFWResults *); int CfwQuery(CFWResults*); int CfwGoto(CFWResults *); int CfwGotoMonitor(CFWResults *); void CfwShowResults(string name, CFWResults); void CfwUpdateProperties(CFWResults); void SetBlobState(IPState state); unsigned short *AllocateBuffer(unsigned short width, unsigned short height); int ReleaseBuffer(unsigned short height, unsigned short *buffer); int ReadoutCcd( unsigned short left, unsigned short top, unsigned short width, unsigned short height, unsigned short *buffer); string CreateFitsName(); int WriteFits( string fits_name, unsigned short width, unsigned short height, unsigned short *buffer); /* FIXME use CFITSIO FITS_HDU_LIST *CreateFitsHeader( FITS_FILE *fp, unsigned int width, unsigned int height);*/ void CreateFitsHeader(fitsfile *fptr, unsigned int width, unsigned int height); int UploadFits(string file_name); void UpdateTemperature(); void UpdateExposure(); static void UpdateTemperature(void *); static void UpdateExposure(void *); inline void SaveExposeTime(double val){m_icam_expose_time = val;} inline double GetExposeTime(){return(m_icam_expose_time);} inline double GetLastExposeTime(){return(m_icam_expose_time);} inline void SaveTemperature(double val){m_icam_temperature = val;} inline double GetLastTemperature(){return(m_icam_temperature);} #endif protected: void InitVars(); int OpenDriver(); int CloseDriver(); unsigned short CalcSetpoint(double temperature); double CalcTemperature(short thermistorType, short ccdSetpoint); double BcdPixel2double(ulong bcd); }; //============================================================================= #endif //_SBIG_CAM_ indi-0.5/src/sbigudrv.h0000644000175000017500000005215510610474336012712 0ustar jrjr/* SBIGUDRV.H Contains the function prototypes and enumerated constants for the Universal Parallel/USB/Ethernet driver. This supports the following devices: ST-7E/8E/9E/10E ST-5C/237/237A (PixCel255/237) ST-1K, ST-2K ST-L Large Format Camera ST-402 Camera AO-7, AOL Version 4.47 - December 13,2005 (c)1995-2005 - Santa Barbara Instrument Group THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _PARDRV_ #define _PARDRV_ /* needed for KDE_EXPORT macros */ /* DO NOT EDIT OR REMOVE THIS */ #ifndef HAVE_CONFIG_H #include #else #define KDE_EXPORT #endif /* SBIG Specific Code */ #ifndef TARGET #define ENV_WIN 1 /* Target for Windows environment */ #define ENV_WINVXD 2 /* SBIG Use Only, Win 9X VXD */ #define ENV_WINSYS 3 /* SBIG Use Only, Win NT SYS */ #define ENV_ESRVJK 4 /* SBIG Use Only, Ethernet Remote */ #define ENV_ESRVWIN 5 /* SBIG Use Only, Ethernet Remote */ #define ENV_MACOSX 6 /* SBIG Use Only, Mac OSX */ #define ENV_LINUX 7 /* SBIG Use Only, Linux */ #define TARGET ENV_LINUX /* Set for your target */ #endif /* Enumerated Constants Note that the various constants are declared here as enums for ease of declaration but in the structures that use the enums unsigned shorts are used to force the various 16 and 32 bit compilers to use 16 bits. */ /* Supported Camera Commands These are the commands supported by the driver. They are prefixed by CC_ to designate them as camera commands and avoid conflicts with other enums. Some of the commands are marked as SBIG use only and have been included to enhance testability of the driver for SBIG. */ typedef enum { /* General Use Commands */ CC_NULL, /* 1 - 10 */ CC_START_EXPOSURE=1, CC_END_EXPOSURE, CC_READOUT_LINE, CC_DUMP_LINES, CC_SET_TEMPERATURE_REGULATION, CC_QUERY_TEMPERATURE_STATUS, CC_ACTIVATE_RELAY, CC_PULSE_OUT, CC_ESTABLISH_LINK, CC_GET_DRIVER_INFO, /* 11 - 20 */ CC_GET_CCD_INFO, CC_QUERY_COMMAND_STATUS, CC_MISCELLANEOUS_CONTROL, CC_READ_SUBTRACT_LINE, CC_UPDATE_CLOCK, CC_READ_OFFSET, CC_OPEN_DRIVER, CC_CLOSE_DRIVER, CC_TX_SERIAL_BYTES, CC_GET_SERIAL_STATUS, /* 21 - 30 */ CC_AO_TIP_TILT, CC_AO_SET_FOCUS, CC_AO_DELAY, CC_GET_TURBO_STATUS, CC_END_READOUT, CC_GET_US_TIMER, CC_OPEN_DEVICE, CC_CLOSE_DEVICE, CC_SET_IRQL, CC_GET_IRQL, /* 31 - 40 */ CC_GET_LINE, CC_GET_LINK_STATUS, CC_GET_DRIVER_HANDLE, CC_SET_DRIVER_HANDLE, CC_START_READOUT, CC_GET_ERROR_STRING, CC_SET_DRIVER_CONTROL, CC_GET_DRIVER_CONTROL, CC_USB_AD_CONTROL, CC_QUERY_USB, /* 41 - 50 */ CC_GET_PENTIUM_CYCLE_COUNT, CC_RW_USB_I2C, CC_CFW, CC_BIT_IO, CC_USER_EEPROM, CC_AO_CENTER, /* SBIG Use Only Commands */ CC_SEND_BLOCK=90, CC_SEND_BYTE, CC_GET_BYTE, CC_SEND_AD, CC_GET_AD, CC_CLOCK_AD, CC_SYSTEM_TEST, CC_GET_DRIVER_OPTIONS, CC_SET_DRIVER_OPTIONS, CC_LAST_COMMAND} PAR_COMMAND; /* Return Error Codes These are the error codes returned by the driver function. They are prefixed with CE_ to designate them as camera errors. */ #ifndef CE_ERROR_BASE #define CE_ERROR_BASE 1 #endif typedef enum { /* 0 - 10 */ CE_NO_ERROR, CE_CAMERA_NOT_FOUND=CE_ERROR_BASE, CE_EXPOSURE_IN_PROGRESS, CE_NO_EXPOSURE_IN_PROGRESS, CE_UNKNOWN_COMMAND, CE_BAD_CAMERA_COMMAND, CE_BAD_PARAMETER, CE_TX_TIMEOUT, CE_RX_TIMEOUT, CE_NAK_RECEIVED, CE_CAN_RECEIVED, /* 11 - 20 */ CE_UNKNOWN_RESPONSE, CE_BAD_LENGTH, CE_AD_TIMEOUT, CE_KBD_ESC, CE_CHECKSUM_ERROR, CE_EEPROM_ERROR, CE_SHUTTER_ERROR, CE_UNKNOWN_CAMERA, CE_DRIVER_NOT_FOUND, CE_DRIVER_NOT_OPEN, /* 21 - 30 */ CE_DRIVER_NOT_CLOSED, CE_SHARE_ERROR, CE_TCE_NOT_FOUND, CE_AO_ERROR, CE_ECP_ERROR, CE_MEMORY_ERROR, CE_DEVICE_NOT_FOUND, CE_DEVICE_NOT_OPEN, CE_DEVICE_NOT_CLOSED, CE_DEVICE_NOT_IMPLEMENTED, /* 31 - 40 */ CE_DEVICE_DISABLED, CE_OS_ERROR, CE_SOCK_ERROR, CE_SERVER_NOT_FOUND, CE_CFW_ERROR, CE_NEXT_ERROR, CE_FAKE_DRIVER } PAR_ERROR; /* Camera Command State Codes These are the return status codes for the Query Command Status command. Theyt are prefixed with CS_ to designate them as camera status. */ typedef enum { CS_IDLE, CS_IN_PROGRESS, CS_INTEGRATING, CS_INTEGRATION_COMPLETE } PAR_COMMAND_STATUS; #define CS_PULSE_IN_ACTIVE 0x8000 #define CS_WAITING_FOR_TRIGGER 0x8000 /* Misc. Enumerated Constants ABG_STATE7 - Passed to Start Exposure Command MY_LOGICAL - General purpose type DRIVER_REQUEST - Used with Get Driver Info command CCD_REQUEST - Used with Imaging commands to specify CCD CCD_INFO_REQUEST - Used with Get CCD Info Command PORT - Used with Establish Link Command CAMERA_TYPE - Returned by Establish Link and Get CCD Info commands SHUTTER_COMMAND, SHUTTER_STATE7 - Used with Start Exposure and Miscellaneous Control Commands TEMPERATURE_REGULATION - Used with Enable Temperature Regulation LED_STATE - Used with the Miscellaneous Control Command FILTER_COMMAND, FILTER_STATE - Used with the Miscellaneous Control Command AD_SIZE, FILTER_TYPE - Used with the GetCCDInfo3 Command AO_FOCUS_COMMAND - Used with the AO Set Focus Command SBIG_DEVICE_TYPE - Used with Open Device Command DRIVER_CONTROL_PARAMS - Used with Get/SetDriverControl Command USB_AD_CONTROL_COMMAND - Used with UsbADControl Command CFW_MODEL_SELECT, CFW_STATUS, CFW_ERROR - Used with CFW command CFW_POSITION, CFW_GET_INFO_SELECT - Used with CFW Command BIT_IO_OPERATION, BIT_IO_NMAE - Used with BitIO command */ typedef enum { ABG_LOW7, ABG_CLK_LOW7, ABG_CLK_MED7, ABG_CLK_HI7 } ABG_STATE7; typedef unsigned short MY_LOGICAL; typedef enum { DRIVER_STD, DRIVER_EXTENDED, DRIVER_USB_LOADER } DRIVER_REQUEST; typedef enum { CCD_IMAGING, CCD_TRACKING, CCD_EXT_TRACKING } CCD_REQUEST; typedef enum { CCD_INFO_IMAGING, CCD_INFO_TRACKING, CCD_INFO_EXTENDED, CCD_INFO_EXTENDED_5C, CCD_INFO_EXTENDED2_IMAGING, CCD_INFO_EXTENDED2_TRACKING } CCD_INFO_REQUEST; typedef enum { ABG_NOT_PRESENT, ABG_PRESENT } IMAGING_ABG; typedef enum { BR_AUTO, BR_9600, BR_19K, BR_38K, BR_57K, BR_115K } PORT_RATE; typedef enum { ST7_CAMERA=4, ST8_CAMERA, ST5C_CAMERA, TCE_CONTROLLER, ST237_CAMERA, STK_CAMERA, ST9_CAMERA, STV_CAMERA, ST10_CAMERA, ST1K_CAMERA, ST2K_CAMERA, STL_CAMERA, ST402_CAMERA, NEXT_CAMERA, NO_CAMERA=0xFFFF } CAMERA_TYPE; typedef enum { SC_LEAVE_SHUTTER, SC_OPEN_SHUTTER, SC_CLOSE_SHUTTER, SC_INITIALIZE_SHUTTER, SC_OPEN_EXT_SHUTTER, SC_CLOSE_EXT_SHUTTER} SHUTTER_COMMAND; typedef enum { SS_OPEN, SS_CLOSED, SS_OPENING, SS_CLOSING } SHUTTER_STATE7; typedef enum { REGULATION_OFF, REGULATION_ON, REGULATION_OVERRIDE, REGULATION_FREEZE, REGULATION_UNFREEZE, REGULATION_ENABLE_AUTOFREEZE, REGULATION_DISABLE_AUTOFREEZE } TEMPERATURE_REGULATION; #define REGULATION_FROZEN_MASK 0x8000 typedef enum { LED_OFF, LED_ON, LED_BLINK_LOW, LED_BLINK_HIGH } LED_STATE; typedef enum { FILTER_LEAVE, FILTER_SET_1, FILTER_SET_2, FILTER_SET_3, FILTER_SET_4, FILTER_SET_5, FILTER_STOP, FILTER_INIT } FILTER_COMMAND; typedef enum { FS_MOVING, FS_AT_1, FS_AT_2, FS_AT_3, FS_AT_4, FS_AT_5, FS_UNKNOWN } FILTER_STATE; typedef enum { AD_UNKNOWN, AD_12_BITS, AD_16_BITS } AD_SIZE; typedef enum { FW_UNKNOWN, FW_EXTERNAL, FW_VANE, FW_FILTER_WHEEL } FILTER_TYPE; typedef enum { AOF_HARD_CENTER, AOF_SOFT_CENTER, AOF_STEP_IN, AOF_STEP_OUT } AO_FOCUS_COMMAND; typedef enum { DEV_NONE, DEV_LPT1, DEV_LPT2, DEV_LPT3, DEV_USB=0x7F00, DEV_ETH, DEV_USB1, DEV_USB2, DEV_USB3, DEV_USB4 } SBIG_DEVICE_TYPE; typedef enum { DCP_USB_FIFO_ENABLE, DCP_CALL_JOURNAL_ENABLE, DCP_IVTOH_RATIO, DCP_USB_FIFO_SIZE, DCP_USB_DRIVER, DCP_KAI_RELGAIN, DCP_USB_PIXEL_DL_ENABLE, DCP_HIGH_THROUGHPUT, DCP_VDD_OPTIMIZED, DCP_AUTO_AD_GAIN, DCP_NO_HCLKS_FOR_INTEGRATION, DCP_TDI_MODE_ENABLE, DCP_LAST } DRIVER_CONTROL_PARAM; typedef enum { USB_AD_IMAGING_GAIN, USB_AD_IMAGING_OFFSET, USB_AD_TRACKING_GAIN, USB_AD_TRACKING_OFFSET } USB_AD_CONTROL_COMMAND; typedef enum { USBD_SBIGE, USBD_SBIGI, USBD_SBIGM, USBD_NEXT } ENUM_USB_DRIVER; typedef enum { CFWSEL_UNKNOWN, CFWSEL_CFW2, CFWSEL_CFW5, CFWSEL_CFW8, CFWSEL_CFWL, CFWSEL_CFW402, CFWSEL_AUTO, CFWSEL_CFW6A, CFWSEL_CFW10, CFWSEL_CFW10_SERIAL } CFW_MODEL_SELECT; typedef enum { CFWC_QUERY, CFWC_GOTO, CFWC_INIT, CFWC_GET_INFO, CFWC_OPEN_DEVICE, CFWC_CLOSE_DEVICE } CFW_COMMAND; typedef enum { CFWS_UNKNOWN, CFWS_IDLE, CFWS_BUSY } CFW_STATUS; typedef enum { CFWE_NONE, CFWE_BUSY, CFWE_BAD_COMMAND, CFWE_CAL_ERROR, CFWE_MOTOR_TIMEOUT, CFWE_BAD_MODEL, CFWE_DEVICE_NOT_CLOSED, CFWE_DEVICE_NOT_OPEN, CFWE_I2C_ERROR } CFW_ERROR; typedef enum { CFWP_UNKNOWN, CFWP_1, CFWP_2, CFWP_3, CFWP_4, CFWP_5, CFWP_6, CFWP_7, CFWP_8, CFWP_9, CFWP_10} CFW_POSITION; typedef enum { CFWPORT_COM1=1, CFWPORT_COM2, CFWPORT_COM3, CFWPORT_COM4 } CFW_COM_PORT; typedef enum { CFWG_FIRMWARE_VERSION, CFWG_CAL_DATA, CFWG_DATA_REGISTERS } CFW_GETINFO_SELECT; typedef enum { BITIO_WRITE, BITIO_READ } BITIO_OPERATION; typedef enum { BITI_PS_LOW, BITO_IO1, BITO_IO2, BITI_IO3, BITO_FPGA_WE } BITIO_NAME; /* General Purpose Flags */ #define END_SKIP_DELAY 0x8000 /* set in ccd parameter of EndExposure command to skip synchronization delay - Use this to increase the rep rate when taking darks to later be subtracted from SC_LEAVE_SHUTTER exposures such as when tracking and imaging */ #define START_SKIP_VDD 0x8000 /* set in ccd parameter of StartExposure command to skip lowering Imaging CCD Vdd during integration. - Use this to increase the rep rate when you don't care about glow in the upper-left corner of the imaging CCD */ #define START_MOTOR_ALWAYS_ON 0x4000 /* set in ccd parameter of StartExposure and EndExposure commands to force shutter motor to stay on all the time which reduces delays in Start and End Exposure timing and yields higher image throughput. Don't do this too often or camera head will heat up */ #define EXP_WAIT_FOR_TRIGGER_IN 0x80000000 /* set in exposureTime to wait for trigger in pulse */ #define EXP_SEND_TRIGGER_OUT 0x40000000 /* set in exposureTime to send trigger out Y- */ #define EXP_LIGHT_CLEAR 0x20000000 /* set to do light clear of the CCD */ #define EXP_MS_EXPOSURE 0x10000000 /* set to interpret exposure time as milliseconds */ #define EXP_TIME_MASK 0x00FFFFFF /* mask with exposure time to remove flags */ /* Capabilities Bits - Bit Field Definitions for the capabilitiesBits in the GetCCDInfoResults4 struct. */ #define CB_CCD_TYPE_MASK 0x0001 /* mask for CCD type */ #define CB_CCD_TYPE_FULL_FRAME 0x0000 /* b0=0 is full frame CCD */ #define CB_CCD_TYPE_FRAME_TRANSFER 0x0001 /* b0=1 is frame transfer CCD */ #define CB_CCD_ESHUTTER_MASK 0x0002 /* mask for electronic shutter type */ #define CB_CCD_ESHUTTER_NO 0x0000 /* b1=0 indicates no electronic shutter */ #define CB_CCD_ESHUTTER_YES 0x0002 /* b1=1 indicates electronic shutter */ #define CB_CCD_EXT_TRACKER_MASK 0x0004 /* mask for external tracker support */ #define CB_CCD_EXT_TRACKER_NO 0x0000 /* b2=0 indicates no exteranl tracker support */ #define CB_CCD_EXT_TRACKER_YES 0x0004 /* b2=1 indicates external tracker support */ /* Defines */ #define MIN_ST7_EXPOSURE 12 /* Minimum exposure in 1/100ths second */ #define MIN_ST402_EXPOSURE 4 /* Minimum exposure in 1/100ths second */ #define MIN_ST3200_EXPOSURE 9 /* Minimum exposure in 1/100ths second */ /* Command Parameter and Results Structs Make sure you set your compiler for byte structure alignment as that is how the driver was built. */ /* Force 8 Byte Struct Align */ #if TARGET == ENV_MACOSX || TARGET == ENV_LINUX #pragma pack(push,8) #else #pragma pack(push) #pragma pack(8) #endif typedef struct { unsigned short /* CCD_REQUEST */ ccd; unsigned long exposureTime; unsigned short /* ABG_STATE7 */ abgState; unsigned short /* SHUTTER_COMMAND */ openShutter; } StartExposureParams; typedef struct { unsigned short /* CCD_REQUEST */ ccd; } EndExposureParams; typedef struct { unsigned short /* CCD_REQUEST */ ccd; unsigned short readoutMode; unsigned short pixelStart; unsigned short pixelLength; } ReadoutLineParams; typedef struct { unsigned short /* CCD_REQUEST */ ccd; unsigned short readoutMode; unsigned short lineLength; } DumpLinesParams; typedef struct { unsigned short /* CCD_REQUEST */ ccd; } EndReadoutParams; typedef struct { unsigned short /* CCD_REQUEST */ ccd; unsigned short readoutMode; unsigned short top; unsigned short left; unsigned short height; unsigned short width; } StartReadoutParams; typedef struct { unsigned short /* TEMPERATURE_REGULATION */ regulation; unsigned short ccdSetpoint; } SetTemperatureRegulationParams; typedef struct { MY_LOGICAL enabled; unsigned short ccdSetpoint; unsigned short power; unsigned short ccdThermistor; unsigned short ambientThermistor; } QueryTemperatureStatusResults; typedef struct { unsigned short tXPlus; unsigned short tXMinus; unsigned short tYPlus; unsigned short tYMinus; } ActivateRelayParams; typedef struct { unsigned short numberPulses; unsigned short pulseWidth; unsigned short pulsePeriod; } PulseOutParams; typedef struct { unsigned short dataLength; unsigned char data[256]; } TXSerialBytesParams; typedef struct { unsigned short bytesSent; } TXSerialBytesResults; typedef struct { MY_LOGICAL clearToCOM; } GetSerialStatusResults; typedef struct { unsigned short sbigUseOnly; } EstablishLinkParams; typedef struct { unsigned short /* CAMERA_TYPE */ cameraType; } EstablishLinkResults; typedef struct { unsigned short /* DRIVER_REQUEST */ request; } GetDriverInfoParams; typedef struct { unsigned short version; char name[64]; unsigned short maxRequest; } GetDriverInfoResults0; typedef struct { unsigned short /* CCD_INFO_REQUEST */ request; } GetCCDInfoParams; typedef struct { unsigned short mode; unsigned short width; unsigned short height; unsigned short gain; unsigned long pixel_width; unsigned long pixel_height; } READOUT_INFO; typedef struct { unsigned short firmwareVersion; unsigned short /* CAMERA_TYPE */ cameraType; char name[64]; unsigned short readoutModes; struct { unsigned short mode; unsigned short width; unsigned short height; unsigned short gain; unsigned long pixelWidth; unsigned long pixelHeight; } readoutInfo[20]; } GetCCDInfoResults0; typedef struct { unsigned short badColumns; unsigned short columns[4]; unsigned short /* IMAGING_ABG */ imagingABG; char serialNumber[10]; } GetCCDInfoResults2; typedef struct { unsigned short /* AD_SIZE */ adSize; unsigned short /* FILTER_TYPE */ filterType; } GetCCDInfoResults3; typedef struct { unsigned short capabilitiesBits; unsigned short dumpExtra; } GetCCDInfoResults4; typedef struct { unsigned short command; } QueryCommandStatusParams; typedef struct { unsigned short status; } QueryCommandStatusResults; typedef struct { MY_LOGICAL fanEnable; unsigned short /* SHUTTER_COMMAND */ shutterCommand; unsigned short /* LED_STATE */ ledState; } MiscellaneousControlParams; typedef struct { unsigned short /* CCD_REQUEST */ ccd; } ReadOffsetParams; typedef struct { unsigned short offset; } ReadOffsetResults; typedef struct { unsigned short xDeflection; unsigned short yDeflection; } AOTipTiltParams; typedef struct { unsigned short /* AO_FOCUS_COMMAND */ focusCommand; } AOSetFocusParams; typedef struct { unsigned long delay; } AODelayParams; typedef struct { MY_LOGICAL turboDetected; } GetTurboStatusResults; typedef struct { unsigned short deviceType; /* SBIG_DEVICE_TYPE, specifies LPT, Ethernet, etc */ unsigned short lptBaseAddress; /* DEV_LPTN: Windows 9x Only, Win NT uses deviceSelect */ unsigned long ipAddress; /* DEV_ETH: Ethernet address */ } OpenDeviceParams; typedef struct { unsigned short level; } SetIRQLParams; typedef struct { unsigned short level; } GetIRQLResults; typedef struct { MY_LOGICAL linkEstablished; unsigned short baseAddress; unsigned short /* CAMERA_TYPE */ cameraType; unsigned long comTotal; unsigned long comFailed; } GetLinkStatusResults; typedef struct { unsigned long count; } GetUSTimerResults; typedef struct { unsigned short port; unsigned short length; unsigned char *source; } SendBlockParams; typedef struct { unsigned short port; unsigned short data; } SendByteParams; typedef struct { unsigned short /* CCD_REQUEST */ ccd; unsigned short readoutMode; unsigned short pixelStart; unsigned short pixelLength; } ClockADParams; typedef struct { unsigned short testClocks; unsigned short testMotor; unsigned short test5800; unsigned short stlAlign; unsigned short motorAlwaysOn; } SystemTestParams; typedef struct { unsigned short outLength; unsigned char *outPtr; unsigned short inLength; unsigned char *inPtr; } SendSTVBlockParams; typedef struct { unsigned short errorNo; } GetErrorStringParams; typedef struct { char errorString[64]; } GetErrorStringResults; typedef struct { short handle; } SetDriverHandleParams; typedef struct { short handle; } GetDriverHandleResults; typedef struct { unsigned short /* DRIVER_CONTROL_PARAM */ controlParameter; unsigned long controlValue; } SetDriverControlParams; typedef struct { unsigned short /* DRIVER_CONTROL_PARAM */ controlParameter; } GetDriverControlParams; typedef struct { unsigned long controlValue; } GetDriverControlResults; typedef struct { unsigned short /* USB_AD_CONTROL_COMMAND */ command; short data; } USBADControlParams; typedef struct { MY_LOGICAL cameraFound; unsigned short /* CAMERA_TYPE */ cameraType; char name[64]; char serialNumber[10]; } QUERY_USB_INFO; typedef struct { unsigned short camerasFound; QUERY_USB_INFO usbInfo[4]; } QueryUSBResults; typedef struct { unsigned short rightShift; } GetPentiumCycleCountParams; typedef struct { unsigned long countLow; unsigned long countHigh; } GetPentiumCycleCountResults; typedef struct { unsigned char address; unsigned char data; MY_LOGICAL write; unsigned char deviceAddress; } RWUSBI2CParams; typedef struct { unsigned char data; } RWUSBI2CResults; typedef struct { unsigned short /* CFW_MODEL_SELECT */ cfwModel; unsigned short /* CFW_COMMAND */ cfwCommand; unsigned long cfwParam1; unsigned long cfwParam2; unsigned short outLength; unsigned char *outPtr; unsigned short inLength; unsigned char *inPtr; } CFWParams; typedef struct { unsigned short /* CFW_MODEL_SELECT */ cfwModel; unsigned short /* CFW_POSITION */ cfwPosition; unsigned short /* CFW_STATUS */ cfwStatus; unsigned short /* CFW_ERROR */ cfwError; unsigned long cfwResult1; unsigned long cfwResult2; } CFWResults; typedef struct { unsigned short /* BITIO_OPERATION */ bitOperation; unsigned short /* BITIO_NAME */ bitName; MY_LOGICAL setBit; } BitIOParams; typedef struct { MY_LOGICAL bitIsSet; } BitIOResults; typedef struct { MY_LOGICAL writeData; unsigned char data[32]; } UserEEPROMParams, UserEEPROMResults; #pragma pack(pop) /* Restore previous struct align */ /* Function Prototypes This are the driver interface functions. SBIGUnivDrvCommand() - Supports Parallel, USB and Ethernet based cameras. Each function takes a command parameter and pointers to parameters and results structs. The calling program needs to allocate the memory for the parameters and results structs and these routines read them and fill them in respectively. */ #if TARGET == ENV_WIN #ifdef __cplusplus extern "C" KDE_EXPORT short __stdcall SBIGUnivDrvCommand(short command, void *Params, void *Results); #else extern KDE_EXPORT short __stdcall SBIGUnivDrvCommand(short command, void *Params, void *Results); #endif #else #ifdef __cplusplus extern "C" KDE_EXPORT short SBIGUnivDrvCommand(short command, void *Params, void *Results); #else extern KDE_EXPORT short SBIGUnivDrvCommand(short command, void *Params, void *Results); #endif #endif #endif /* ifndef _PARDRV_ */ indi-0.5/src/indiapi.h0000644000175000017500000003045510610474336012501 0ustar jrjr#if 0 INDI Copyright (C) 2003 Elwood C. Downey This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #ifndef INDI_API_H #define INDI_API_H /** \mainpage Instrument Neutral Distributed Interface INDI \section Introduction INDI is a simple XML-like communications protocol described for interactive and automated remote control of diverse instrumentation.\n INDI is small, easy to parse, and stateless. In the INDI paradigm each Device poses all command and status functions in terms of settings and getting Properties. Each Property is a vector of one or more names members. Each property has a current value vector; a target value vector; provides information about how it should be sequenced with respect to other Properties to accomplish one coordinated unit of observation; and provides hints as to how it might be displayed for interactive manipulation in a GUI.\n Clients learn the Properties of a particular Device at runtime using introspection. This decouples Client and Device implementation histories. Devices have a complete authority over whether to accept commands from Clients. INDI accommadates intermediate servers, broadcasting, and connection topologies ranging from one-to-one on a single system to many-to-many between systems of different genre.\n The INDI protocol can be nested within other XML elements such as constraints for automatic scheduling and execution.\n For a complete review on the INDI protocol, please refer to the INDI white paper. \section Audience Intended Audience INDI is intended for developers who seek a scalable API for device control and automation. Hardware drivers written under INDI can be used under any INDI-compatible client. INDI serves as a backend only, you need frontend clients to control devices. Current clients include KStars, Xephem, DCD, and Cartes du Ciel. \section Development Developing under INDI

Please refere to the INDI Developers Manual for a complete guide on INDI's driver developemnt framework.

The INDI Library API is divided into the following main sections:

\section Help You can find information on INDI development in the INDI sourceforge site. Furthermore, you can discuss INDI related issues on the INDI development mailing list. \author Elwood Downey \author Jasem Mutlaq */ /** \file indiapi.h \brief Constants and Data structure definitions for the interface to the reference INDI C API implementation. \author Elwood C. Downey */ /******************************************************************************* * INDI wire protocol version implemented by this API. * N.B. this is indepedent of the API itself. */ #define INDIV 1.6 /******************************************************************************* * Manifest constants */ /** \typedef ISState \brief Switch state. */ typedef enum { ISS_OFF, ISS_ON } ISState; /* switch state */ /** \typedef IPState \brief Property state. */ typedef enum { IPS_IDLE, IPS_OK, IPS_BUSY, IPS_ALERT } IPState; /* property state */ /** \typedef ISRule \brief Switch vector rule hint. */ typedef enum { ISR_1OFMANY, ISR_ATMOST1, ISR_NOFMANY } ISRule; /* switch vector rule hint */ /** \typedef IPerm \brief Permission hint, with respect to client. */ typedef enum { IP_RO, IP_WO, IP_RW } IPerm; /* permission hint, WRT client */ /* The XML strings for these attributes may be any length but implementations * are only obligued to support these lengths for the various string attributes. */ #define MAXINDINAME 32 #define MAXINDILABEL 32 #define MAXINDIDEVICE 32 #define MAXINDIGROUP 32 #define MAXINDIFORMAT 32 #define MAXINDIBLOBFMT 32 #define MAXINDITSTAMP 32 /******************************************************************************* * Typedefs for each INDI Property type. * * INumber.format may be any printf-style appropriate for double * or style "m" to create sexigesimal using the form "%.m" where * is the total field width. * is the width of the fraction. valid values are: * 9 -> :mm:ss.ss * 8 -> :mm:ss.s * 6 -> :mm:ss * 5 -> :mm.m * 3 -> :mm * * examples: * * to produce use * * "-123:45" %7.3m * " 0:01:02" %9.6m */ /** \struct IText \brief One text descriptor. */ typedef struct { /** index name */ char name[MAXINDINAME]; /** short description */ char label[MAXINDILABEL]; /** malloced text string */ char *text; /** pointer to parent */ struct _ITextVectorProperty *tvp; /** handy place to hang helper info */ void *aux0; /** handy place to hang helper info */ void *aux1; } IText; /** \struct _ITextVectorProperty \brief Text vector property descriptor. */ typedef struct _ITextVectorProperty { /** device name */ char device[MAXINDIDEVICE]; /** property name */ char name[MAXINDINAME]; /** short description */ char label[MAXINDILABEL]; /** GUI grouping hint */ char group[MAXINDIGROUP]; /** client accessibility hint */ IPerm p; /** current max time to change, secs */ double timeout; /** current property state */ IPState s; /** texts comprising this vector */ IText *tp; /** dimension of tp[] */ int ntp; /** ISO 8601 timestamp of this event */ char timestamp[MAXINDITSTAMP]; /** handy place to hang helper info */ void *aux; } ITextVectorProperty; /** \struct INumber \brief One number descriptor. */ typedef struct { char name[MAXINDINAME]; /** index name */ char label[MAXINDILABEL]; /** short description */ char format[MAXINDIFORMAT]; /** GUI display format, see above */ double min, max; /** range, ignore if min == max */ double step; /** step size, ignore if step == 0 */ double value; /** current value */ struct _INumberVectorProperty *nvp; /** pointer to parent */ void *aux0, *aux1; /** handy place to hang helper info */ } INumber; /** \struct _INumberVectorProperty \brief Number vector property descriptor. INumber.format may be any printf-style appropriate for double or style "m" to create sexigesimal using the form "%\.\m" where:\n \ is the total field width.\n \ is the width of the fraction. valid values are:\n 9 -> \:mm:ss.ss \n 8 -> \:mm:ss.s \n 6 -> \:mm:ss \n 5 -> \:mm.m \n 3 -> \:mm \n examples:\n To produce "-123:45", use \%7.3m \n To produce " 0:01:02", use \%9.6m */ typedef struct _INumberVectorProperty { /** device name */ char device[MAXINDIDEVICE]; /** property name */ char name[MAXINDINAME]; /** short description */ char label[MAXINDILABEL]; /** GUI grouping hint */ char group[MAXINDIGROUP]; /** client accessibility hint */ IPerm p; /** current max time to change, secs */ double timeout; /** current property state */ IPState s; /** numbers comprising this vector */ INumber *np; /** dimension of np[] */ int nnp; /** ISO 8601 timestamp of this event */ char timestamp[MAXINDITSTAMP]; /** handy place to hang helper info */ void *aux; } INumberVectorProperty; /** \struct ISwitch \brief One switch descriptor. */ typedef struct { char name[MAXINDINAME]; /** index name */ char label[MAXINDILABEL]; /** this switch's label */ ISState s; /** this switch's state */ struct _ISwitchVectorProperty *svp; /** pointer to parent */ void *aux; /** handy place to hang helper info */ } ISwitch; /** \struct _ISwitchVectorProperty \brief Switch vector property descriptor. */ typedef struct _ISwitchVectorProperty { /** device name */ char device[MAXINDIDEVICE]; /** property name */ char name[MAXINDINAME]; /** short description */ char label[MAXINDILABEL]; /** GUI grouping hint */ char group[MAXINDIGROUP]; /** client accessibility hint */ IPerm p; /** switch behavior hint */ ISRule r; /** current max time to change, secs */ double timeout; /** current property state */ IPState s; /** switches comprising this vector */ ISwitch *sp; /** dimension of sp[] */ int nsp; /** ISO 8601 timestamp of this event */ char timestamp[MAXINDITSTAMP]; /** handy place to hang helper info */ void *aux; } ISwitchVectorProperty; /** \struct ILight \brief One light descriptor. */ typedef struct { char name[MAXINDINAME]; /** index name */ char label[MAXINDILABEL]; /** this lights's label */ IPState s; /** this lights's state */ struct _ILightVectorProperty *lvp; /** pointer to parent */ void *aux; /** handy place to hang helper info */ } ILight; /** \struct _ILightVectorProperty \brief Light vector property descriptor. */ typedef struct _ILightVectorProperty { /** device name */ char device[MAXINDIDEVICE]; /** property name */ char name[MAXINDINAME]; /** short description */ char label[MAXINDILABEL]; /** GUI grouping hint */ char group[MAXINDIGROUP]; /** current property state */ IPState s; /** lights comprising this vector */ ILight *lp; /** dimension of lp[] */ int nlp; /** ISO 8601 timestamp of this event */ char timestamp[MAXINDITSTAMP]; /** handy place to hang helper info */ void *aux; } ILightVectorProperty; /** \struct IBLOB \brief One Blob (Binary Large Object) descriptor. */ typedef struct { /* one BLOB descriptor */ /** index name */ char name[MAXINDINAME]; /** this BLOB's label */ char label[MAXINDILABEL]; /** format attr */ char format[MAXINDIBLOBFMT]; /** malloced binary large object bytes */ void *blob; /** bytes in blob */ int bloblen; /** n uncompressed bytes */ int size; /** pointer to parent */ struct _IBLOBVectorProperty *bvp; /** handy place to hang helper info */ void *aux0, *aux1, *aux2; } IBLOB; /** \struct _IBLOBVectorProperty \brief BLOB (Binary Large Object) vector property descriptor. */ typedef struct _IBLOBVectorProperty { /* BLOB vector property descriptor */ /** device name */ char device[MAXINDIDEVICE]; /** property name */ char name[MAXINDINAME]; /** short description */ char label[MAXINDILABEL]; /** GUI grouping hint */ char group[MAXINDIGROUP]; /** client accessibility hint */ IPerm p; /** current max time to change, secs */ double timeout; /** current property state */ IPState s; /** BLOBs comprising this vector */ IBLOB *bp; /** dimension of bp[] */ int nbp; /** ISO 8601 timestamp of this event */ char timestamp[MAXINDITSTAMP]; /** handy place to hang helper info */ void *aux; } IBLOBVectorProperty; /** \brief Handy macro to find the number of elements in array a[]. Must be used with actual array, not pointer. */ #define NARRAY(a) (sizeof(a)/sizeof(a[0])) #endif indi-0.5/src/README0000644000175000017500000001035710605175713011573 0ustar jrjrThe code here demonstrates the use of INDI, an Instrument-Neutral Device Interface protocol. See http://www.clearskyinstitute.com/INDI/INDI.pdf. Architecture: Typical INDI Client / Server / Driver / Device connectivity: INDI Client 1 ----| |---- INDI Driver A ---- Dev X | | INDI Client 2 ----| |---- INDI Driver B ---- Dev Y | | | ... |--- indiserver ---| |-- Dev Z | | | | INDI Client n ----| |---- INDI Driver C ---- Dev T Client INET Server UNIX Driver Hardware processes sockets process pipes processes devices Indiserver is the public network access point where one or more INDI Clients may contact one or more INDI Drivers. Indiserver launches each driver process and arranges for it to receive the INDI protocol from Clients on its stdin and expects to find commands destined for Clients on the driver's stdout. Anything arriving from a driver process' stderr is copied to indiserver's stderr. Indiserver only provides convenient port, fork and data steering services. If desired, a Client may run and connect to INDI Drivers directly. Construction: An INDI driver typically consists of one .c file, eg, mydriver.c, which #includes indiapi.h to access the reference API declarations. It is compiled then linked with indidrivermain.o, eventloop.o and liblilxml.a to form an INDI process. These supporting files contain the implementation of the INDI Driver API and need not be changed in any way. Note that evenloop.[ch] provide a nice callback facility independent of INDI which may be used in other projects if desired. The driver implementation, again in our example mydriver.c, does not contain a main() but is expected to operate as an event-driver program. The driver must implement each ISxxx() function but never call them. The IS() functions are called by the reference implementation main() as messages arrive from Clients. Within each IS function the driver performs the desired tasks then may report back to the Client by calling the IDxxx() functions. The reference API provides IE() functions to allow the driver to add its own callback functions if desired. The driver can arrange for functions to be called when reading a file descriptor will not block; when a time interval has expired; or when there is no other client traffic in progress. The sample indiserver is a stand alone process that may be used to run one or more INDI-compliant drivers. It takes the names of each driver process to run in its command line args. To build indiserver type 'make indiserver'; to build all the sample drivers type 'make drivers'; to run the sample server with all drivers type 'make run'. Killing indiserver will also kill all the drivers it started. Secure remote operation: Suppose we want to run indiserver and its clients on a remote machine, r, and connect them to our favorite INDI client, XEphem, running on the local machine. From the local machine log onto the remote machine, r, by typing: ssh2 -L 7624:s:7624 r after logging in, run indiserver on the remote machine: make run Back on the local machine, start XEphem, then open Views -> Sky View -> Telescope -> INDI panel. XEphem will connect to the remote INDI server securely and automatically begin running. Sweet. Testing: A low-level way to test the socket, forking and data steering abilities of indiserver is to use the 'hose' command from the netpipes collection (http://web.purplefrog.com/~thoth/netpipes/netpipes.html): 1. start indiserver using UNIX' cat program as the only INDI "device": % indiserver cat & 2. use hose to connect to the "cat" device driver which just copies back: % hose localhost 7624 --slave hello world hello world more stuff more stuff ! For RCS Only -- Do Not Edit ! @(#) $RCSfile: README,v $ $Date: 2004/06/03 21:17:19 $ $Revision: 1.2 $ $Name: $ indi-0.5/src/stvdriver.c0000644000175000017500000012411310610506343013074 0ustar jrjr#if 0 STV Low Level Driver Copyright (C) 2006 Markus Wildi, markus.wildi@datacomm.ch The initial work is based on the program STVremote by Shashikiran Ganesh. email: gshashikiran_AT_linuxmail_dot_org This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include #include #include #include #include #include "stvdriver.h" #ifndef _WIN32 #include #endif /* INDI Common Routines/RS232 */ #include "indicom.h" extern int fd ; extern char tracking_buf[] ; struct termios orig_tty_setting; /* old serial port setting to restore on close */ struct termios tty_setting; /* new serial port setting */ #define FALSE 0 #define TRUE 1 /*int tty_read( int fd, char *buf, int nbytes, int timeout, int *nbytes_read) ; */ /*int tty_write( int fd, const char *buffer, int *nbytes_written) ; */ void ISUpdateDisplay( int buffer, int line) ; int STV_portWrite( char *buf, int nbytes) ; int STV_TXDisplay( void) ; int STV_TerminateTXDisplay( void) ; int STV_FileStatus( int) ; int STV_DownloadComplete( void) ; int STV_RequestImage( int compression, int buffer, int x_offset, int y_offset, int *length, int *lines, int image[][320], IMAGE_INFO *image_info) ; int STV_RequestImageData( int compression, int *data, int j, int length, int *values) ; int STV_Download( void) ; int STV_DownloadAll( void) ; int STV_RequestAck( void) ; int STV_CheckHeaderSum( unsigned char *buf) ; int STV_CheckDataSum( unsigned char *data) ; int STV_PrintBuffer( unsigned char *buf, int n ) ; int STV_PrintBufferAsText( unsigned char *buf, int n ) ; int STV_CheckAck( unsigned char *buf) ; int STV_SendPacket( int cmd, int *data, int n) ; int STV_ReceivePacket( unsigned char *buf, int mode) ; int STV_DecompressData( unsigned char *data, int *values, int length, int expected_n_values) ; int STV_BufferStatus( int buffer) ; void STV_PrintBits( unsigned int x, int n) ; unsigned int STV_RecombineInt( unsigned char low_byte, unsigned char high_byte) ; unsigned int STV_GetBits( unsigned int x, int p, int n) ; int STV_MenueSetup( int delay) ; int STV_MenueDateTime( int delay) ; int STV_MenueCCDTemperature( int delay) ; typedef struct { double ccd_temperature ; } DISPLAY_INFO ; DISPLAY_INFO di ; /* STV Buttons */ int STV_LRRotaryDecrease(void) { int data[]={LR_ROTARY_DECREASE_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_LRRotaryIncrease(void) { int data[]={ LR_ROTARY_INCREASE_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_UDRotaryDecrease(void) { int data[]={UD_ROTARY_DECREASE_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_UDRotaryIncrease(void) { int data[]={UD_ROTARY_INCREASE_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_AKey(void) { /* Parameter button */ int data[]={A_KEY_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_BKey(void) { /* Value Button */ int data[]={ B_KEY_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_Setup(void) { int data[]={SETUP_KEY_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1); } int STV_Interrupt(void) { int data[]={INT_KEY_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_Focus(void) { int data[]= {FOCUS_KEY_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_Image(void) { int data[]={IMAGE_KEY_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_Monitor(void) { int data[]={MONITOR_KEY_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_Calibrate(void) { int data[]={CAL_KEY_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_Track(void) { int data[]={TRACK_KEY_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_Display(void) { int data[]={DISPLAY_KEY_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_FileOps(void) { int data[]={FILEOPS_KEY_PATTERN} ; return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; } int STV_RequestImageInfo(int buffer, IMAGE_INFO *image_info) { int i ; int length ; int res ; int data[]= {buffer} ; unsigned char buf[1024] ; unsigned int value[21] ; if(( res= STV_BufferStatus( buffer)) != 0) { if( res== 1) { /*fprintf( stderr," STV_RequestImageInfo buffer empty %d\n", buffer) ; */ return res ; /* Buffer is empty */ } else { fprintf( stderr," STV_RequestImageInfo error %d\n", res) ; return res ; } } res= STV_SendPacket( REQUEST_IMAGE_INFO, data, 1) ; usleep(50000) ; res= STV_ReceivePacket( buf, 0) ; if(buf[1] != REQUEST_IMAGE_INFO) { /*length= buf[3] * 0x100 + buf[2] ; */ /*res= STV_PrintBuffer(buf, 6+ length+ 2) ; */ AGAINI: if(( res= STV_ReceivePacket( buf, 0)) < 0) { /* STV answers with a packet 0x03 sometimes, should be 0x04 */ return -1 ;; } if(buf[1] != REQUEST_IMAGE_INFO) { /* Second try */ fprintf( stderr, "STV_RequestImageInfo: expected REQUEST_IMAGE_INFO, received %d, try again\n", buf[1]) ; goto AGAINI ; } } length= buf[3] * 0x100 + buf[2]; /* DECODE it */ for( i= 6; i < length; i+= 2) { value[( i- 6)/2]= STV_RecombineInt( buf[ i], buf[ i+1]) ; } image_info->descriptor = value[0] ; /* Decode the descriptor */ /*STV_PrintBits(( unsigned int)value[0], 16) ; */ if(( image_info->descriptor & ID_BITS_MASK)== ID_BITS_10) { /* fprintf( stderr, "ADC Resolution: 10 bits\n") ; */ } else if(( image_info->descriptor & ID_BITS_MASK )== ID_BITS_8) { /*fprintf( stderr, "Resolution: 8 bits (focus mode only)\n") ; */ } if(( image_info->descriptor & ID_UNITS_MASK)== ID_UNITS_INCHES) { /*fprintf( stderr, "Units: inch\n") ; */ } else if(( image_info->descriptor & ID_UNITS_MASK)== ID_UNITS_CM) { /*fprintf( stderr, "Unis: cm\n") ; */ } if(( image_info->descriptor & ID_SCOPE_MASK)== ID_SCOPE_REFRACTOR) { /*fprintf( stderr, "Refractor\n") ; */ } else if(( image_info->descriptor & ID_SCOPE_MASK)== ID_SCOPE_REFLECTOR) { /*fprintf( stderr, "Reflector\n") ; */ } if(( image_info->descriptor & ID_DATETIME_MASK)== ID_DATETIME_VALID) { /*fprintf( stderr, "Date and time valid\n") ; */ } else if(( image_info->descriptor & ID_DATETIME_MASK)== ID_DATETIME_INVALID) { /*fprintf( stderr, "Date and time invalid\n") ; */ } if(( image_info->descriptor & ID_BIN_MASK)== ID_BIN_1X1) { image_info->binning=1 ; } else if(( image_info->descriptor & ID_BIN_MASK)== ID_BIN_2X2) { image_info->binning=2 ; } else if(( image_info->descriptor & ID_BIN_MASK)== ID_BIN_3X3) { image_info->binning=3 ; } if(( image_info->descriptor & ID_PM_MASK)== ID_PM_PM) { /*fprintf( stderr, "Time: PM\n") ; */ } else if(( image_info->descriptor & ID_PM_MASK)== ID_PM_AM) { /*fprintf( stderr, "Time: AM\n") ; */ } /* ToDo: Include that to the fits header */ if(( image_info->descriptor & ID_FILTER_MASK)== ID_FILTER_LUNAR) { /*fprintf( stderr, "Filter: Lunar\n") ; */ } else if(( image_info->descriptor & ID_FILTER_MASK)== ID_FILTER_NP ) { /*fprintf( stderr, "Filter: clear\n") ; */ } /* ToDo: Include that to the fits header */ if(( image_info->descriptor & ID_DARKSUB_MASK )== ID_DARKSUB_YES) { /*fprintf( stderr, "Drak sub yes\n") ; */ } else if(( image_info->descriptor & ID_DARKSUB_MASK )== ID_DARKSUB_NO) { /*fprintf( stderr, "Dark sub no\n") ; */ } if(( image_info->descriptor & ID_MOSAIC_MASK)== ID_MOSAIC_NONE) { /*fprintf( stderr, "Is NOT a mosaic\n") ; */ } else if(( image_info->descriptor & ID_MOSAIC_MASK)== ID_MOSAIC_SMALL) { /*fprintf( stderr, "Is a small mosaic\n") ; */ } else if(( image_info->descriptor & ID_MOSAIC_MASK)== ID_MOSAIC_LARGE) { /*fprintf( stderr, "Is a large mosaic\n") ; */ } image_info->height = value[1] ; image_info->width = value[2] ; image_info->top = value[3] ; image_info->left = value[4] ; /* Exposure time */ if((value[5]>= 100 ) && (value[5]<= 60000)) { image_info->exposure = ((float)value[5]) * 0.01; } else if((value[5]>= 60001 ) && (value[5]<= 60999)){ image_info->exposure = (( float)value[5]- 60000.) *.001 ; } else { fprintf( stderr, "Error Exposure time %d\n", value[5]) ; image_info->exposure = -1. ; } image_info->noExposure = value[6] ; image_info->analogGain = value[7] ; image_info->digitalGain= value[8] ; image_info->focalLength= value[9] ; image_info->aperture = value[10] ; image_info->packedDate = value[11] ; image_info->year = STV_GetBits( value[11], 6, 7) + 1999; image_info->day = STV_GetBits( value[11], 11, 5) ; image_info->month = STV_GetBits( value[11], 15, 4) ; image_info->packedTime = value[12]; image_info->seconds = STV_GetBits( value[12], 5, 6) ; image_info->minutes = STV_GetBits( value[12], 11, 6) ; image_info->hours = STV_GetBits( value[12], 15, 4) ; if(( image_info->descriptor & ID_PM_PM) > 0) { image_info->hours += 12 ; } if((value[13] & 0x8000)== 0x8000) { image_info->ccdTemp= (float)(0xffff - value[13]) /100. ; } else { image_info->ccdTemp= (float)value[13]/100. ; } image_info->siteID = value[14] ; image_info->eGain = value[15] ; image_info->background = value[16] ; image_info->range = value[17] ; image_info->pedestal = value[18] ; image_info->ccdTop = value[19] ; image_info->ccdLeft = value[20] ; /* fprintf( stderr, "descriptor:%d 0x%2x 0x%2x\n", image_info->descriptor, buf[6], buf[6+1]) ; */ /* fprintf( stderr, "height:%d\n", image_info->height) ; */ /* fprintf( stderr, "width:%d\n", image_info->width) ; */ /* fprintf( stderr, "top:%d\n", image_info->top) ; */ /* fprintf( stderr, "left:%d\n", image_info->left) ; */ /* fprintf( stderr, "exposure:%f\n", image_info->exposure) ; */ /* fprintf( stderr, "noExposure:%d\n", image_info->noExposure) ; */ /* fprintf( stderr, "analogGain:%d\n", image_info->analogGain) ; */ /* fprintf( stderr, "digitalGain:%d\n", image_info->digitalGain) ; */ /* fprintf( stderr, "focalLength:%d\n", image_info->focalLength) ; */ /* fprintf( stderr, "aperture:%d\n", image_info->aperture) ; */ /* fprintf( stderr, "packedDate:%d\n", image_info->packedDate) ; */ /* fprintf( stderr, "Year:%d\n", image_info->year) ; */ /* fprintf( stderr, "Day:%d\n", image_info->day) ; */ /* fprintf( stderr, "Month:%d\n", image_info->month) ; */ /* fprintf( stderr, "packedTime:%d\n", image_info->packedTime) ; */ /* fprintf( stderr, "Seconds:%d\n", image_info->seconds) ; */ /* fprintf( stderr, "minutes:%d\n", image_info->minutes) ; */ /* fprintf( stderr, "hours:%d\n", image_info->hours) ; */ /* fprintf( stderr, "ccdTemp:%f\n", image_info->ccdTemp) ; */ /* fprintf( stderr, "siteID:%d\n", image_info->siteID) ; */ /* fprintf( stderr, "eGain:%d\n", image_info->eGain) ; */ /* fprintf( stderr, "background:%d\n", image_info->background) ; */ /* fprintf( stderr, "range :%d\n", image_info->range ) ; */ /* fprintf( stderr, "pedestal:%d\n", image_info->pedestal) ; */ /* fprintf( stderr, "ccdTop :%d\n", image_info->ccdTop) ; */ /* fprintf( stderr, "ccdLeft:%d\n", image_info->ccdLeft) ; */ return 0 ; } int STV_RequestImage( int compression, int buffer, int x_offset, int y_offset, int *length, int *lines, int image[][320], IMAGE_INFO *image_info) { int i, j ; int res ; int n_values ; unsigned char buf[0xffff] ; int values[1024] ; int data[]= { 0, y_offset, *length, buffer} ; /* Offset row, Offset line, length, buffer number */ int XOFF ; /* fprintf(stderr, "STV_RequestImage: --------------------------------buffer= %d, %d\n", buffer, lines) ; */ if(( res= STV_RequestImageInfo( buffer, image_info)) != 0) { /* Trigger for download */ /* buffer empty */ return res ; } res= STV_BKey() ; /* "press" the STV Value button */ usleep(50000) ; res= STV_ReceivePacket(buf, 0) ; /* Check the boundaries obtained from the image data versus windowing */ /* Take the smaller boundaries in each direction */ if( x_offset > image_info->height) { x_offset= image_info->height ; } XOFF= image_info->top + x_offset ; if( y_offset > image_info->width) { y_offset= image_info->width ; } data[1]= image_info->left + y_offset ; if( *length > image_info->width- y_offset) { *length= image_info->width- y_offset ; } data[2]= *length ; if( *lines > image_info->height- x_offset) { *lines= image_info->height- x_offset ; } /*fprintf(stderr, "STV_RequestImage: DATA 0=%d, 1=%d, 2=%d, 3=%d, length=%d, lines=%d\n", data[0], data[1], data[2], data[3], *length, *lines) ; */ for( j= 0 ; j < *lines ; j++) { data[0]= j + XOFF; /*line */ if(( n_values= STV_RequestImageData( compression, data, j, *length, values)) < 0) { fprintf(stderr, "STV_RequestImage: Calling STV_RequestImageData failed %d\n", n_values) ; return n_values ; } else { for( i= 0; i < n_values ; i++) { image[j][i]= values[i] ; } ISUpdateDisplay( buffer, j) ; } } /* Read the 201th line, see mosaic mode */ /* ToDo: analyze/display the data or use them in the fits header(s) */ data[0]= 200; /*line */ if(( res= STV_RequestImageData( 1, data, 200, *length, values)) < 0) { return res ; } else { for( i= 0 ; i< n_values ; i++) { /* fprintf( stderr, "%d: %d ", i, values[i]) ; */ } /* fprintf( stderr, "\n") ; */ } res= STV_DownloadComplete() ; ISUpdateDisplay( buffer, -j) ; return 0 ; } int STV_RequestImageData( int compression, int *data, int j, int length, int *values) { int i ; int res ; int data_length ; int n_values ; unsigned char buf[0xffff] ; data_length= -1 ; if( compression== ON) { /* compressed download */ if(( res= STV_SendPacket( REQUEST_COMPRESSED_IMAGE_DATA, data, 4)) != 0){ fprintf(stderr, "STV_RequestImageData: could not write\n") ; return -1 ; } AGAINC: if(( res= STV_ReceivePacket(buf, 0)) > 0) { if( buf[1] != REQUEST_COMPRESSED_IMAGE_DATA) { if( buf[1] != DISPLAY_ECHO) { if( buf[1] != ACK) { fprintf(stderr, "STV_RequestImageData: expected REQUEST_COMPRESSED_IMAGE_DATA, received %2x\n", buf[1]) ; } } goto AGAINC ; } data_length= (int)buf[3] * 0x100 + (int)buf[2] ; if(( n_values= STV_DecompressData((buf+6), values, data_length, length)) < 0 ) { n_values= -n_values ; fprintf( stderr, "SEVERE ERROR on Line %d, pixel position=%d\n", j, n_values) ; _exit( -1) ; } if( n_values == length) { return n_values ; } else { fprintf( stderr, "SEVERE Error: Length not equal, Line: %d, %d != %d, data %2x %2x, values %d, %d\n", j, n_values, length, buf[ 6+ length -2], buf[ 6+ length -1], values[n_values-2], values[n_values-1]) ; _exit( 1) ; } } else { fprintf( stderr, "Error: waiting for data on the serial port at line %d\n", j) ; return -1 ; } } else { /* uncompressed download */ if(( res= STV_SendPacket( REQUEST_IMAGE_DATA, data, 4))== 0) { AGAINU: if(( res= STV_ReceivePacket(buf, 0)) > 0) { if( buf[1] != REQUEST_IMAGE_DATA) { if( buf[1] != DISPLAY_ECHO) { if( buf[1] != ACK) { fprintf(stderr, "STV_RequestImageData: expected REQUEST_IMAGE_DATA, received %2x\n", buf[1]) ; } } goto AGAINU ; } data_length= (int)buf[3] * 0x100 + (int)buf[2] ; for( i= 0; i < data_length ; i += 2) { values[i/2]= STV_RecombineInt(buf[6 + i], buf[7 + i]) ; } return data_length/2 ; /*ISUpdateDisplay( buffer, j) ; */ /* Update the display of the INDI client */ } else { fprintf( stderr, "Error: waiting for data on the serial port at line %d\n", j) ; return -1 ; } } else { fprintf( stderr, "STV_RequestImageData: error writing %d\n", res) ; } } return 0 ; } int STV_DecompressData( unsigned char *data, int *values, int length, int expected_n_values) { int i, n_values ; int value ; int base ; base= STV_RecombineInt( data[0], data[1]) ; /*STV Manual says: MSB then LSB! */ values[0]= base ; i= 2 ; n_values= 1 ; while( i < length ) { if( (( data[ i] & 0xc0))== 0x80) { /*two bytes, first byte: bit 7 set, 6 cleared, 14 bits data */ if(( data[ i] & 0x20)== 0x20) { /* minus sign set? */ value= - ((int)(( (~data[ i] & 0x1f)) * 0x100) + (((int) (~data[ i+ 1])) & 0xff))- 1 ; /* value without sign */ } else { value= (int) (( data[ i] & 0x1f) * 0x100) + (int) (data[ i + 1]) ; } base= value + base ; /* new base value */ values[n_values++]= base ; /*pixel data */ i += 2 ; } else if((( data[ i] & 0x80))== 0) { /* one byte: bit 7 clear (7 bits data) */ if(( data[ i] & 0x40)== 0x40) { /* minus sign set? */ value= - (int) ( (~(data[ i])) & 0x3f) - 1 ; /* value without sign */ } else { value= (int) ( data[ i] & 0x3f) ; /*fprintf( stderr, "Value 7P: %d, pixel value: %d, length %d, pix=%d\n", value, value+ base, length, n_values) ; */ } /* Sometimes the STV send a 0 at the end, thats not very likely a pixel to pixel variation */ /* I checked the last decompressed pixel value against the last uncompressed pixel value */ /* with different images - it seems to be ok. */ if(( value == 0) &&( n_values== expected_n_values)){ /*fprintf( stderr, "Ignoring byte %d, Zero difference obtained values: %d\n", i, n_values) ; */ } else { base= value + base ; values[n_values++]= base ; } i++ ; } else if( (( data[ i] & 0xc0))== 0xc0) { /*two bytes, values= pixel_n/4 */ /*STV_PrintBits( data[ i], 8) ; */ /*STV_PrintBits( data[ i+ 1], 8) ; */ value= 4* ((int) (( data[ i] & 0x3f) * 0x100) + (int) (data[ i + 1])) ; /*fprintf( stderr, "Value 14P: %d, pixel value: %d, length %d, pix=%d\n", value, value+ base, length, n_values) ; */ base= value ; values[n_values++]= value ; i += 2 ; /*return -n_values ; */ } else { fprintf( stderr, "Unknown compression case: %2x, length %d, i=%d\n", data[ i], length, i) ; return -n_values ; /* exit */ } } return n_values ; } int STV_TXDisplay(void) { int data[]={TRUE} ; return STV_SendPacket( DISPLAY_ECHO, data, 1); } int STV_TerminateTXDisplay(void) { int res ; int data[]={FALSE} ; res= STV_SendPacket( DISPLAY_ECHO, data, 1); /* Despite the manual says so, I not always see an ACK packet */ /* So i flush it for the moment */ tcflush(fd, TCIOFLUSH); return res ; } int STV_FileStatus(int status) { int data[]= {status} ; return STV_SendPacket( FILE_STATUS, data, 1); } int STV_DownloadComplete(void) { return STV_SendPacket( DOWNLOAD_COMPLETE, NULL, 0); } int STV_Download(void) { return STV_SendPacket( REQUEST_DOWNLOAD, NULL, 0) ; } int STV_DownloadAll(void) { return STV_SendPacket( REQUEST_DOWNLOAD_ALL, NULL, 0); } int STV_RequestAck(void) { int data[]={0x06,0x06,0x06 } ; /* SBIG manual says contains data, which? */ return STV_SendPacket( REQUEST_ACK, data, 3) ; } int STV_BufferStatus( int buffer){ unsigned char buf[1024]; int buffers ; int res ; int val ; /*fprintf(stderr, "STV_BufferStatus entering\n") ; */ usleep(50000) ; if(( res= STV_SendPacket( REQUEST_BUFFER_STATUS, NULL, 0)) < 0) { fprintf( stderr, "STV_BufferStatus: Error requesting buffer status: %d\n", buffer) ; return -1 ; } else { /*fprintf( stderr, "STV_BufferStatus %2d\n", buffer) ; */ } AGAIN: if(( res= STV_ReceivePacket( buf, 0)) < 0) { fprintf( stderr, "STV_BufferStatus: Error reading: %d\n", res) ; return -1 ;; } if( buf[1]== REQUEST_BUFFER_STATUS) { buffers= STV_RecombineInt( buf[6], buf[7]) * 0x10000 + STV_RecombineInt( buf[8], buf[9]) ; if(( val= STV_GetBits( buffers, buffer, 1))== 1) { res= 0 ; /* image present */ } else { /*fprintf( stderr, "STV_BufferStatus %2d is empty\n", buffer) ; */ res= 1 ; /* empty */ } } else { /* The SBIG manual does not specify an ACK, but it is there (at least sometimes) */ if(( val= STV_CheckAck( buf))== 0) { /*fprintf( stderr, "STV_BufferStatus SAW ACK, reading again\n") ; */ goto AGAIN ; } /* The SBIG manual does not specify the cmd in the answer */ if( buf[1] != DISPLAY_ECHO) { fprintf( stderr, "STV_BufferStatus: unexpected cmd byte received %d\n", buf[1]) ; val= STV_RecombineInt(buf[2], buf[3]) ; res= STV_PrintBuffer( buf, 6+ val + 2) ; return -1 ; } else { /* a display packet is silently ignored, there are many of this kind */ fprintf( stderr, "STV_BufferStatus DISPLAY_ECHO received, try again\n") ; return -1 ; } } /* fprintf(stderr, "STV_BufferStatus leaving\n") ; */ return res; } /* Low level communication */ /* STV_ReceivePacket n_bytes read */ int STV_ReceivePacket( unsigned char *buf, int mode) { int i,j,k ; int n_bytes=0 ; int length=0 ; int res ; int trb=0 ; int pos=0 ; char display1[25] ; char display2[25] ; j= 0 ; tracking_buf[ 0]= 0 ; /*fprintf( stderr,"R") ; */ while(pos < 6) { /* Read the header first, calculate length of data */ /* At higher speeds the data arrives in smaller chunks, assembling the packet */ if(( trb= read( fd, (char *)(buf + pos), 1))== -1) { fprintf(stderr, "Error, %s\n", strerror(errno)) ; } if(buf[0]== 0xa5) { if( pos== 5) { pos++ ; break ; } else { pos+= trb ; /* could be zero */ } } else { /* In tracking mode the STV sends raw data (time, brightnes, centroid x,y). */ /* Under normal operation here appear pieces of a packet. This could happen */ /* on start up or if something goes wrong. */ tracking_buf[ j++]= buf[pos] ; /*fprintf(stderr, "READ: %d, read %d, pos %d, 0x%2x< %c\n", j, trb, pos, buf[pos], buf[pos]) ; */ } } if( j> 0) { /* Sometimes the packets are corrupt, e.g. at the very beginning */ /* Or it is tracking information */ tracking_buf[ j]= 0 ; if( mode== ON) { /* Tracking mode */ fprintf(stderr, "%s\n", tracking_buf) ; } else { for( k= 0 ; k< j; k++) { if(!( tracking_buf[ k] >29 && tracking_buf[ k] < 127)) { tracking_buf[ k]= 0x20 ; /* simply */ } } fprintf(stderr, "Not a packet: length: %d >%s<\n", j, tracking_buf) ; } } n_bytes= pos ; if(( buf[0]== 0xa5) && ( pos== 6)) { /* Check the sanity of the header part */ if((res= STV_CheckHeaderSum( buf))== 0) { length= (int)buf[3] * 0x100 + (int)buf[2]; ; if( length >0) { trb= 0 ; while( pos < 6 + length + 2) { /* header, data, check sum */ /* At higher speeds the data arrives in smaller chunks, assembling the packet */ if(( trb= read(fd, (char *)(buf + pos), (6 + length + 2)- pos))== -1) { fprintf(stderr, "STV_ReceivePacket: Error reading at serial port, %s\n", strerror( errno)) ; return -1 ; } pos += trb ; } n_bytes += pos ; /*fprintf(stderr, "STV_ReceivePacket: LEAVING LOOP length %d, to read %d, read %d, pos %d\n", length, (6 + length + 2)- pos, trb, pos) ; */ } } else { fprintf(stderr, "STV_ReceivePacket: Header check failed\n") ; return -1 ; } } else if( pos >0) { for(i= 0 ; i < 6 ; i++) { if( buf[i]==0xa5){ fprintf(stderr, "STV_ReceivePacket: pos= %d, saw 0xa5 at %d\n", pos, i) ; } } return -1 ; } else { fprintf(stderr, "STV_ReceivePacket: NO 0xa5 until pos= %d\n", pos) ; return -1 ; } if( length > 0) { /* Check the sanity of the data */ if((res= STV_CheckDataSum( buf))== -1) { return -1 ; } } /* Analyse the display and retrieve the values */ if( buf[1]== DISPLAY_ECHO) { for( i=0 ; i< 24; i++) { display1[i]= buf[i+6] ; if( display1[i]== 0 ){ display1[i]= 0x32 ; } display2[i]= buf[i+30] ; if( display2[i]== 0 ){ display2[i]= 0x32 ; } } display1[24]= 0 ; display2[24]= 0 ; /*fprintf(stderr, "STV_ReceivePacket: DISPLAY1 %s<\n", display1) ; */ /*fprintf(stderr, "STV_ReceivePacket: DISPLAY2 %s<\n", display2) ; */ /* CCD temperature */ if(( res= strncmp( "CCD Temp.", display2, 9)) ==0) { float t ; res= sscanf( display2, "CCD Temp. %f", &t) ; di.ccd_temperature= (double) t; /*fprintf(stderr, "STV_ReceivePacket: Read from DISPLAY2 %g<\n", di.ccd_temperature ) ; */ }/* further values can be stored here */ } return n_bytes ; } int STV_CheckHeaderSum( unsigned char *buf) { int sum = buf[0] + buf[1] + buf[2] + buf[3] ; /* Calculated header sum */ int sumbuf= STV_RecombineInt( buf[4],buf[5]) ; /* STV packet header sum */ if(buf[0] != 0xa5) { fprintf(stderr, "STV_CheckHeaderSum: Wrong start byte, skipping\n") ; return -1 ; } if( sum != sumbuf) { fprintf(stderr, "STV_CheckHeaderSum: NOK: %d==%d\n", sum, sumbuf ) ; return -1 ; } return 0 ; } int STV_CheckDataSum( unsigned char *buf) { /* *buf points to the beginning of the packet */ int j, n ; int sum= 0 ; int sumbuf=0 ; n= STV_RecombineInt( buf[2], buf[3]) ; if( n== 0) { fprintf(stderr, "STV_CheckDataSum: No data present\n") ; return 0 ; } sumbuf= STV_RecombineInt( buf[6 + n], buf[6 + n +1]) ; for( j=0; j < n ; j++) { sum += (int)buf[6 + j] ; } sum= sum & 0xffff ; if( sum != sumbuf) { fprintf(stderr, "DATA SUM NOK: %d !=%d\n", sum, sumbuf) ; return -1 ; } return 0 ; } int STV_PrintBuffer( unsigned char *buf, int n ) { /* For debugging purposes only */ int i ; fprintf(stderr, "\nHEADER: %d bytes ", n) ; for(i=0; i < n; i++) { if( i==6) { fprintf(stderr, "\nDATA : ") ; } fprintf(stderr, "%d:0x%2x<>%c< >>", i, (unsigned char)buf[i], (unsigned char)buf[i]) ; /*STV_PrintBits((unsigned int) buf[i], 8) ; */ } fprintf(stderr, "\n") ; return 0 ; } int STV_PrintBufferAsText( unsigned char *buf, int n ) { /* For debugging purposes only */ int i ; fprintf(stderr, "\nHEADER: %d bytes ", n) ; for(i=0; i < n; i++) { if( i==6) { fprintf(stderr, "\nDATA : ") ; } fprintf(stderr, "%c", (unsigned char)buf[i]) ; } fprintf(stderr, "\n") ; return 0 ; } /* Aggregates a STV command packet */ int STV_SendPacket( int cmd, int *data, int n) { char buf[1024]; int j,l ; int res ; int sum ; /* check sum */ /* Header section */ buf[0] = (unsigned char) 0xa5; /* start byte */ buf[1] = (unsigned char) cmd; /* command byte */ buf[2] = (unsigned char) 2 * n; /* data length N (low byte) */ buf[3] = (unsigned char) 0x00; /* data length N (high byte) */ sum = buf[0] + buf[1] + buf[2] + buf[3]; /* header checksum */ buf[4] = (unsigned char) sum % 0x100; /* header checksum low byte */ buf[5] = (unsigned char) (sum / 0x100); /* header checksum high byte */ /* DATA section */ l= 0 ; if( n > 0) { l= 2 ; /* Two bytes per value are sent to STV */ for( j=0; j < 2 * n ; j += 2) { buf[6+ j] = (unsigned char) (data[j/2] % 0x100); /* data low byte */ buf[7+ j] = (unsigned char) (data[j/2] / 0x100); /* data high byte */ } sum = 0 ; for( j=0; j < 2 * n ; j++) { if((int)buf[6+ j] < 0 ) { sum = sum + 0xff+ (int)buf[6+ j] + 1 ; } else { sum = sum + (int)buf[6+ j] ; } } buf[6 + 2 * n ] = (unsigned char) (sum % 0x10000) ; /* data checksum (low byte) */ buf[7 + 2 * n ] = (unsigned char) (sum / 0x100) ; /* data checksum (high byte) */ } if(( res= STV_CheckHeaderSum( (unsigned char *) buf)) != 0) { /* Check outgoing packet as well */ fprintf(stderr, "STV_SendPacket: corrupt header\n") ; if(n > 0) { if(( res= STV_CheckDataSum( (unsigned char *) buf)) != 0) { fprintf(stderr, "STV_SendPacket: corrupt data\n") ; } } } return STV_portWrite( buf, 8 + l * n ) ; } /* Returns 0 or -1 in case of an error */ int STV_portWrite( char *buf, int nbytes){ int bytesWritten = 0; /*fprintf( stderr,"w") ; */ while (nbytes > 0) { if((bytesWritten = write(fd, buf, nbytes)) == -1) { fprintf(stderr, "STV_portWrite: Error writing at serial port, %s\n", strerror( errno)) ; /* return -1 ; */ } if (bytesWritten < 0) { fprintf( stderr, "STV_portWrite: Error writing\n") ; return -1; } else { buf += bytesWritten; nbytes -= bytesWritten; } } return nbytes ; } int STV_CheckAck( unsigned char *buf) { /* Watch out for an ACK, for debugging purposes only */ int i ; unsigned char ackseq[]= {0xa5, 0x06, 0x00, 0x00, 0xab, 0x00} ; for(i= 0; i < 6; i++ ) { if( buf[i] != ackseq[i] ) { return -1 ; } } return 0 ; } unsigned int STV_RecombineInt( unsigned char low_byte, unsigned char high_byte) { return (unsigned int) high_byte * (unsigned int)0x100 + (unsigned int)low_byte ; } unsigned int STV_GetBits( unsigned int x, int p, int n){ /* from the C book */ return ( x >> (p+ 1-n)) & ~(~0 << n) ; } void STV_PrintBits( unsigned int x, int n) { /* debugging purposes only */ int i ; int res ; fprintf( stderr, "STV_PrintBits:\n") ; if( n> 8) { fprintf( stderr, "54321098 76543210\n") ; } else { fprintf( stderr, "76543210\n") ; } for( i= n; i >0 ; i--) { if(( i==8) && (n> 8)) { fprintf( stderr, " ") ; } if(( res=STV_GetBits( x, i-1, 1))==0) { fprintf( stderr, "0") ; } else { fprintf( stderr, "1") ; } } fprintf( stderr, "\n") ; } double STV_SetCCDTemperature( double set_value) { int i ; int res ; int delay= 40000 ; unsigned char buf[1024] ; /* 1st step */ res= STV_Interrupt() ; /* Reset Display */ tcflush(fd, TCIOFLUSH); usleep( 100000) ; STV_MenueCCDTemperature( delay) ; for( i=0 ; i< 100 ; i++) { /* Change to the highest temperature */ res= STV_LRRotaryIncrease() ; tcflush(fd, TCIOFLUSH); usleep( delay) ; } di.ccd_temperature= 25.2 ; /* The actual value is set in STV_ReceivePacket, needed to enter the while() loop */ i= 0 ; while( set_value < di.ccd_temperature) { /*fprintf( stderr, "STV_SetCCDTemperature %g %g\n", set_value, di.ccd_temperature) ; */ res= STV_LRRotaryDecrease() ; /* Lower CCD temperature */ /*fprintf(stderr, ":") ; */ usleep( 10000) ; res= STV_TerminateTXDisplay(); usleep( 10000) ; res= STV_TXDisplay(); /* That's the trick, STV sends at least one display */ res= STV_ReceivePacket( buf, 0) ; /* discard it */ /*STV_PrintBufferAsText( buf, res) ; */ if(( res != 62) || ( i++ > 100)) { /* why 56 + 6?, 6 + 48 + 6 */ STV_PrintBuffer( buf, res) ; /*STV_PrintBufferAsText( buf, res) ; */ return 0.0 ; } } res= STV_Interrupt() ; return di.ccd_temperature ; } int STV_MenueCCDTemperature( int delay) { int res ; res= STV_MenueSetup( delay) ; usleep( delay) ; res= STV_UDRotaryIncrease() ; /* Change to CCD Temperature */ /*usleep( delay) ; */ tcflush(fd, TCIOFLUSH); return 0 ; } int STV_SetDateTime( char *times) { int i ; int res ; int turn ; time_t curtime; struct tm utc; struct tm *utcp; int delay= 20000 ; /*fprintf(stderr, "STV_SetTime\n") ; */ if((times== NULL) || (( res= strlen(times))==0)) { /* Get the current time. */ curtime = time (NULL); utcp = gmtime( &curtime); /* I'm not C guru */ utc.tm_mon = utcp->tm_mon ; utc.tm_mday = utcp->tm_mday ; utc.tm_year = utcp->tm_year ; utc.tm_hour = utcp->tm_hour ; utc.tm_min = utcp->tm_min ; utc.tm_sec = utcp->tm_sec ; } else { if( extractISOTime( times, &utc) < 0) { fprintf( stderr, "Bad time string %s\n", times) ; return -1 ; } } /* Print out the date and time in the standard format. */ /*fprintf( stderr, "TIME %s\n", asctime (utc)) ; */ /* 1st step */ res= STV_Interrupt() ; /* Reset Display */ usleep( delay) ; tcflush(fd, TCIOFLUSH); res= STV_MenueDateTime( delay) ; usleep( delay) ; res= STV_MenueDateTime( delay) ; /* This not an error */ usleep( delay) ; for( i=0 ; i< 13 ; i++) { /* Reset Month menu to the lef most position */ res= STV_LRRotaryDecrease() ; usleep( delay) ; } for( i=0 ; i< utc.tm_mon ; i++) { /* Set Month menu */ res= STV_LRRotaryIncrease() ; usleep( delay) ; tcflush(fd, TCIOFLUSH); } res= STV_AKey() ; /* Press the Parameter button */ usleep( delay) ; tcflush(fd, TCIOFLUSH); for( i=0 ; i< 32 ; i++) { /* Reset Day menu to the lef most position */ res= STV_LRRotaryDecrease() ; usleep( delay) ; tcflush(fd, TCIOFLUSH); } for( i= 0; i< utc.tm_mday-1 ; i++) { /* Set Day menu -1? */ res= STV_LRRotaryIncrease() ; usleep( delay) ; tcflush(fd, TCIOFLUSH); } res= STV_AKey() ; /* Press the Parameter button */ usleep( delay) ; tcflush(fd, TCIOFLUSH); for( i=0 ; i< 128 ; i++) { /* Reset Year menu to the lef most position, ATTENTION */ res= STV_LRRotaryDecrease() ; usleep( delay) ; /* sleep a 1/100 second */ tcflush(fd, TCIOFLUSH); } for( i=0 ; i< utc.tm_year -99 ; i++) { /* Set Year menu */ res= STV_LRRotaryIncrease() ; usleep( delay) ; tcflush(fd, TCIOFLUSH); } res= STV_AKey() ; /* Press the Parameter button */ usleep( delay) ; tcflush(fd, TCIOFLUSH); for( i=0 ; i< 25 ; i++) { /* Reset Hour menu to the lef most position, ATTENTION */ res= STV_LRRotaryDecrease() ; usleep( delay) ; tcflush(fd, TCIOFLUSH); } for( i=0 ; i< utc.tm_hour ; i++) { /* Set Hour menu */ res= STV_LRRotaryIncrease() ; usleep( delay) ; tcflush(fd, TCIOFLUSH); } res= STV_AKey() ; /* Press the Parameter button */ usleep( delay) ; tcflush(fd, TCIOFLUSH); for( i=0 ; i< 61 ; i++) { /* Reset Minute menu to the lef most position, ATTENTION */ res= STV_LRRotaryDecrease() ; usleep( delay) ; tcflush(fd, TCIOFLUSH); } for( i=0 ; i< utc.tm_min ; i++) { /* Set Minute menu */ res= STV_LRRotaryIncrease() ; usleep( delay) ; tcflush(fd, TCIOFLUSH); } res= STV_AKey() ; /* Press the Parameter button */ tcflush(fd, TCIOFLUSH); for( i=0 ; i< 5 ; i++) { /* Reset Seconds menu to the lef most position, ATTENTION */ res= STV_LRRotaryDecrease() ; usleep( delay) ; tcflush(fd, TCIOFLUSH); } if ( utc.tm_sec < 15) { turn= 0 ; } else if ( utc.tm_sec < 30) { turn= 1 ; } else if ( utc.tm_sec < 45) { turn= 2 ; } else { turn= 3 ; } for( i=0 ; i< turn ; i++) { /* Set Seconds menu, steps of 15 seconds */ res= STV_LRRotaryIncrease() ; usleep( delay) ; tcflush(fd, TCIOFLUSH); } res= STV_AKey() ; /* Press the Parameter button */ usleep( delay) ; tcflush(fd, TCIOFLUSH); res= STV_BKey() ; /* Press the Parameter button */ usleep( delay) ; tcflush(fd, TCIOFLUSH); res= STV_Interrupt() ; return 0 ; } int STV_MenueDateTime( int delay) { int i ; int res ; res= STV_MenueSetup( delay) ; usleep( delay) ; res= STV_BKey() ; /* Press the Value button */ usleep( delay) ; for( i=0 ; i< 8 ; i++) { /* Reset Date menu to the lef most position */ res= STV_UDRotaryDecrease() ; usleep( delay) ; tcflush(fd, TCIOFLUSH); } return 0 ; } int STV_MenueSetup( int delay) { int i ; int res ; res= STV_Setup() ; /* Change to Setup */ usleep( delay) ; for( i=0 ; i< 16 ; i++) { /* Reset Setup menu to the lef most position */ res= STV_UDRotaryDecrease() ; usleep( delay) ; tcflush(fd, TCIOFLUSH); } return 0 ; } int STV_Connect( char *device, int baud) { /*fprintf( stderr, "STV_Connect\n") ; */ if(( fd= init_serial( device, baud, 8, 0, 1))== -1) { fprintf(stderr, "Error on port %s, %s\n", device, strerror(errno)) ; return -1 ; } return fd ; } /****************************************************************************** * shutdown_serial(..) ****************************************************************************** * Restores terminal settings of open serial port device and close the file. * Arguments: * fd: file descriptor of open serial port device. *****************************************************************************/ void shutdown_serial(int fd) { if (fd > 0) { if (tcsetattr(fd, TCSANOW, &orig_tty_setting) < 0) { perror("shutdown_serial: can't restore serial device's terminal settings."); } close(fd); } } /****************************************************************************** * init_serial(..) ****************************************************************************** * Opens and initializes a serial device and returns it's file descriptor. * Arguments: * device_name : device name string of the device to open (/dev/ttyS0, ...) * bit_rate : bit rate * word_size : number of data bits, 7 or 8, USE 8 DATA BITS with modbus * parity : 0=no parity, 1=parity EVEN, 2=parity ODD * stop_bits : number of stop bits : 1 or 2 * Return: * file descriptor of successfully opened serial device * or -1 in case of error. *****************************************************************************/ int init_serial(char *device_name, int bit_rate, int word_size, int parity, int stop_bits) { int fd; char *msg; /* open serial device */ fd = open(device_name, O_RDWR | O_NOCTTY); if (fd < 0) { if (asprintf(&msg, "init_serial: open %s failed", device_name) < 0) perror(NULL); else perror(msg); return -1; } /* save current tty settings */ if (tcgetattr(fd, &orig_tty_setting) < 0) { perror("init_serial: can't get terminal parameters."); return -1; } /* Control Modes */ /* Set bps rate */ int bps; switch (bit_rate) { case 0: bps = B0; break; case 50: bps = B50; break; case 75: bps = B75; break; case 110: bps = B110; break; case 134: bps = B134; break; case 150: bps = B150; break; case 200: bps = B200; break; case 300: bps = B300; break; case 600: bps = B600; break; case 1200: bps = B1200; break; case 1800: bps = B1800; break; case 2400: bps = B2400; break; case 4800: bps = B4800; break; case 9600: bps = B9600; break; case 19200: bps = B19200; break; case 38400: bps = B38400; break; case 57600: bps = B57600; break; case 115200: bps = B115200; break; case 230400: bps = B230400; break; default: if (asprintf(&msg, "init_serial: %d is not a valid bit rate.", bit_rate) < 0) perror(NULL); else perror(msg); return -1; } if ((cfsetispeed(&tty_setting, bps) < 0) || (cfsetospeed(&tty_setting, bps) < 0)) { perror("init_serial: failed setting bit rate."); return -1; } /* Control Modes */ /* set no flow control word size, parity and stop bits. */ /* Also don't hangup automatically and ignore modem status. */ /* Finally enable receiving characters. */ tty_setting.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | HUPCL | CRTSCTS); /* #ifdef CBAUDEX */ /*tty_setting.c_cflag &= ~(CBAUDEX); */ /*#endif */ /*#ifdef CBAUDEXT */ /*tty_setting.c_cflag &= ~(CBAUDEXT); */ /*#endif */ tty_setting.c_cflag |= (CLOCAL | CREAD); /* word size */ switch (word_size) { case 5: tty_setting.c_cflag |= CS5; break; case 6: tty_setting.c_cflag |= CS6; break; case 7: tty_setting.c_cflag |= CS7; break; case 8: tty_setting.c_cflag |= CS8; break; default: fprintf( stderr, "Default\n") ; if (asprintf(&msg, "init_serial: %d is not a valid data bit count.", word_size) < 0) perror(NULL); else perror(msg); return -1; } /* parity */ switch (parity) { case PARITY_NONE: break; case PARITY_EVEN: tty_setting.c_cflag |= PARENB; break; case PARITY_ODD: tty_setting.c_cflag |= PARENB | PARODD; break; default: fprintf( stderr, "Default1\n") ; if (asprintf(&msg, "init_serial: %d is not a valid parity selection value.", parity) < 0) perror(NULL); else perror(msg); return -1; } /* stop_bits */ switch (stop_bits) { case 1: break; case 2: tty_setting.c_cflag |= CSTOPB; break; default: fprintf( stderr, "Default2\n") ; if (asprintf(&msg, "init_serial: %d is not a valid stop bit count.", stop_bits) < 0) perror(NULL); else perror(msg); return -1; } /* Control Modes complete */ /* Ignore bytes with parity errors and make terminal raw and dumb. */ tty_setting.c_iflag &= ~(PARMRK | ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON | IXANY); tty_setting.c_iflag |= INPCK | IGNPAR | IGNBRK; /* Raw output. */ tty_setting.c_oflag &= ~(OPOST | ONLCR); /* Local Modes */ /* Don't echo characters. Don't generate signals. */ /* Don't process any characters. */ tty_setting.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN | NOFLSH | TOSTOP); tty_setting.c_lflag |= NOFLSH; /* blocking read until 1 char arrives */ tty_setting.c_cc[VMIN] = 1; tty_setting.c_cc[VTIME] = 0; /* now clear input and output buffers and activate the new terminal settings */ tcflush(fd, TCIOFLUSH); if (tcsetattr(fd, TCSANOW, &tty_setting)) { perror("init_serial: failed setting attributes on serial port."); shutdown_serial(fd); return -1; } return fd; } indi-0.5/src/indi_philips.cpp0000644000175000017500000000377710610474326014100 0ustar jrjr#if 0 V4L INDI Driver INDI Interface for V4L devices (Philips) Copyright (C) 2003-2005 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include "v4lphilips.h" V4L_Philips *MainCam = NULL; /* Main and only camera */ /* send client definitions of all properties */ void ISInit() { if (MainCam == NULL) { MainCam = new V4L_Philips(); MainCam->initProperties("Philips Webcam"); MainCam->initCamBase(); } } void ISGetProperties (const char *dev) { ISInit(); MainCam->ISGetProperties(dev); } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { ISInit(); MainCam->ISNewSwitch(dev, name, states, names, n); } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { ISInit(); MainCam->ISNewText(dev, name, texts, names, n); } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { ISInit(); MainCam->ISNewNumber(dev, name, values, names, n); } void ISNewBLOB (const char */*dev*/, const char */*name*/, int */*sizes[]*/, char **/*blobs[]*/, char **/*formats[]*/, char **/*names[]*/, int /*n*/) { // We use this if we're receiving binary data from the client. Most likely we won't for this driver. } indi-0.5/src/trutech_wheel.c0000644000175000017500000002372310610474331013714 0ustar jrjr#if 0 True Technology Filter Wheel Copyright (C) 2006 Jasem Mutlaq (mutlaqja AT ikarustech DOT com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "indidevapi.h" #include "eventloop.h" #include "indicom.h" void ISInit(void); void getBasicData(void); void ISPoll(void *); void handleExposure(void *); void connectFilter(void); int manageDefaults(char errmsg[]); int checkPowerS(ISwitchVectorProperty *sp); int checkPowerN(INumberVectorProperty *np); int checkPowerT(ITextVectorProperty *tp); int getOnSwitch(ISwitchVectorProperty *sp); int isFilterConnected(void); static int targetFilter; static int fd; static char COMM_PRE = 0x01; static char COMM_INIT = 0xA5; static char COMM_FILL = 0x20; #define mydev "TruTech Wheel" #define MAIN_GROUP "Main Control" #define currentFilter FilterPositionN[0].value #define POLLMS 3000 #define DEFAULT_FILTER_COUNT 5 #define MAX_FILTER_COUNT 10 #define ERRMSG_SIZE 1024 #define CMD_SIZE 5 #define CMD_JUNK 64 #define CMD_RESP 15 #define FILTER_TIMEOUT 15 /* 15 Seconds before timeout */ #define FIRST_FILTER 1 /*INDI controls */ /* Connect/Disconnect */ static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}}; static ISwitchVectorProperty PowerSP = { mydev, "CONNECTION" , "Connection", MAIN_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0}; /* Connection Port */ static IText PortT[] = {{"PORT", "Port", 0, 0, 0, 0}}; static ITextVectorProperty PortTP = { mydev, "DEVICE_PORT", "Ports", MAIN_GROUP, IP_RW, 0, IPS_IDLE, PortT, NARRAY(PortT), "", 0}; /* Home/Learn Swtich */ static ISwitch HomeS[] = {{"Find" , "" , ISS_OFF, 0, 0}}; static ISwitchVectorProperty HomeSP = { mydev, "HOME" , "", MAIN_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE, HomeS, NARRAY(HomeS), "", 0}; /* Filter Count */ static INumber FilterCountN[] = { {"Count", "", "%2.0f", 0 , MAX_FILTER_COUNT, 1, DEFAULT_FILTER_COUNT, 0, 0, 0}}; static INumberVectorProperty FilterCountNP = { mydev, "Filter Count", "", MAIN_GROUP, IP_RW, 0, IPS_IDLE, FilterCountN, NARRAY(FilterCountN), "", 0}; /* Filter Position */ static INumber FilterPositionN[] = { {"SLOT", "Active Filter", "%2.0f", 1 , DEFAULT_FILTER_COUNT, 1, 1, 0, 0, 0}}; static INumberVectorProperty FilterPositionNP = { mydev, "FILTER_SLOT", "Filter", MAIN_GROUP, IP_RW, 0, IPS_IDLE, FilterPositionN, NARRAY(FilterPositionN), "", 0}; /* send client definitions of all properties */ void ISInit() { static int isInit=0; if (isInit) return; targetFilter = -1; fd = -1; isInit = 1; } void ISGetProperties (const char *dev) { ISInit(); if (dev && strcmp (mydev, dev)) return; /* Main Control */ IDDefSwitch(&PowerSP, NULL); IDDefText(&PortTP, NULL); IDDefNumber(&FilterCountNP, NULL); IDDefSwitch(&HomeSP, NULL); IDDefNumber(&FilterPositionNP, NULL); } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n) { dev=dev;name=name;sizes=sizes;blobs=blobs;formats=formats;names=names;n=n; } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { int err; char error_message[ERRMSG_SIZE]; /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; ISInit(); /* Connection */ if (!strcmp (name, PowerSP.name)) { IUUpdateSwitches(&PowerSP, states, names, n); connectFilter(); return; } /* Home Search */ if (!strcmp (name, HomeSP.name)) { int nbytes=0; char type = 0x03; char chksum = COMM_INIT + type + COMM_FILL; char filter_command[5] = { COMM_PRE, COMM_INIT, type, COMM_FILL, chksum }; if (checkPowerS(&HomeSP)) return; err = tty_write(fd, filter_command, CMD_SIZE, &nbytes); /* Send Home Command */ if (err != TTY_OK) { tty_error_msg(err, error_message, ERRMSG_SIZE); HomeSP.s = IPS_ALERT; IDSetSwitch(&HomeSP, "Sending command Home to filter failed. %s", error_message); IDLog("Sending command Home to filter failed. %s\n", error_message); return; } FilterPositionN[0].value = 1; FilterPositionNP.s = IPS_OK; HomeSP.s = IPS_OK; IDSetSwitch(&HomeSP, "Filter set to HOME."); IDSetNumber(&FilterPositionNP, NULL); } } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { ISInit(); /* ignore if not ours */ if (dev && strcmp (mydev, dev)) return; if (!strcmp(name, PortTP.name)) { if (IUUpdateTexts(&PortTP, texts, names, n)) return; PortTP.s = IPS_OK; IDSetText(&PortTP, NULL); } } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { long err; INumber *np; n = n; /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; ISInit(); if (!strcmp(FilterPositionNP.name, name)) { if (!isFilterConnected()) { IDMessage(mydev, "Filter is not connected."); FilterPositionNP.s = IPS_IDLE; IDSetNumber(&FilterPositionNP, NULL); return; } np = IUFindNumber(&FilterPositionNP, names[0]); if (np == &FilterPositionN[0]) { targetFilter = values[0]; int nbytes=0; char type = 0x01; char chksum = COMM_INIT + type + (char) targetFilter; char filter_command[5] = { COMM_PRE, COMM_INIT, type, targetFilter, chksum }; if (targetFilter < FilterPositionN[0].min || targetFilter > FilterPositionN[0].max) { FilterPositionNP.s = IPS_ALERT; IDSetNumber(&FilterPositionNP, "Error: valid range of filter is from %d to %d", (int) FilterPositionN[0].min, (int) FilterPositionN[0].max); return; } IUUpdateNumbers(&FilterPositionNP, values, names, n); err = tty_write(fd, filter_command, CMD_SIZE, &nbytes); FilterPositionNP.s = IPS_OK; IDSetNumber(&FilterPositionNP, "Setting current filter to slot %d", targetFilter); } else { FilterPositionNP.s = IPS_IDLE; IDSetNumber(&FilterPositionNP, NULL); } return; } if (!strcmp(FilterCountNP.name, name)) { if (!isFilterConnected()) { IDMessage(mydev, "Filter is not connected."); FilterCountNP.s = IPS_IDLE; IDSetNumber(&FilterCountNP, NULL); return; } np = IUFindNumber(&FilterCountNP, names[0]); if (np == &FilterCountN[0]) { if (IUUpdateNumbers(&FilterCountNP, values, names, n) <0) return; FilterPositionN[0].min = 1; FilterPositionN[0].max = (int) FilterCountN[0].value; IUUpdateMinMax(&FilterPositionNP); FilterCountNP.s = IPS_OK; IDSetNumber(&FilterCountNP, "Updated number of available filters to %d", ((int) FilterCountN[0].value)); } else { FilterCountNP.s = IPS_IDLE; IDSetNumber(&FilterCountNP, NULL); } return; } } int getOnSwitch(ISwitchVectorProperty *sp) { int i=0; for (i=0; i < sp->nsp ; i++) { if (sp->sp[i].s == ISS_ON) return i; } return -1; } int checkPowerS(ISwitchVectorProperty *sp) { if (PowerSP.s != IPS_OK) { if (!strcmp(sp->label, "")) IDMessage (mydev, "Cannot change property %s while the wheel is offline.", sp->name); else IDMessage (mydev, "Cannot change property %s while the wheel is offline.", sp->label); sp->s = IPS_IDLE; IDSetSwitch(sp, NULL); return -1; } return 0; } int checkPowerN(INumberVectorProperty *np) { if (PowerSP.s != IPS_OK) { if (!strcmp(np->label, "")) IDMessage (mydev, "Cannot change property %s while the wheel is offline.", np->name); else IDMessage (mydev, "Cannot change property %s while the wheel is offline.", np->label); np->s = IPS_IDLE; IDSetNumber(np, NULL); return -1; } return 0; } int checkPowerT(ITextVectorProperty *tp) { if (PowerSP.s != IPS_OK) { if (!strcmp(tp->label, "")) IDMessage (mydev, "Cannot change property %s while the wheel is offline.", tp->name); else IDMessage (mydev, "Cannot change property %s while the wheel is offline.", tp->label); tp->s = IPS_IDLE; IDSetText(tp, NULL); return -1; } return 0; } void connectFilter() { int err; char errmsg[ERRMSG_SIZE]; switch (PowerS[0].s) { case ISS_ON: if ( (err = tty_connect(PortT[0].text, 9600, 8, 0, 1, &fd)) != TTY_OK) { PowerSP.s = IPS_ALERT; IDSetSwitch(&PowerSP, "Error: cannot connect to %s. Make sure the filter is connected and you have access to the port.", PortT[0].text); tty_error_msg(err, errmsg, ERRMSG_SIZE); IDLog("Error: %s\n", errmsg); return; } PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "Filter Wheel is online. True Technology filter wheel suffers from several bugs. Please refer to http://indi.sf.net/profiles/trutech.html for more details."); break; case ISS_OFF: if ( (err = tty_disconnect(fd)) != TTY_OK) { PowerSP.s = IPS_ALERT; IDSetSwitch(&PowerSP, "Error: cannot disconnect."); tty_error_msg(err, errmsg, ERRMSG_SIZE); IDLog("Error: %s\n", errmsg); return; } PowerSP.s = IPS_IDLE; IDSetSwitch(&PowerSP, "Filter Wheel is offline."); break; } } /* isFilterConnected: return 1 if we have a connection, 0 otherwise */ int isFilterConnected(void) { return ((PowerS[0].s == ISS_ON) ? 1 : 0); } indi-0.5/src/lx200classic.cpp0000644000175000017500000002246010610474326013622 0ustar jrjr/* LX200 Classoc Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "lx200classic.h" #include "lx200driver.h" extern LX200Generic *telescope; extern INumberVectorProperty eqNum; extern ITextVectorProperty Time; extern int MaxReticleFlashRate; #define BASIC_GROUP "Main Control" #define LIBRARY_GROUP "Library" #define MOVE_GROUP "Movement Control" static IText ObjectText[] = {{"objectText", "Info", 0, 0, 0, 0}}; static ITextVectorProperty ObjectInfo = {mydev, "Object Info", "", BASIC_GROUP, IP_RO, 0, IPS_IDLE, ObjectText, NARRAY(ObjectText), "", 0}; /* Library group */ static ISwitch StarCatalogS[] = {{"STAR", "", ISS_ON, 0, 0}, {"SAO", "", ISS_OFF, 0, 0}, {"GCVS", "", ISS_OFF, 0, 0}}; static ISwitch DeepSkyCatalogS[] = {{"NGC", "", ISS_ON, 0, 0}, {"IC", "", ISS_OFF, 0, 0}, {"UGC", "", ISS_OFF, 0, 0}, {"Caldwell", "", ISS_OFF, 0, 0}, {"Arp", "", ISS_OFF, 0, 0}, {"Abell", "", ISS_OFF, 0, 0}, {"Messier", "", ISS_OFF, 0, 0}}; static ISwitch SolarS[] = { {"Select", "Select item...", ISS_ON, 0, 0}, {"1", "Mercury", ISS_OFF,0 , 0}, {"2", "Venus", ISS_OFF, 0, 0}, {"3", "Moon", ISS_OFF, 0, 0}, {"4", "Mars", ISS_OFF, 0, 0}, {"5", "Jupiter", ISS_OFF, 0, 0}, {"6", "Saturn", ISS_OFF, 0, 0}, {"7", "Uranus", ISS_OFF, 0, 0}, {"8", "Neptune", ISS_OFF, 0, 0}, {"9", "Pluto", ISS_OFF, 0 ,0}}; static ISwitchVectorProperty StarCatalogSw = { mydev, "Star Catalogs", "", LIBRARY_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, StarCatalogS, NARRAY(StarCatalogS), "", 0}; static ISwitchVectorProperty DeepSkyCatalogSw= { mydev, "Deep Sky Catalogs", "", LIBRARY_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, DeepSkyCatalogS, NARRAY(DeepSkyCatalogS), "", 0}; static ISwitchVectorProperty SolarSw = { mydev, "SOLAR_SYSTEM", "Solar System", LIBRARY_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, SolarS, NARRAY(SolarS), "", 0}; static INumber ObjectN[] = {{ "ObjectN", "Number", "%g", 1., 10000., 1., 0., 0, 0, 0}}; static INumberVectorProperty ObjectNo= { mydev, "Object Number", "", LIBRARY_GROUP, IP_RW, 0, IPS_IDLE, ObjectN, NARRAY(ObjectN), "", 0 }; static INumber MaxSlew[] = {{"maxSlew", "Rate", "%g", 2.0, 9.0, 1.0, 9., 0, 0 ,0}}; static INumberVectorProperty MaxSlewRate = { mydev, "Max slew Rate", "", MOVE_GROUP, IP_RW, 0, IPS_IDLE, MaxSlew, NARRAY(MaxSlew), "", 0}; static INumber altLimit[] = { {"minAlt", "min Alt", "%+03f", -90., 90., 0., 0., 0, 0, 0}, {"maxAlt", "max Alt", "%+03f", -90., 90., 0., 0., 0, 0, 0}}; static INumberVectorProperty elevationLimit = { mydev, "altLimit", "Slew elevation Limit", BASIC_GROUP, IP_RW, 0, IPS_IDLE, altLimit, NARRAY(altLimit), "", 0}; void changeLX200ClassicDeviceName(const char *newName) { strcpy(ObjectInfo.device, newName); strcpy(SolarSw.device, newName); strcpy(StarCatalogSw.device, newName); strcpy(DeepSkyCatalogSw.device, newName); strcpy(ObjectNo.device, newName); strcpy(MaxSlewRate.device , newName ); strcpy(elevationLimit.device , newName ); } LX200Classic::LX200Classic() : LX200Generic() { ObjectInfo.tp[0].text = new char[128]; strcpy(ObjectInfo.tp[0].text, ""); currentCatalog = LX200_STAR_C; currentSubCatalog = 0; } void LX200Classic::ISGetProperties (const char *dev) { if (dev && strcmp (thisDevice, dev)) return; LX200Generic::ISGetProperties(dev); IDDefNumber (&elevationLimit, NULL); IDDefText (&ObjectInfo, NULL); IDDefSwitch (&SolarSw, NULL); IDDefSwitch (&StarCatalogSw, NULL); IDDefSwitch (&DeepSkyCatalogSw, NULL); IDDefNumber (&ObjectNo, NULL); IDDefNumber (&MaxSlewRate, NULL); } void LX200Classic::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { // ignore if not ours // if (strcmp (dev, thisDevice)) return; LX200Generic::ISNewText (dev, name, texts, names, n); } void LX200Classic::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { int err=0; // ignore if not ours // if (strcmp (dev, thisDevice)) return; if ( !strcmp (name, ObjectNo.name) ) { if (checkPower(&ObjectNo)) return; selectCatalogObject(fd, currentCatalog, (int) values[0]); getLX200RA(fd, &eqNum.np[0].value); getLX200DEC(fd, &eqNum.np[1].value); ObjectNo.s = eqNum.s = IPS_OK; IDSetNumber(&ObjectNo , "Object updated"); IDSetNumber(&eqNum, NULL); if (getObjectInfo(fd, ObjectText[0].text) < 0) IDMessage(thisDevice, "Getting object info failed."); else IDSetText (&ObjectInfo, NULL); handleCoordSet(); return; } if ( !strcmp (name, MaxSlewRate.name) ) { if (checkPower(&MaxSlewRate)) return; if ( ( err = setMaxSlewRate(fd, (int) values[0]) < 0) ) { handleError(&MaxSlewRate, err, "Setting maximum slew rate"); return; } MaxSlewRate.s = IPS_OK; MaxSlewRate.np[0].value = values[0]; IDSetNumber(&MaxSlewRate, NULL); return; } if (!strcmp (name, elevationLimit.name)) { // new elevation limits double minAlt = 0, maxAlt = 0; int i, nset; if (checkPower(&elevationLimit)) return; for (nset = i = 0; i < n; i++) { INumber *altp = IUFindNumber (&elevationLimit, names[i]); if (altp == &altLimit[0]) { minAlt = values[i]; nset += minAlt >= -90.0 && minAlt <= 90.0; } else if (altp == &altLimit[1]) { maxAlt = values[i]; nset += maxAlt >= -90.0 && maxAlt <= 90.0; } } if (nset == 2) { //char l[32], L[32]; if ( ( err = setMinElevationLimit(fd, (int) minAlt) < 0) ) { handleError(&elevationLimit, err, "Setting elevation limit"); } setMaxElevationLimit(fd, (int) maxAlt); elevationLimit.np[0].value = minAlt; elevationLimit.np[1].value = maxAlt; elevationLimit.s = IPS_OK; IDSetNumber (&elevationLimit, NULL); } else { elevationLimit.s = IPS_IDLE; IDSetNumber(&elevationLimit, "elevation limit missing or invalid"); } return; } LX200Generic::ISNewNumber (dev, name, values, names, n); } void LX200Classic::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { int index=0; // ignore if not ours // if (strcmp (dev, thisDevice)) return; // Star Catalog if (!strcmp (name, StarCatalogSw.name)) { if (checkPower(&StarCatalogSw)) return; IUResetSwitches(&StarCatalogSw); IUUpdateSwitches(&StarCatalogSw, states, names, n); index = getOnSwitch(&StarCatalogSw); currentCatalog = LX200_STAR_C; if (selectSubCatalog(fd, currentCatalog, index)) { currentSubCatalog = index; StarCatalogSw.s = IPS_OK; IDSetSwitch(&StarCatalogSw, NULL); } else { StarCatalogSw.s = IPS_IDLE; IDSetSwitch(&StarCatalogSw, "Catalog unavailable"); } return; } // Deep sky catalog if (!strcmp (name, DeepSkyCatalogSw.name)) { if (checkPower(&DeepSkyCatalogSw)) return; IUResetSwitches(&DeepSkyCatalogSw); IUUpdateSwitches(&DeepSkyCatalogSw, states, names, n); index = getOnSwitch(&DeepSkyCatalogSw); if (index == LX200_MESSIER_C) { currentCatalog = index; DeepSkyCatalogSw.s = IPS_OK; IDSetSwitch(&DeepSkyCatalogSw, NULL); return; } else currentCatalog = LX200_DEEPSKY_C; if (selectSubCatalog(fd, currentCatalog, index)) { currentSubCatalog = index; DeepSkyCatalogSw.s = IPS_OK; IDSetSwitch(&DeepSkyCatalogSw, NULL); } else { DeepSkyCatalogSw.s = IPS_IDLE; IDSetSwitch(&DeepSkyCatalogSw, "Catalog unavailable"); } return; } // Solar system if (!strcmp (name, SolarSw.name)) { if (checkPower(&SolarSw)) return; IUResetSwitches(&SolarSw); IUUpdateSwitches(&SolarSw, states, names, n); index = getOnSwitch(&SolarSw); // We ignore the first option : "Select item" if (index == 0) { SolarSw.s = IPS_IDLE; IDSetSwitch(&SolarSw, NULL); return; } selectSubCatalog (fd, LX200_STAR_C, LX200_STAR); selectCatalogObject(fd, LX200_STAR_C, index + 900); ObjectNo.s = IPS_OK; SolarSw.s = IPS_OK; getObjectInfo(fd, ObjectInfo.tp[0].text); IDSetNumber(&ObjectNo , "Object updated."); IDSetSwitch(&SolarSw, NULL); if (currentCatalog == LX200_STAR_C || currentCatalog == LX200_DEEPSKY_C) selectSubCatalog(fd, currentCatalog, currentSubCatalog); getObjectRA(fd, &targetRA); getObjectDEC(fd, &targetDEC); handleCoordSet(); return; } LX200Generic::ISNewSwitch (dev, name, states, names, n); } void LX200Classic::ISPoll () { LX200Generic::ISPoll(); } void LX200Classic::getBasicData() { // process parent first LX200Generic::getBasicData(); } indi-0.5/src/stvdriver.h0000644000175000017500000002011110610474336013100 0ustar jrjr#if 0 STV driver Copyright (C) 2006 Markus Wildi, markus.wildi@datacomm.ch This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301 USA #endif #define OFF 0 #define ON 1 #define REQUEST_DOWNLOAD 0x00 #define REQUEST_DOWNLOAD_ALL 0x01 #define DOWNLOAD_COMPLETE 0x02 #define REQUEST_BUFFER_STATUS 0x03 #define REQUEST_IMAGE_INFO 0x04 #define REQUEST_IMAGE_DATA 0x05 #define ACK 0x06 #define REQUEST_COMPRESSED_IMAGE_DATA 0x07 #define SEND_KEY_PATTERN 0x08 #define DISPLAY_ECHO 0x09 #define FILE_STATUS 0x0b #define REQUEST_ACK 0x10 #define NACK 0x15 /* Rotary Knob Key Patterns */ #define LR_ROTARY_DECREASE_PATTERN 0x8000 #define LR_ROTARY_INCREASE_PATTERN 0x4000 #define UD_ROTARY_DECREASE_PATTERN 0x2000 #define UD_ROTARY_INCREASE_PATTERN 0x1000 #define SHIFT_PATTERN 0x0008 /* increases rotary speed when 1 */ /* Mode Key Patterns */ #define CAL_KEY_PATTERN 0x0100 #define TRACK_KEY_PATTERN 0x0200 #define DISPLAY_KEY_PATTERN 0x0400 #define FILEOPS_KEY_PATTERN 0x0800 #define A_KEY_PATTERN 0x0010 #define SETUP_KEY_PATTERN 0x0020 #define B_KEY_PATTERN 0x0040 #define INT_KEY_PATTERN 0x0080 #define FOCUS_KEY_PATTERN 0x0001 #define IMAGE_KEY_PATTERN 0x0002 #define MONITOR_KEY_PATTERN 0x0004 /* The following bit masks have been take from Sbig's documentation */ #define ID_BITS_MASK 0x0001 /* mask for no bits*/ #define ID_BITS_10 0x0001 /* image is full 10 bits*/ #define ID_BITS_8 0x0000 /* image from focus, only 8 bits*/ #define ID_UNITS_MASK 0x0002 /* mask for units for scope*/ #define ID_UNITS_INCHES 0x0002 /* units were inches*/ #define ID_UNITS_CM 0x0000 /* units were cm*/ #define ID_SCOPE_MASK 0x0004 /* mask for telescope type*/ #define ID_SCOPE_REFRACTOR 0x0004 /* scope was refractor*/ #define ID_SCOPE_REFLECTOR 0x0000 /* scope was reflector*/ #define ID_DATETIME_MASK 0x0008 /* mask for date/time valid*/ #define ID_DATETIME_VALID 0x0008 /* date/time was set*/ #define ID_DATETIME_INVALID 0x0000 /* date/time was not set*/ #define ID_BIN_MASK 0x0030 /* mask for binning mode*/ #define ID_BIN_1X1 0x0010 /* binning was 1x1*/ #define ID_BIN_2X2 0x0020 /* binning was 2x2*/ #define ID_BIN_3X3 0x0030 /* binning was 3x3*/ #define ID_PM_MASK 0x0400 /* mask for am/pm in time*/ #define ID_PM_PM 0x0400 /* time was pm, add 12 hours*/ #define ID_PM_AM 0x0000 /* time was am, don;t add 12 hours*/ #define ID_FILTER_MASK 0x0800 /* mask for filter status*/ #define ID_FILTER_LUNAR 0x0800 /* lunar filter was used for image*/ #define ID_FILTER_NP 0x0000 /* no filter was used for image*/ #define ID_DARKSUB_MASK 0x1000 /* mask for dark subtraction*/ #define ID_DARKSUB_YES 0x1000 /* image was dark subtracted*/ #define ID_DARKSUB_NO 0x0000 /* image was not dark subtracted*/ #define ID_MOSAIC_MASK 0x6000 /* mask for mosaic status*/ #define ID_MOSAIC_NONE 0x0000 /* no mosaic, one image per frame*/ #define ID_MOSAIC_SMALL 0x2000 /* small mosaic: 40x40 pixels/image*/ #define ID_MOSAIC_LARGE 0x4000 /* large mosaic: 106x100 pixels/image*/ /* IMAGE_INFO - data for the image Notes: height - 0 or 0xFFFF if no data present exposure - 100-60000 = 1.00 - 600 secs by 0.01 60001-60999 = 0.001 - 0.999 secs by 0.001 packedDate - bits 6-0 = year - 1999 (0 -127) bits 11-7 = day ( 1-31) bits 15-12 = month (1-12) packedTime - bits 6-0 = seconds (0-59) bits 7-12 = minutes (0-59) bits 15-13 = hours mod 12 (0-11) + bit in descriptor can add 12 */ typedef struct { unsigned int descriptor ; /* set of bits*/ unsigned int height, width; /* image sze */ unsigned int top, left ; /* position in buffer */ double exposure ; /* exposure time */ unsigned int noExposure ; /* number of exposures added */ unsigned int analogGain ; /*analog gain */ int digitalGain ; /* digital gain */ unsigned int focalLength ; /*focal length of telescope */ unsigned int aperture ; /* aperture diameter */ unsigned int packedDate ; /* date of image */ unsigned int year ; unsigned int month ; unsigned int day ; unsigned int packedTime ; /* time of image */ unsigned int seconds ; /* time of image */ unsigned int minutes ; /* time of image */ unsigned int hours ; /* time of image */ double ccdTemp ; /* temperature of ccd in 1/100 deg C */ unsigned int siteID; /* site id */ unsigned int eGain ; /* eGain in 1/100th e/ADU */ unsigned int background ; /* background for display */ unsigned int range ; /* range for display */ unsigned int pedestal ; /* Track and Accumulate pedestal */ unsigned int ccdTop, ccdLeft ; /* position of pixels on CCD array */ unsigned int adcResolution ; /* value, 8 or 10 bits */ unsigned int units ; /* 0= cm, 1=inch */ unsigned int telescopeType ; /* 0=refractor, 1= reflector */ unsigned int dateTimeValid ; /* 0= valid */ unsigned int binning ; /* 1x1=1, 2x2=2, 3x3=3 */ unsigned int filterStatus ; /* 0= no filter, 1= lunar filter */ unsigned int darkFrameSuntracted ; /* 0= no, 1= yes */ unsigned int imageIsMosaic ; /* 0=no, 1=40x40 pixels, 2=106x100 pixels */ double pixelSize ; /* 7.4 um */ double minValue ; /* Pixel Contents */ double maxValue ; } IMAGE_INFO ; /* * $Id: serial.h 49 2006-08-25 18:07:14Z lukas $ * * Copyright (C) 2006, Lukas Zimmermann, Basel, Switzerland. * * 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, 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. Or visit http://www.gnu.org/licenses/gpl.html. */ #ifndef __serial_h__ #define __serial_h__ #define PARITY_NONE 0 #define PARITY_EVEN 1 #define PARITY_ODD 2 typedef unsigned char byte; /* define byte type */ /* Restores terminal settings of open serial port device and close the file. */ void shutdown_serial(int fd); /* Opens and initializes a serial device and returns it's file descriptor. */ int init_serial(char *device_name, int bit_rate, int word_size, int parity, int stop_bits); /* Calculates the 16 bit CRC of an array of bytes and returns it. */ unsigned int calc_crc(byte byte_array[], int size); #endif /*#ifndef __serial_h__*/ indi-0.5/src/v4ldriver.cpp0000644000175000017500000005341710610474326013342 0ustar jrjr#if 0 V4L INDI Driver INDI Interface for V4L devices Copyright (C) 2003-2005 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include "v4ldriver.h" V4L_Driver::V4L_Driver() { V4LFrame = (img_t *) malloc (sizeof(img_t)); if (V4LFrame == NULL) { IDMessage(NULL, "Error: unable to initialize driver. Low memory."); IDLog("Error: unable to initialize driver. Low memory."); return; } camNameT[0].text = NULL; PortT[0].text = NULL; IUSaveText(&PortT[0], "/dev/video0"); divider = 128.; } V4L_Driver::~V4L_Driver() { free (V4LFrame); } void V4L_Driver::initProperties(const char *dev) { strncpy(device_name, dev, MAXINDIDEVICE); /* Connection */ IUFillSwitch(&PowerS[0], "CONNECT", "Connect", ISS_OFF); IUFillSwitch(&PowerS[1], "DISCONNECT", "Disconnect", ISS_ON); IUFillSwitchVector(&PowerSP, PowerS, NARRAY(PowerS), dev, "CONNECTION", "Connection", COMM_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE); /* Port */ IUFillText(&PortT[0], "PORT", "Port", "/dev/video0"); IUFillTextVector(&PortTP, PortT, NARRAY(PortT), dev, "DEVICE_PORT", "Ports", COMM_GROUP, IP_RW, 0, IPS_IDLE); /* Video Stream */ IUFillSwitch(&StreamS[0], "ON", "", ISS_OFF); IUFillSwitch(&StreamS[1], "OFF", "", ISS_ON); IUFillSwitchVector(&StreamSP, StreamS, NARRAY(StreamS), dev, "VIDEO_STREAM", "Video Stream", COMM_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE); /* Compression */ IUFillSwitch(&CompressS[0], "ON", "", ISS_ON); IUFillSwitch(&CompressS[1], "OFF", "", ISS_OFF); IUFillSwitchVector(&CompressSP, CompressS, NARRAY(StreamS), dev, "Compression", "", IMAGE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE); /* Image type */ IUFillSwitch(&ImageTypeS[0], "Grey", "", ISS_ON); IUFillSwitch(&ImageTypeS[1], "Color", "", ISS_OFF); IUFillSwitchVector(&ImageTypeSP, ImageTypeS, NARRAY(ImageTypeS), dev, "Image Type", "", IMAGE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE); /* Camera Name */ IUFillText(&camNameT[0], "Model", "", ""); IUFillTextVector(&camNameTP, camNameT, NARRAY(camNameT), dev, "Camera Model", "", COMM_GROUP, IP_RO, 0, IPS_IDLE); /* Expose */ IUFillNumber(&ExposeTimeN[0], "EXPOSE_DURATION", "Duration (s)", "%5.2f", 0., 36000., 0.5, 1.); IUFillNumberVector(&ExposeTimeNP, ExposeTimeN, NARRAY(ExposeTimeN), dev, "CCD_EXPOSE_DURATION", "Expose", COMM_GROUP, IP_RW, 60, IPS_IDLE); /* Frame Rate */ IUFillNumber(&FrameRateN[0], "RATE", "Rate", "%0.f", 1., 50., 1., 10.); IUFillNumberVector(&FrameRateNP, FrameRateN, NARRAY(FrameRateN), dev, "FRAME_RATE", "Frame Rate", COMM_GROUP, IP_RW, 60, IPS_IDLE); /* Frame dimension */ IUFillNumber(&FrameN[0], "X", "X", "%.0f", 0., 0., 0., 0.); IUFillNumber(&FrameN[1], "Y", "Y", "%.0f", 0., 0., 0., 0.); IUFillNumber(&FrameN[2], "WIDTH", "Width", "%.0f", 0., 0., 10., 0.); IUFillNumber(&FrameN[3], "HEIGHT", "Height", "%.0f", 0., 0., 10., 0.); IUFillNumberVector(&FrameNP, FrameN, NARRAY(FrameN), dev, "CCD_FRAME", "Frame", IMAGE_GROUP, IP_RW, 60, IPS_IDLE); /*IUFillNumber(&ImageSizeN[0], "WIDTH", "Width", "%0.f", 0., 0., 10., 0.); IUFillNumber(&ImageSizeN[1], "HEIGHT", "Height", "%0.f", 0., 0., 10., 0.); IUFillNumberVector(&ImageSizeNP, ImageSizeN, NARRAY(ImageSizeN), dev, "IMAGE_SIZE", "Image Size", IMAGE_GROUP, IP_RW, 60, IPS_IDLE);*/ #ifndef HAVE_LINUX_VIDEODEV2_H IUFillNumber(&ImageAdjustN[0], "Contrast", "", "%0.f", 0., 256., 1., 0.); IUFillNumber(&ImageAdjustN[1], "Brightness", "", "%0.f", 0., 256., 1., 0.); IUFillNumber(&ImageAdjustN[2], "Hue", "", "%0.f", 0., 256., 1., 0.); IUFillNumber(&ImageAdjustN[3], "Color", "", "%0.f", 0., 256., 1., 0.); IUFillNumber(&ImageAdjustN[4], "Whiteness", "", "%0.f", 0., 256., 1., 0.); IUFillNumberVector(&ImageAdjustNP, ImageAdjustN, NARRAY(ImageAdjustN), dev, "Image Adjustments", "", IMAGE_GROUP, IP_RW, 60, IPS_IDLE); #else IUFillNumberVector(&ImageAdjustNP, NULL, 0, dev, "Image Adjustments", "", IMAGE_GROUP, IP_RW, 60, IPS_IDLE); #endif // We need to setup the BLOB (Binary Large Object) below. Using this property, we can send FITS to our client strcpy(imageB.name, "CCD1"); strcpy(imageB.label, "Feed"); strcpy(imageB.format, ""); imageB.blob = 0; imageB.bloblen = 0; imageB.size = 0; imageB.bvp = 0; imageB.aux0 = 0; imageB.aux1 = 0; imageB.aux2 = 0; strcpy(imageBP.device, dev); strcpy(imageBP.name, "Video"); strcpy(imageBP.label, "Video"); strcpy(imageBP.group, COMM_GROUP); strcpy(imageBP.timestamp, ""); imageBP.p = IP_RO; imageBP.timeout = 0; imageBP.s = IPS_IDLE; imageBP.bp = &imageB; imageBP.nbp = 1; imageBP.aux = 0; } void V4L_Driver::initCamBase() { #ifndef HAVE_LINUX_VIDEODEV2_H v4l_base = new V4L1_Base(); #else v4l_base = new V4L2_Base(); #endif } void V4L_Driver::ISGetProperties (const char *dev) { if (dev && strcmp (device_name, dev)) return; /* COMM_GROUP */ IDDefSwitch(&PowerSP, NULL); IDDefText(&PortTP, NULL); IDDefText(&camNameTP, NULL); IDDefSwitch(&StreamSP, NULL); #ifndef HAVE_LINUX_VIDEODEV2_H IDDefNumber(&FrameRateNP, NULL); #endif IDDefNumber(&ExposeTimeNP, NULL); IDDefBLOB(&imageBP, NULL); /* Image properties */ IDDefSwitch(&CompressSP, NULL); IDDefSwitch(&ImageTypeSP, NULL); IDDefNumber(&FrameNP, NULL); #ifndef HAVE_LINUX_VIDEODEV2_H IDDefNumber(&ImageAdjustNP, NULL); #endif } void V4L_Driver::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { char errmsg[ERRMSGSIZ]; /* ignore if not ours */ if (dev && strcmp (device_name, dev)) return; /* Connection */ if (!strcmp (name, PowerSP.name)) { IUResetSwitches(&PowerSP); IUUpdateSwitches(&PowerSP, states, names, n); connectCamera(); return; } /* Compression */ if (!strcmp(name, CompressSP.name)) { IUResetSwitches(&CompressSP); IUUpdateSwitches(&CompressSP, states, names, n); CompressSP.s = IPS_OK; IDSetSwitch(&CompressSP, NULL); return; } /* Image Type */ if (!strcmp(name, ImageTypeSP.name)) { IUResetSwitches(&ImageTypeSP); IUUpdateSwitches(&ImageTypeSP, states, names, n); ImageTypeSP.s = IPS_OK; IDSetSwitch(&ImageTypeSP, NULL); return; } /* Video Stream */ if (!strcmp(name, StreamSP.name)) { if (checkPowerS(&StreamSP)) return; IUResetSwitches(&StreamSP); IUUpdateSwitches(&StreamSP, states, names, n); StreamSP.s = IPS_IDLE; if (StreamS[0].s == ISS_ON) { frameCount = 0; IDLog("Starting the video stream.\n"); StreamSP.s = IPS_BUSY; v4l_base->start_capturing(errmsg); } else { IDLog("The video stream has been disabled. Frame count %d\n", frameCount); v4l_base->stop_capturing(errmsg); } IDSetSwitch(&StreamSP, NULL); return; } } void V4L_Driver::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int /*n*/) { IText *tp; /* ignore if not ours */ if (dev && strcmp (device_name, dev)) return; if (!strcmp(name, PortTP.name) ) { PortTP.s = IPS_OK; tp = IUFindText( &PortTP, names[0] ); if (!tp) return; IUSaveText(tp, texts[0]); IDSetText (&PortTP, NULL); return; } } void V4L_Driver::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { char errmsg[ERRMSGSIZ]; /* ignore if not ours */ if (dev && strcmp (device_name, dev)) return; /* Frame Size */ if (!strcmp (FrameNP.name, name)) { if (checkPowerN(&FrameNP)) return; int oldW = (int) FrameN[2].value; int oldH = (int) FrameN[3].value; FrameNP.s = IPS_OK; if (IUUpdateNumbers(&FrameNP, values, names, n) < 0) return; if (v4l_base->setSize( (int) FrameN[2].value, (int) FrameN[3].value) != -1) { FrameN[2].value = v4l_base->getWidth(); FrameN[3].value = v4l_base->getHeight(); V4LFrame->width = (int) FrameN[2].value; V4LFrame->height= (int) FrameN[3].value; IDSetNumber(&FrameNP, NULL); return; } else { FrameN[2].value = oldW; FrameN[3].value = oldH; FrameNP.s = IPS_ALERT; IDSetNumber(&FrameNP, "Failed to set a new image size."); } return; } #ifndef HAVE_LINUX_VIDEODEV2_H /* Frame rate */ if (!strcmp (FrameRateNP.name, name)) { if (checkPowerN(&FrameRateNP)) return; FrameRateNP.s = IPS_IDLE; if (IUUpdateNumbers(&FrameRateNP, values, names, n) < 0) return; v4l_base->setFPS( (int) FrameRateN[0].value ); FrameRateNP.s = IPS_OK; IDSetNumber(&FrameRateNP, NULL); return; } #endif if (!strcmp (ImageAdjustNP.name, name)) { if (checkPowerN(&ImageAdjustNP)) return; ImageAdjustNP.s = IPS_IDLE; if (IUUpdateNumbers(&ImageAdjustNP, values, names, n) < 0) return; #ifndef HAVE_LINUX_VIDEODEV2_H v4l_base->setContrast( (int) (ImageAdjustN[0].value * divider)); v4l_base->setBrightness( (int) (ImageAdjustN[1].value * divider)); v4l_base->setHue( (int) (ImageAdjustN[2].value * divider)); v4l_base->setColor( (int) (ImageAdjustN[3].value * divider)); v4l_base->setWhiteness( (int) (ImageAdjustN[4].value * divider)); ImageAdjustN[0].value = v4l_base->getContrast() / divider; ImageAdjustN[1].value = v4l_base->getBrightness() / divider; ImageAdjustN[2].value = v4l_base->getHue() / divider; ImageAdjustN[3].value = v4l_base->getColor() / divider; ImageAdjustN[4].value = v4l_base->getWhiteness() / divider; #else unsigned int ctrl_id; for (int i=0; i < ImageAdjustNP.nnp; i++) { ctrl_id = *((unsigned int *) ImageAdjustNP.np[i].aux0); if (v4l_base->setINTControl( ctrl_id , ImageAdjustNP.np[i].value, errmsg) < 0) { ImageAdjustNP.s = IPS_ALERT; IDSetNumber(&ImageAdjustNP, "Unable to adjust setting. %s", errmsg); return; } } #endif ImageAdjustNP.s = IPS_OK; IDSetNumber(&ImageAdjustNP, NULL); return; } /* Exposure */ if (!strcmp (ExposeTimeNP.name, name)) { if (checkPowerN(&ExposeTimeNP)) return; if (StreamS[0].s == ISS_ON) v4l_base->stop_capturing(errmsg); StreamS[0].s = ISS_OFF; StreamS[1].s = ISS_ON; StreamSP.s = IPS_IDLE; IDSetSwitch(&StreamSP, NULL); V4LFrame->expose = 1000; ExposeTimeNP.s = IPS_BUSY; IDSetNumber(&ExposeTimeNP, NULL); time(&capture_start); v4l_base->start_capturing(errmsg); return; } } void V4L_Driver::newFrame(void *p) { ((V4L_Driver *) (p))->updateFrame(); } void V4L_Driver::updateFrame() { char errmsg[ERRMSGSIZ]; static int dropLarge = 5; if (StreamSP.s == IPS_BUSY) { frameCount++; // Drop some frames /*if (FrameN[2].value > 160) {* FIXME find an optimal solution to drop frame rates */ dropLarge--; if (dropLarge == 0) { dropLarge = (int) (5.0 * (FrameN[2].value / 160.0)); updateStream(); return; } } else if (ExposeTimeNP.s == IPS_BUSY) { V4LFrame->Y = v4l_base->getY(); v4l_base->stop_capturing(errmsg); time(&capture_end); IDLog("Capture of ONE frame took %g seconds.\n", difftime(capture_end, capture_start)); grabImage(); } } void V4L_Driver::updateStream() { int width = v4l_base->getWidth(); int height = v4l_base->getHeight(); uLongf compressedBytes = 0; uLong totalBytes; unsigned char *targetFrame; int r; if (PowerS[0].s == ISS_OFF || StreamS[0].s == ISS_OFF) return; if (ImageTypeS[0].s == ISS_ON) V4LFrame->Y = v4l_base->getY(); else V4LFrame->colorBuffer = v4l_base->getColorBuffer(); totalBytes = ImageTypeS[0].s == ISS_ON ? width * height : width * height * 4; targetFrame = ImageTypeS[0].s == ISS_ON ? V4LFrame->Y : V4LFrame->colorBuffer; /* Do we want to compress ? */ if (CompressS[0].s == ISS_ON) { /* Compress frame */ V4LFrame->compressedFrame = (unsigned char *) realloc (V4LFrame->compressedFrame, sizeof(unsigned char) * totalBytes + totalBytes / 64 + 16 + 3); compressedBytes = sizeof(unsigned char) * totalBytes + totalBytes / 64 + 16 + 3; r = compress2(V4LFrame->compressedFrame, &compressedBytes, targetFrame, totalBytes, 4); if (r != Z_OK) { /* this should NEVER happen */ IDLog("internal error - compression failed: %d\n", r); return; } /* #3.A Send it compressed */ imageB.blob = V4LFrame->compressedFrame; imageB.bloblen = compressedBytes; imageB.size = totalBytes; strcpy(imageB.format, ".stream.z"); } else { /* #3.B Send it uncompressed */ imageB.blob = targetFrame; imageB.bloblen = totalBytes; imageB.size = totalBytes; strcpy(imageB.format, ".stream"); } imageBP.s = IPS_OK; IDSetBLOB (&imageBP, NULL); #ifndef HAVE_LINUX_VIDEODEV2_H char errmsg[ERRMSGSIZ]; v4l_base->start_capturing(errmsg); #endif } /* Downloads the image from the CCD row by row and store them in a raw file. N.B. No processing is done on the image */ int V4L_Driver::grabImage() { int err, fd; char errmsg[ERRMSG_SIZE]; char temp_filename[TEMPFILE_LEN] = "/tmp/fitsXXXXXX"; if ((fd = mkstemp(temp_filename)) < 0) { IDMessage(device_name, "Error making temporary filename."); IDLog("Error making temporary filename.\n"); return -1; } close(fd); err = writeFITS(temp_filename, errmsg); if (err) { IDMessage(device_name, errmsg, NULL); return -1; } return 0; } int V4L_Driver::writeFITS(const char * filename, char errmsg[]) { fitsfile *fptr; /* pointer to the FITS file; defined in fitsio.h */ int status; long fpixel = 1, naxis = 2, nelements; long naxes[2]; char filename_rw[TEMPFILE_LEN+1]; // Append ! to file name to over write it. snprintf(filename_rw, TEMPFILE_LEN+1, "!%s", filename); naxes[0] = v4l_base->getWidth(); naxes[1] = v4l_base->getHeight(); status = 0; /* initialize status before calling fitsio routines */ fits_create_file(&fptr, filename_rw, &status); /* create new file */ /* Create the primary array image (16-bit short integer pixels */ fits_create_img(fptr, BYTE_IMG, naxis, naxes, &status); addFITSKeywords(fptr); nelements = naxes[0] * naxes[1]; /* number of pixels to write */ /* Write the array of integers to the image */ fits_write_img(fptr, TBYTE, fpixel, nelements, V4LFrame->Y, &status); fits_close_file(fptr, &status); /* close the file */ fits_report_error(stderr, status); /* print out any error messages */ /* Success */ ExposeTimeNP.s = IPS_OK; IDSetNumber(&ExposeTimeNP, NULL); uploadFile(filename); unlink(filename); return status; } void V4L_Driver::addFITSKeywords(fitsfile *fptr) { int status=0; fits_update_key(fptr, TLONG, "EXPOSURE", &(V4LFrame->expose), "Total Exposure Time (ms)", &status); fits_update_key(fptr, TSTRING, "INSTRUME", v4l_base->getDeviceName(), "Webcam Name", &status); fits_write_date(fptr, &status); } void V4L_Driver::uploadFile(const char * filename) { FILE * fitsFile; unsigned char *fitsData; int r=0; unsigned int nr = 0; uLong totalBytes; uLongf compressedBytes = 0; struct stat stat_p; if ( -1 == stat (filename, &stat_p)) { IDLog(" Error occurred attempting to stat %s\n", filename); return; } totalBytes = stat_p.st_size; fitsFile = fopen(filename, "r"); if (fitsFile == NULL) return; fitsData = new unsigned char[totalBytes]; /* #1 Read file from disk */ for (unsigned int i=0; i < totalBytes; i+= nr) { nr = fread(fitsData + i, 1, totalBytes - i, fitsFile); if (nr <= 0) { IDLog("Error reading temporary FITS file.\n"); return; } } fclose(fitsFile); if (CompressS[0].s == ISS_ON) { /* #2 Compress it */ V4LFrame->compressedFrame = (unsigned char *) realloc (V4LFrame->compressedFrame, sizeof(unsigned char) * totalBytes + totalBytes / 64 + 16 + 3); compressedBytes = sizeof(unsigned char) * totalBytes + totalBytes / 64 + 16 + 3; r = compress2(V4LFrame->compressedFrame, &compressedBytes, fitsData, totalBytes, 9); if (r != Z_OK) { /* this should NEVER happen */ IDLog("internal error - compression failed: %d\n", r); return; } /* #3.A Send it compressed */ imageB.blob = V4LFrame->compressedFrame; imageB.bloblen = compressedBytes; imageB.size = totalBytes; strcpy(imageB.format, ".fits.z"); } else { imageB.blob = fitsData; imageB.bloblen = totalBytes; imageB.size = totalBytes; strcpy(imageB.format, ".fits"); } imageBP.s = IPS_OK; IDSetBLOB (&imageBP, NULL); delete [] fitsData; } void V4L_Driver::connectCamera() { char errmsg[ERRMSGSIZ]; switch (PowerS[0].s) { case ISS_ON: if (v4l_base->connectCam(PortT[0].text, errmsg) < 0) { PowerSP.s = IPS_IDLE; PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch(&PowerSP, "Error: unable to open device"); IDLog("Error: %s\n", errmsg); return; } /* Sucess! */ PowerS[0].s = ISS_ON; PowerS[1].s = ISS_OFF; PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "Video4Linux Generic Device is online. Retrieving basic data."); v4l_base->registerCallback(newFrame, this); V4LFrame->compressedFrame = (unsigned char *) malloc (sizeof(unsigned char) * 1); IDLog("V4L Device is online. Retrieving basic data.\n"); getBasicData(); break; case ISS_OFF: PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_IDLE; free(V4LFrame->compressedFrame); V4LFrame->compressedFrame = NULL; v4l_base->disconnectCam(); IDSetSwitch(&PowerSP, "Video4Linux Generic Device is offline."); break; } } /* Retrieves basic data from the device upon connection.*/ void V4L_Driver::getBasicData() { int xmax, ymax, xmin, ymin; v4l_base->getMaxMinSize(xmax, ymax, xmin, ymin); /* Width */ FrameN[2].value = v4l_base->getWidth(); FrameN[2].min = xmin; FrameN[2].max = xmax; V4LFrame->width = (int) FrameN[2].value; /* Height */ FrameN[3].value = v4l_base->getHeight(); FrameN[3].min = ymin; FrameN[3].max = ymax; V4LFrame->height = (int) FrameN[3].value; IUUpdateMinMax(&FrameNP); IDSetNumber(&FrameNP, NULL); IUSaveText(&camNameT[0], v4l_base->getDeviceName()); IDSetText(&camNameTP, NULL); #ifndef HAVE_LINUX_VIDEODEV2_H updateV4L1Controls(); #else updateV4L2Controls(); #endif } #ifdef HAVE_LINUX_VIDEODEV2_H void V4L_Driver::updateV4L2Controls() { // #1 Query for INTEGER controls, and fill up the structure free(ImageAdjustNP.np); ImageAdjustNP.nnp = 0; if (v4l_base->queryINTControls(&ImageAdjustNP) > 0) IDDefNumber(&ImageAdjustNP, NULL); } #else void V4L_Driver::updateV4L1Controls() { if ( (v4l_base->getContrast() / divider) > ImageAdjustN[0].max) divider *=2; if ( (v4l_base->getHue() / divider) > ImageAdjustN[2].max) divider *=2; ImageAdjustN[0].value = v4l_base->getContrast() / divider; ImageAdjustN[1].value = v4l_base->getBrightness() / divider; ImageAdjustN[2].value = v4l_base->getHue() / divider; ImageAdjustN[3].value = v4l_base->getColor() / divider; ImageAdjustN[4].value = v4l_base->getWhiteness() / divider; ImageAdjustNP.s = IPS_OK; IDSetNumber(&ImageAdjustNP, NULL); } #endif int V4L_Driver::checkPowerS(ISwitchVectorProperty *sp) { if (PowerSP.s != IPS_OK) { if (!strcmp(sp->label, "")) IDMessage (device_name, "Cannot change property %s while the camera is offline.", sp->name); else IDMessage (device_name, "Cannot change property %s while the camera is offline.", sp->label); sp->s = IPS_IDLE; IDSetSwitch(sp, NULL); return -1; } return 0; } int V4L_Driver::checkPowerN(INumberVectorProperty *np) { if (PowerSP.s != IPS_OK) { if (!strcmp(np->label, "")) IDMessage (device_name, "Cannot change property %s while the camera is offline.", np->name); else IDMessage (device_name, "Cannot change property %s while the camera is offline.", np->label); np->s = IPS_IDLE; IDSetNumber(np, NULL); return -1; } return 0; } int V4L_Driver::checkPowerT(ITextVectorProperty *tp) { if (PowerSP.s != IPS_OK) { if (!strcmp(tp->label, "")) IDMessage (device_name, "Cannot change property %s while the camera is offline.", tp->name); else IDMessage (device_name, "Cannot change property %s while the camera is offline.", tp->label); tp->s = IPS_IDLE; IDSetText(tp, NULL); return -1; } return 0; } indi-0.5/src/fq.h0000644000175000017500000000225410610474336011466 0ustar jrjr/* a fifo queue that never fills. * Copyright (C) 2005 Elwood C. Downey ecdowney@clearskyinstitute.com This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ typedef struct _FQ FQ; extern FQ *newFQ(int grow); extern void delFQ (FQ *q); extern void pushFQ (FQ *q, void *e); extern void *popFQ (FQ *q); extern void *peekFQ (FQ *q); extern int nFQ (FQ *q); extern void setMemFuncsFQ (void *(*newmalloc)(size_t size), void *(*newrealloc)(void *ptr, size_t size), void (*newfree)(void *ptr)); indi-0.5/src/celestrongps.h0000644000175000017500000000357510610474336013577 0ustar jrjr/* Celestron GPS Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef CELESTRONGPS_H #define CELESTRONGPS_H #include "indidevapi.h" #include "indicom.h" #define POLLMS 1000 /* poll period, ms */ class CelestronGPS { public: CelestronGPS(); virtual ~CelestronGPS() {} virtual void ISGetProperties (const char *dev); virtual void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); virtual void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n); virtual void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); virtual void ISPoll (); virtual void getBasicData(); int checkPower(INumberVectorProperty *np); int checkPower(ISwitchVectorProperty *sp); int checkPower(ITextVectorProperty *tp); void connectTelescope(); void slewError(int slewCode); int handleCoordSet(); int getOnSwitch(ISwitchVectorProperty *sp); private: int timeFormat; double JD; double currentRA; double currentDEC; double targetRA; double targetDEC; double lastRA; double lastDEC; int lastSet; int currentSet; }; #endif indi-0.5/src/lx200gps.cpp0000644000175000017500000002347310610474326012777 0ustar jrjr/* LX200 GPS Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "lx200gps.h" #include "lx200driver.h" #define GPSGroup "Extended GPS Features" extern LX200Generic *telescope; extern int MaxReticleFlashRate; static ISwitch GPSPowerS[] = {{ "On", "", ISS_OFF, 0, 0}, {"Off", "", ISS_ON, 0, 0}}; static ISwitch GPSStatusS[] = {{ "Sleep", "", ISS_OFF, 0, 0}, {"Wake up", "", ISS_OFF, 0 ,0}, {"Restart", "", ISS_OFF, 0, 0}}; static ISwitch GPSUpdateS[] = { {"Update GPS", "", ISS_OFF, 0, 0}, {"Update Client", "", ISS_OFF, 0, 0}}; static ISwitch AltDecPecS[] = {{ "Enable", "", ISS_OFF, 0 ,0}, {"Disable", "", ISS_OFF, 0 ,0}}; static ISwitch AzRaPecS[] = {{ "Enable", "", ISS_OFF, 0, 0}, {"Disable", "", ISS_OFF, 0 ,0}}; static ISwitch SelenSyncS[] = {{ "Sync", "", ISS_OFF, 0, 0}}; static ISwitch AltDecBackSlashS[] = {{ "Activate", "", ISS_OFF, 0, 0}}; static ISwitch AzRaBackSlashS[] = {{ "Activate", "", ISS_OFF, 0, 0}}; static ISwitch OTAUpdateS[] = {{ "Update", "", ISS_OFF, 0, 0}}; static ISwitchVectorProperty GPSPowerSw = { mydev, "GPS Power", "", GPSGroup, IP_RW, ISR_1OFMANY, 0 , IPS_IDLE, GPSPowerS, NARRAY(GPSPowerS), "", 0}; static ISwitchVectorProperty GPSStatusSw = { mydev, "GPS Status", "", GPSGroup, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, GPSStatusS, NARRAY(GPSStatusS), "", 0}; static ISwitchVectorProperty GPSUpdateSw = { mydev, "GPS System", "", GPSGroup, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, GPSUpdateS, NARRAY(GPSUpdateS), "", 0}; static ISwitchVectorProperty AltDecPecSw = { mydev, "Alt/Dec PEC", "", GPSGroup, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, AltDecPecS, NARRAY(AltDecPecS), "", 0}; static ISwitchVectorProperty AzRaPecSw = { mydev, "Az/Ra PEC", "", GPSGroup, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, AzRaPecS, NARRAY(AzRaPecS), "", 0}; static ISwitchVectorProperty SelenSyncSw = { mydev, "Selenographic Sync", "", GPSGroup, IP_RW, ISR_ATMOST1, 0, IPS_IDLE, SelenSyncS, NARRAY(SelenSyncS), "", 0}; static ISwitchVectorProperty AltDecBackSlashSw = { mydev, "Alt/Dec Anti-backslash", "", GPSGroup, IP_RW, ISR_ATMOST1, 0, IPS_IDLE, AltDecBackSlashS, NARRAY(AltDecBackSlashS), "", 0}; static ISwitchVectorProperty AzRaBackSlashSw = { mydev, "Az/Ra Anti-backslash", "", GPSGroup, IP_RW, ISR_ATMOST1, 0, IPS_IDLE, AzRaBackSlashS, NARRAY(AzRaBackSlashS), "", 0}; static ISwitchVectorProperty OTAUpdateSw = { mydev, "OTA Update", "", GPSGroup, IP_RW, ISR_ATMOST1, 0, IPS_IDLE, OTAUpdateS, NARRAY(OTAUpdateS), "", 0}; static INumber Temp[] = { {"Temp.", "", "%g", -200., 500., 0., 0., 0, 0, 0 } }; static INumberVectorProperty OTATemp = { mydev, "OTA Temperature (C)", "", GPSGroup, IP_RO, 0, IPS_IDLE, Temp, NARRAY(Temp), "", 0}; void updateTemp(void *p); void changeLX200GPSDeviceName(const char *newName) { strcpy(GPSPowerSw.device, newName); strcpy(GPSStatusSw.device, newName ); strcpy(GPSUpdateSw.device, newName ); strcpy(AltDecPecSw.device, newName ); strcpy(AzRaPecSw.device,newName ); strcpy(SelenSyncSw.device, newName ); strcpy(AltDecBackSlashSw.device, newName ); strcpy(AzRaBackSlashSw.device, newName ); strcpy(OTATemp.device, newName ); strcpy(OTAUpdateSw.device, newName); } LX200GPS::LX200GPS() : LX200_16() { IEAddTimer(900000, updateTemp, &fd); } void LX200GPS::ISGetProperties (const char *dev) { if (dev && strcmp (thisDevice, dev)) return; // process parent first LX200_16::ISGetProperties(dev); IDDefSwitch (&GPSPowerSw, NULL); IDDefSwitch (&GPSStatusSw, NULL); IDDefSwitch (&GPSUpdateSw, NULL); IDDefSwitch (&AltDecPecSw, NULL); IDDefSwitch (&AzRaPecSw, NULL); IDDefSwitch (&SelenSyncSw, NULL); IDDefSwitch (&AltDecBackSlashSw, NULL); IDDefSwitch (&AzRaBackSlashSw, NULL); IDDefNumber (&OTATemp, NULL); IDDefSwitch (&OTAUpdateSw, NULL); } void LX200GPS::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { // ignore if not ours // if (strcmp (dev, thisDevice)) return; LX200_16::ISNewText (dev, name, texts, names, n); } void LX200GPS::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { LX200_16::ISNewNumber (dev, name, values, names, n); } void LX200GPS::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { int index; char msg[64]; if (strcmp (dev, thisDevice)) return; /* GPS Power */ if (!strcmp(name,GPSPowerSw.name)) { if (checkPower(&GPSPowerSw)) return; if (IUUpdateSwitches(&GPSPowerSw, states, names, n) < 0) return; index = getOnSwitch(&GPSPowerSw); index == 0 ? turnGPSOn(fd) : turnGPSOff(fd); GPSPowerSw.s = IPS_OK; IDSetSwitch (&GPSPowerSw, index == 0 ? "GPS System is ON" : "GPS System is OFF" ); return; } /* GPS Status Update */ if (!strcmp(name,GPSStatusSw.name)) { if (checkPower(&GPSStatusSw)) return; if (IUUpdateSwitches(&GPSStatusSw, states, names, n) < 0) return; index = getOnSwitch(&GPSStatusSw); if (index == 0) { gpsSleep(fd); strcpy(msg, "GPS system is in sleep mode."); } else if (index == 1) { gpsWakeUp(fd); strcpy(msg, "GPS system is reactivated."); } else { gpsRestart(fd); strcpy(msg, "GPS system is restarting..."); updateTime(); updateLocation(); } GPSStatusSw.s = IPS_OK; IDSetSwitch (&GPSStatusSw, "%s", msg); return; } /* GPS Update */ if (!strcmp(name,GPSUpdateSw.name)) { if (checkPower(&GPSUpdateSw)) return; if (IUUpdateSwitches(&GPSUpdateSw, states, names, n) < 0) return; index = getOnSwitch(&GPSUpdateSw); GPSUpdateSw.s = IPS_OK; if (index == 0) { IDSetSwitch(&GPSUpdateSw, "Updating GPS system. This operation might take few minutes to complete..."); if (updateGPS_System(fd)) { IDSetSwitch(&GPSUpdateSw, "GPS system update successful."); updateTime(); updateLocation(); } else { GPSUpdateSw.s = IPS_IDLE; IDSetSwitch(&GPSUpdateSw, "GPS system update failed."); } } else { updateTime(); updateLocation(); IDSetSwitch(&GPSUpdateSw, "Client time and location is synced to LX200 GPS Data."); } return; } /* Alt Dec Periodic Error correction */ if (!strcmp(name, AltDecPecSw.name)) { if (checkPower(&AltDecPecSw)) return; if (IUUpdateSwitches(&AltDecPecSw, states, names, n) < 0) return; index = getOnSwitch(&AltDecPecSw); if (index == 0) { enableDecAltPec(fd); strcpy (msg, "Alt/Dec Compensation Enabled"); } else { disableDecAltPec(fd); strcpy (msg, "Alt/Dec Compensation Disabled"); } AltDecPecSw.s = IPS_OK; IDSetSwitch(&AltDecPecSw, "%s", msg); return; } /* Az RA periodic error correction */ if (!strcmp(name, AzRaPecSw.name)) { if (checkPower(&AzRaPecSw)) return; if (IUUpdateSwitches(&AzRaPecSw, states, names, n) < 0) return; index = getOnSwitch(&AzRaPecSw); if (index == 0) { enableRaAzPec(fd); strcpy (msg, "Ra/Az Compensation Enabled"); } else { disableRaAzPec(fd); strcpy (msg, "Ra/Az Compensation Disabled"); } AzRaPecSw.s = IPS_OK; IDSetSwitch(&AzRaPecSw, "%s", msg); return; } if (!strcmp(name, AltDecBackSlashSw.name)) { if (checkPower(&AltDecBackSlashSw)) return; activateAltDecAntiBackSlash(fd); AltDecBackSlashSw.s = IPS_OK; IDSetSwitch(&AltDecBackSlashSw, "Alt/Dec Anti-backslash enabled"); return; } if (!strcmp(name, AzRaBackSlashSw.name)) { if (checkPower(&AzRaBackSlashSw)) return; activateAzRaAntiBackSlash(fd); AzRaBackSlashSw.s = IPS_OK; IDSetSwitch(&AzRaBackSlashSw, "Az/Ra Anti-backslash enabled"); return; } if (!strcmp(name, OTAUpdateSw.name)) { int error_type=0; if (checkPower(&OTAUpdateSw)) return; IUResetSwitches(&OTAUpdateSw); if ( (error_type = getOTATemp(fd, &OTATemp.np[0].value)) < 0) { OTAUpdateSw.s = IPS_ALERT; OTATemp.s = IPS_ALERT; IDSetNumber(&OTATemp, "Error: OTA temperature read timed out."); } else { OTAUpdateSw.s = IPS_OK; OTATemp.s = IPS_OK; IDSetNumber(&OTATemp, NULL); } return; } LX200_16::ISNewSwitch (dev, name, states, names, n); } void LX200GPS::ISPoll () { LX200_16::ISPoll(); } void updateTemp(void * p) { int fd = *((int *) p); if (telescope->isTelescopeOn()) { if (getOTATemp(fd, &OTATemp.np[0].value) < 0) { OTATemp.s = IPS_ALERT; IDSetNumber(&OTATemp, "Error: OTA temperature read timed out."); return; } else { OTATemp.s = IPS_OK; IDSetNumber(&OTATemp, NULL); } } IEAddTimer(900000, updateTemp, &fd); } void LX200GPS::getBasicData() { //getOTATemp(&OTATemp.np[0].value); //IDSetNumber(&OTATemp, NULL); // process parent LX200_16::getBasicData(); } indi-0.5/src/sbig_dummy.cpp0000644000175000017500000000200110610474326013537 0ustar jrjr#if 0 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif #include "sbigudrv.h" /* JM: Dummy SBIG Universal Driver. The real one is proprietary */ short KDE_EXPORT SBIGUnivDrvCommand(short command, void *Params, void *Results) { command=command; Params=Params; Results=Results; return CE_FAKE_DRIVER; } indi-0.5/src/fli_pdf.c0000644000175000017500000003612110610474331012451 0ustar jrjr#if 0 FLI Precision Digital Focuer Copyright (C) 2005 Jasem Mutlaq (mutlaqja AT ikarustech DOT com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fli/libfli.h" #include "indidevapi.h" #include "eventloop.h" #include "indicom.h" void ISInit(void); void getBasicData(void); void ISPoll(void *); void handleExposure(void *); void connectPDF(void); int findPDF(flidomain_t domain); int manageDefaults(char errmsg[]); int checkPowerS(ISwitchVectorProperty *sp); int checkPowerN(INumberVectorProperty *np); int checkPowerT(ITextVectorProperty *tp); int getOnSwitch(ISwitchVectorProperty *sp); int isPDFConnected(void); double min(void); double max(void); extern char* me; extern int errno; #define mydev "FLI PDF" #define MAIN_GROUP "Main Control" #define currentPosition FocuserN[0].value #define POLLMS 1000 typedef struct { flidomain_t domain; char *dname; char *name; char *model; long HWRevision; long FWRevision; long current_pos; long home; } pdf_t; static flidev_t fli_dev; static pdf_t *FLIPDF; static int portSwitchIndex; static int simulation; static long targetPosition; long int Domains[] = { FLIDOMAIN_USB, FLIDOMAIN_SERIAL, FLIDOMAIN_PARALLEL_PORT, FLIDOMAIN_INET }; /*INDI controls */ /* Connect/Disconnect */ static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}}; static ISwitchVectorProperty PowerSP = { mydev, "CONNECTION" , "Connection", MAIN_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0}; /* Types of Ports */ static ISwitch PortS[] = {{"USB", "", ISS_ON, 0, 0}, {"Serial", "", ISS_OFF, 0, 0}, {"Parallel", "", ISS_OFF, 0, 0}, {"INet", "", ISS_OFF, 0, 0}}; static ISwitchVectorProperty PortSP = { mydev, "Port Type", "", MAIN_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, PortS, NARRAY(PortS), "", 0}; /* Focuser control */ static INumber FocuserN[] = { {"Position", "", "%2.0f", -10000., 10000., 1., 0, 0, 0, 0}}; static INumberVectorProperty FocuserNP = { mydev, "Focuser", "", MAIN_GROUP, IP_RW, 0, IPS_IDLE, FocuserN, NARRAY(FocuserN), "", 0}; /* Focuser home */ static ISwitch HomeS[] = { {"Home", "", ISS_OFF, 0, 0} }; static ISwitchVectorProperty HomeSP = { mydev, "Home", "", MAIN_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, HomeS, NARRAY(HomeS), "", 0}; /* send client definitions of all properties */ void ISInit() { static int isInit=0; if (isInit) return; /* USB by default {USB, SERIAL, PARALLEL, INET} */ portSwitchIndex = 0; targetPosition = 0; /* No Simulation by default */ simulation = 0; /* Enable the following for simulation mode */ /*simulation = 1; IDLog("WARNING: Simulation is on\n");*/ IEAddTimer (POLLMS, ISPoll, NULL); isInit = 1; } void ISGetProperties (const char *dev) { ISInit(); if (dev && strcmp (mydev, dev)) return; /* Main Control */ IDDefSwitch(&PowerSP, NULL); IDDefSwitch(&PortSP, NULL); IDDefSwitch(&HomeSP, NULL); IDDefNumber(&FocuserNP, NULL); } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n) { dev=dev;name=name;sizes=sizes;blobs=blobs;formats=formats;names=names;n=n; } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { long err=0; /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; ISInit(); /* Port type */ if (!strcmp (name, PortSP.name)) { PortSP.s = IPS_IDLE; IUResetSwitches(&PortSP); IUUpdateSwitches(&PortSP, states, names, n); portSwitchIndex = getOnSwitch(&PortSP); PortSP.s = IPS_OK; IDSetSwitch(&PortSP, NULL); return; } /* Connection */ if (!strcmp (name, PowerSP.name)) { IUResetSwitches(&PowerSP); IUUpdateSwitches(&PowerSP, states, names, n); connectPDF(); return; } if (!strcmp(name, HomeSP.name)) { if (!isPDFConnected()) { IDMessage(mydev, "Device not connected."); HomeSP.s = IPS_IDLE; IDSetSwitch(&HomeSP, NULL); return; } if ( (err = FLIHomeFocuser(fli_dev))) { HomeSP.s = IPS_ALERT; IDSetSwitch(&HomeSP, "FLIHomeFocuser() failed. %s.", strerror((int)-err)); IDLog("FLIHomeFocuser() failed. %s.\n", strerror((int)-err)); return; } HomeSP.s = IPS_OK; IDSetSwitch(&HomeSP, "Focuser at home position."); IDLog("Focuser at home position.\n"); return; } } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { ISInit(); /* ignore if not ours */ if (dev && strcmp (mydev, dev)) return; /* suppress warning */ n=n; dev=dev; name=name; names=names; texts=texts; } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { long err; long newPos; names=names; n = n; /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; ISInit(); if (!strcmp(FocuserNP.name, name)) { if (simulation) { targetPosition = values[0]; FocuserNP.s = IPS_BUSY; IDSetNumber(&FocuserNP, "Setting focuser position to %ld", targetPosition); IDLog("Setting focuser position to %ld", targetPosition); return; } if (!isPDFConnected()) { IDMessage(mydev, "Device not connected."); FocuserNP.s = IPS_IDLE; IDSetNumber(&FocuserNP, NULL); return; } targetPosition = values[0]; FocuserNP.s = IPS_BUSY; IDSetNumber(&FocuserNP, "Setting focuser position to %ld", targetPosition); IDLog("Setting focuser position to %ld\n", targetPosition); if ( (err = FLIStepMotor(fli_dev, targetPosition))) { FocuserNP.s = IPS_ALERT; IDSetNumber(&FocuserNP, "FLIStepMotor() failed. %s.", strerror((int)-err)); IDLog("FLIStepMotor() failed. %s.", strerror((int)-err)); return; } /* Check current focuser position */ if (( err = FLIGetStepperPosition(fli_dev, &newPos))) { FocuserNP.s = IPS_ALERT; IDSetNumber(&FocuserNP, "FLIGetStepperPosition() failed. %s.", strerror((int)-err)); IDLog("FLIGetStepperPosition() failed. %s.\n", strerror((int)-err)); return; } if (newPos == targetPosition) { FLIPDF->current_pos = targetPosition; currentPosition = FLIPDF->current_pos; FocuserNP.s = IPS_OK; IDSetNumber(&FocuserNP, "Focuser position %ld", targetPosition); return; } return; } } /* Retrieves basic data from the focuser upon connection like temperature, array size, firmware..etc */ void getBasicData() { char buff[2048]; long err; if ((err = FLIGetModel (fli_dev, buff, 2048))) { IDMessage(mydev, "FLIGetModel() failed. %s.", strerror((int)-err)); IDLog("FLIGetModel() failed. %s.\n", strerror((int)-err)); return; } else { if ( (FLIPDF->model = malloc (sizeof(char) * 2048)) == NULL) { IDMessage(mydev, "malloc() failed."); IDLog("malloc() failed."); return; } strcpy(FLIPDF->model, buff); } if (( err = FLIGetHWRevision(fli_dev, &FLIPDF->HWRevision))) { IDMessage(mydev, "FLIGetHWRevision() failed. %s.", strerror((int)-err)); IDLog("FLIGetHWRevision() failed. %s.\n", strerror((int)-err)); return; } if (( err = FLIGetFWRevision(fli_dev, &FLIPDF->FWRevision))) { IDMessage(mydev, "FLIGetFWRevision() failed. %s.", strerror((int)-err)); IDLog("FLIGetFWRevision() failed. %s.\n", strerror((int)-err)); return; } if (( err = FLIGetStepperPosition(fli_dev, &FLIPDF->current_pos))) { IDSetNumber(&FocuserNP, "FLIGetStepperPosition() failed. %s.", strerror((int)-err)); IDLog("FLIGetStepperPosition() failed. %s.\n", strerror((int)-err)); return; } currentPosition = FLIPDF->current_pos; IDLog("Model: %s\n", FLIPDF->model); IDLog("HW Revision %ld\n", FLIPDF->HWRevision); IDLog("FW Revision %ld\n", FLIPDF->FWRevision); IDLog("Initial focuser position %ld\n", FLIPDF->current_pos); FocuserNP.s = IPS_OK; IDSetNumber(&FocuserNP, NULL); IDLog("Exiting getBasicData()\n"); } void ISPoll(void *p) { static int simMTC = 5; p=p; if (!isPDFConnected()) { IEAddTimer (POLLMS, ISPoll, NULL); return; } switch (FocuserNP.s) { case IPS_IDLE: case IPS_OK: break; case IPS_BUSY: /* Simulate that it takes 5 seconds to change positoin*/ if (simulation) { simMTC--; if (simMTC == 0) { simMTC = 5; currentPosition = targetPosition; FocuserNP.s = IPS_OK; IDSetNumber(&FocuserNP, "Focuser position %ld", targetPosition); break; } IDSetNumber(&FocuserNP, NULL); break; } /*if (( err = FLIGetFilterPos(fli_dev, ¤tFilter))) { FocuserNP.s = IPS_ALERT; IDSetNumber(&FocuserNP, "FLIGetFilterPos() failed. %s.", strerror((int)-err)); IDLog("FLIGetFilterPos() failed. %s.\n", strerror((int)-err)); return; } if (targetPosition == currentFilter) { FLIPDF->current_filter = currentFilter; FocuserNP.s = IPS_OK; IDSetNumber(&FocuserNP, "Filter set to slot #%2.0f", currentFilter); return; } IDSetNumber(&FocuserNP, NULL);*/ break; case IPS_ALERT: break; } IEAddTimer (POLLMS, ISPoll, NULL); } int getOnSwitch(ISwitchVectorProperty *sp) { int i=0; for (i=0; i < sp->nsp ; i++) { /*IDLog("Switch %s is %s\n", sp->sp[i].name, sp->sp[i].s == ISS_ON ? "On" : "Off");*/ if (sp->sp[i].s == ISS_ON) return i; } return -1; } int checkPowerS(ISwitchVectorProperty *sp) { if (simulation) return 0; if (PowerSP.s != IPS_OK) { if (!strcmp(sp->label, "")) IDMessage (mydev, "Cannot change property %s while the focuser is offline.", sp->name); else IDMessage (mydev, "Cannot change property %s while the focuser is offline.", sp->label); sp->s = IPS_IDLE; IDSetSwitch(sp, NULL); return -1; } return 0; } int checkPowerN(INumberVectorProperty *np) { if (simulation) return 0; if (PowerSP.s != IPS_OK) { if (!strcmp(np->label, "")) IDMessage (mydev, "Cannot change property %s while the focuser is offline.", np->name); else IDMessage (mydev, "Cannot change property %s while the focuser is offline.", np->label); np->s = IPS_IDLE; IDSetNumber(np, NULL); return -1; } return 0; } int checkPowerT(ITextVectorProperty *tp) { if (simulation) return 0; if (PowerSP.s != IPS_OK) { if (!strcmp(tp->label, "")) IDMessage (mydev, "Cannot change property %s while the focuser is offline.", tp->name); else IDMessage (mydev, "Cannot change property %s while the focuser is offline.", tp->label); tp->s = IPS_IDLE; IDSetText(tp, NULL); return -1; } return 0; } void connectPDF() { long err; /* USB by default {USB, SERIAL, PARALLEL, INET} */ switch (PowerS[0].s) { case ISS_ON: if (simulation) { /* Success! */ PowerS[0].s = ISS_ON; PowerS[1].s = ISS_OFF; PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "Simulation PDF is online."); IDLog("Simulation PDF is online.\n"); return; } IDLog("Current portSwitch is %d\n", portSwitchIndex); IDLog("Attempting to find the device in domain %ld\n", Domains[portSwitchIndex]); if (findPDF(Domains[portSwitchIndex])) { PowerSP.s = IPS_IDLE; PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch(&PowerSP, "Error: no focusers were detected."); IDLog("Error: no focusers were detected.\n"); return; } if ((err = FLIOpen(&fli_dev, FLIPDF->name, FLIPDF->domain | FLIDEVICE_FOCUSER))) { PowerSP.s = IPS_IDLE; PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch(&PowerSP, "Error: FLIOpen() failed. %s.", strerror( (int) -err)); IDLog("Error: FLIOpen() failed. %s.\n", strerror( (int) -err)); return; } /* Success! */ PowerS[0].s = ISS_ON; PowerS[1].s = ISS_OFF; PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "Focuser is online. Retrieving basic data."); IDLog("Focuser is online. Retrieving basic data.\n"); getBasicData(); break; case ISS_OFF: if (simulation) { PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_IDLE; IDSetSwitch(&PowerSP, "Focuser is offline."); return; } PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_IDLE; if ((err = FLIClose(fli_dev))) { PowerSP.s = IPS_ALERT; IDSetSwitch(&PowerSP, "Error: FLIClose() failed. %s.", strerror( (int) -err)); IDLog("Error: FLIClose() failed. %s.\n", strerror( (int) -err)); return; } IDSetSwitch(&PowerSP, "Focuser is offline."); break; } } /* isPDFConnected: return 1 if we have a connection, 0 otherwise */ int isPDFConnected(void) { if (simulation) return 1; return ((PowerS[0].s == ISS_ON) ? 1 : 0); } int findPDF(flidomain_t domain) { char **devlist; long err; IDLog("In findPDF, the domain is %ld\n", domain); if (( err = FLIList(domain | FLIDEVICE_FOCUSER, &devlist))) { IDLog("FLIList() failed. %s\n", strerror((int)-err)); return -1; } if (devlist != NULL && devlist[0] != NULL) { int i; IDLog("Trying to allocate memory to FLIPDF\n"); if ((FLIPDF = malloc (sizeof (pdf_t))) == NULL) { IDLog("malloc() failed.\n"); return -1; } for (i = 0; devlist[i] != NULL; i++) { int j; for (j = 0; devlist[i][j] != '\0'; j++) if (devlist[i][j] == ';') { devlist[i][j] = '\0'; break; } } FLIPDF->domain = domain; /* Each driver handles _only_ one camera for now */ switch (domain) { case FLIDOMAIN_PARALLEL_PORT: FLIPDF->dname = strdup("parallel port"); break; case FLIDOMAIN_USB: FLIPDF->dname = strdup("USB"); break; case FLIDOMAIN_SERIAL: FLIPDF->dname = strdup("serial"); break; case FLIDOMAIN_INET: FLIPDF->dname = strdup("inet"); break; default: FLIPDF->dname = strdup("Unknown domain"); } IDLog("Domain set OK\n"); FLIPDF->name = strdup(devlist[0]); if ((err = FLIFreeList(devlist))) { IDLog("FLIFreeList() failed. %s.\n", strerror((int)-err)); return -1; } } /* end if */ else { if ((err = FLIFreeList(devlist))) { IDLog("FLIFreeList() failed. %s.\n", strerror((int)-err)); return -1; } return -1; } IDLog("FindPDF() finished successfully.\n"); return 0; } indi-0.5/src/intelliscope.c0000644000175000017500000001113210610474331013533 0ustar jrjr#if 0 Intelliscope INDI driver Copyright (C) 2005 Douglas Philipson (dougp AT intermind DOT net) Based on code by Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include "config.h" #include #include #include #include #include #include #include #include "indidevapi.h" #include "indicom.h" #include "lx200driver.h" #define mydev "Intelliscope" #define BASIC_GROUP "Main Control" #define POLLMS 1000 #define currentRA eq[0].value #define currentDEC eq[1].value static void ISPoll(void *); static void ISInit(void); static void connectTelescope(void); int fd; static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}}; ISwitchVectorProperty PowerSP = { mydev, "CONNECTION" , "Connection", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0}; static IText PortT[] = {{"PORT", "Port", 0, 0, 0, 0}}; static ITextVectorProperty PortTP = { mydev, "DEVICE_PORT", "Ports", BASIC_GROUP, IP_RW, 0, IPS_IDLE, PortT, NARRAY(PortT), "", 0}; /* equatorial position */ INumber eq[] = { {"RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0., 0, 0, 0}, {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}, }; INumberVectorProperty eqNum = { mydev, "EQUATORIAL_EOD_COORD", "Equatorial JNow", BASIC_GROUP, IP_RO, 0, IPS_IDLE, eq, NARRAY(eq), "", 0}; void ISInit(void) { static int isInit=0; if (isInit) return; isInit = 1; fd = -1; IEAddTimer (POLLMS, ISPoll, NULL); } void ISGetProperties (const char *dev) { ISInit(); dev=dev; IDDefSwitch(&PowerSP, NULL); IDDefText(&PortTP, NULL); IDDefNumber(&eqNum, NULL); } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { ISInit(); dev = dev; if (!strcmp(name, PowerSP.name)) { IUResetSwitches(&PowerSP); IUUpdateSwitches(&PowerSP, states, names, n); connectTelescope(); return; } } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { ISInit(); dev=dev; names=names; n=n; if (!strcmp(name, PortTP.name)) { IUSaveText(&PortT[0], texts[0]); PortTP.s = IPS_OK; IDSetText(&PortTP, NULL); return; } } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { dev=dev;name=name;values=values;names=names;n=n; } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n) { dev=dev;name=name;sizes=sizes;blobs=blobs;formats=formats;names=names;n=n; } void ISPoll (void *p) { p=p; if (PowerS[0].s == ISS_ON) { switch (eqNum.s) { case IPS_IDLE: case IPS_OK: case IPS_BUSY: if (updateIntelliscopeCoord(fd, ¤tRA, ¤tDEC) < 0) { eqNum.s = IPS_ALERT; IDSetNumber(&eqNum, "Unknown error while reading telescope coordinates"); IDLog("Unknown error while reading telescope coordinates\n"); break; } IDSetNumber(&eqNum, NULL); break; case IPS_ALERT: break; } } IEAddTimer(POLLMS, ISPoll, NULL); } void connectTelescope(void) { switch (PowerS[0].s) { case ISS_ON: if (tty_connect(PortT[0].text, 9600, 8, 0, 1, &fd) != TTY_OK) { PowerSP.s = IPS_ALERT; IUResetSwitches(&PowerSP); IDSetSwitch(&PowerSP, "Error connecting to port %s", PortT[0].text); return; } PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "Intelliscope is online."); break; case ISS_OFF: tty_disconnect(fd); IUResetSwitches(&PowerSP); eqNum.s = PortTP.s = PowerSP.s = IPS_IDLE; IDSetSwitch(&PowerSP, "Intelliscope is offline."); IDSetText(&PortTP, NULL); IDSetNumber(&eqNum, NULL); break; } } indi-0.5/src/sbigcam.cpp0000644000175000017500000026035010610474326013022 0ustar jrjr//========================================================================== #if 0 File name : sbigcam.cpp Driver type: SBIG CCD Camera INDI Driver Copyright (C) 2005-2006 Jan Soldan (jsoldan AT asu DOT cas DOT cz) 251 65 Ondrejov-236, Czech Republic Acknowledgement: Jasem Mutlaq (mutlaqja AT ikarustech DOT com) Matt Longmire (matto AT sbig DOT com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif //========================================================================== #include "sbigcam.h" using namespace std; //========================================================================== #ifdef INDI // We declare an auto pointer to SBIG CCD camera. auto_ptr sbig_cam(0); #endif //========================================================================== // Initialize variables. Here we create new instance of SbigCam class. //========================================================================== #ifdef INDI void ISInit() { if(sbig_cam.get() == 0) sbig_cam.reset(new SbigCam()); } #endif //========================================================================== // INDI will call this function is called when the client inquires about // the device properties. //========================================================================== #ifdef INDI void ISGetProperties(const char *dev) { if(dev && strcmp(DEVICE_NAME, dev)) return; ISInit(); sbig_cam->ISGetProperties(); } #endif //========================================================================== #ifdef INDI void ISNewSwitch( const char *dev, const char *name, ISState *states, char *names[], int num) { if(dev && strcmp (DEVICE_NAME, dev)) return; ISInit(); sbig_cam->ISNewSwitch(name, states, names, num); } #endif //========================================================================== #ifdef INDI void ISNewText( const char *dev, const char *name, char *texts[], char *names[], int num) { if(dev && strcmp (DEVICE_NAME, dev)) return; ISInit(); sbig_cam->ISNewText(name, texts, names, num); } #endif //========================================================================== #ifdef INDI void ISNewNumber( const char *dev, const char *name, double values[], char *names[], int num) { if(dev && strcmp (DEVICE_NAME, dev)) return; ISInit(); sbig_cam->ISNewNumber(name, values, names, num); } #endif //========================================================================== #ifdef INDI void ISNewBLOB( const char */*dev*/, const char */*name*/, int */*sizes[]*/, char ** /*blobs[]*/, char **/*formats[]*/, char **/*names[]*/, int /*num*/) { // We use this if we're receiving binary data from the client. // Most likely we won't for this driver. } #endif //========================================================================== SbigCam::SbigCam() { InitVars(); OpenDriver(); #ifdef INDI IEAddTimer(POLL_TEMPERATURE_MS, SbigCam::UpdateTemperature, this); IEAddTimer(POLL_EXPOSURE_MS, SbigCam::UpdateExposure, this); #endif } //========================================================================== SbigCam::SbigCam(const char* devName) { InitVars(); if(OpenDriver() == CE_NO_ERROR) OpenDevice(devName); #ifdef INDI IEAddTimer(POLL_TEMPERATURE_MS, SbigCam::UpdateTemperature, this); IEAddTimer(POLL_EXPOSURE_MS, SbigCam::UpdateExposure, this); #endif } //========================================================================== SbigCam::~SbigCam() { CloseDevice(); CloseDriver(); } //========================================================================== int SbigCam::OpenDriver() { int res; GetDriverHandleResults gdhr; SetDriverHandleParams sdhp; // Call the driver directly. if((res = SBIGUnivDrvCommand(CC_OPEN_DRIVER, 0, 0)) == CE_NO_ERROR){ // The driver was not open, so record the driver handle. res = SBIGUnivDrvCommand(CC_GET_DRIVER_HANDLE, 0, &gdhr); }else if(res == CE_DRIVER_NOT_CLOSED){ // The driver is already open which we interpret as having been // opened by another instance of the class so get the driver to // allocate a new handle and then record it. sdhp.handle = INVALID_HANDLE_VALUE; res = SBIGUnivDrvCommand(CC_SET_DRIVER_HANDLE, &sdhp, 0); if(res == CE_NO_ERROR){ if((res = SBIGUnivDrvCommand(CC_OPEN_DRIVER, 0, 0)) == CE_NO_ERROR){ res = SBIGUnivDrvCommand(CC_GET_DRIVER_HANDLE, 0, &gdhr); } } } if(res == CE_NO_ERROR) SetDriverHandle(gdhr.handle); return(res); } //========================================================================== int SbigCam::CloseDriver() { int res; if((res = SBIGUnivDrvCommand(CC_CLOSE_DRIVER, 0, 0)) == CE_NO_ERROR){ SetDriverHandle(); } return(res); } //========================================================================== int SbigCam::OpenDevice(const char *devName) { int res; OpenDeviceParams odp; // Check if device already opened: if(IsDeviceOpen()) return(CE_NO_ERROR); // Try to open new device: if(strcmp(devName, SBIG_USB0) == 0){ odp.deviceType = DEV_USB1; }else if(strcmp(devName, SBIG_USB1) == 0){ odp.deviceType = DEV_USB2; }else if(strcmp(devName, SBIG_USB2) == 0){ odp.deviceType = DEV_USB3; }else if(strcmp(devName, SBIG_USB3) == 0){ odp.deviceType = DEV_USB4; }else if(strcmp(devName, SBIG_LPT0) == 0){ odp.deviceType = DEV_LPT1; }else if(strcmp(devName, SBIG_LPT1) == 0){ odp.deviceType = DEV_LPT2; }else if(strcmp(devName, SBIG_LPT2) == 0){ odp.deviceType = DEV_LPT3; }else{ return(CE_BAD_PARAMETER); } if((res = SBIGUnivDrvCommand(CC_OPEN_DEVICE, &odp, 0)) == CE_NO_ERROR){ SetDeviceName(devName); SetFileDescriptor(true); } return(res); } //========================================================================== int SbigCam::CloseDevice() { int res = CE_NO_ERROR; if(IsDeviceOpen()){ if((res = SBIGUnivDrvCommand(CC_CLOSE_DEVICE, 0, 0)) == CE_NO_ERROR){ SetFileDescriptor(); // set value to -1 SetCameraType(); // set value to NO_CAMERA } } return(res); } //========================================================================= int SbigCam::GetDriverInfo(GetDriverInfoParams *gdip, void *res) { return(SBIGUnivDrvCommand(CC_GET_DRIVER_INFO, gdip, res)); } //========================================================================== int SbigCam::SetDriverHandle(SetDriverHandleParams *sdhp) { return(SBIGUnivDrvCommand(CC_SET_DRIVER_HANDLE, sdhp, 0)); } //========================================================================== int SbigCam::GetDriverHandle(GetDriverHandleResults *gdhr) { return(SBIGUnivDrvCommand(CC_GET_DRIVER_HANDLE, 0, gdhr)); } //========================================================================== int SbigCam::StartExposure(StartExposureParams *sep) { return(SBIGUnivDrvCommand(CC_START_EXPOSURE, sep, 0)); } //========================================================================== int SbigCam::EndExposure(EndExposureParams *eep) { return(SBIGUnivDrvCommand(CC_END_EXPOSURE, eep, 0)); } //========================================================================== int SbigCam::StartReadout(StartReadoutParams *srp) { return(SBIGUnivDrvCommand(CC_START_READOUT, srp, 0)); } //========================================================================== int SbigCam::ReadoutLine(ReadoutLineParams *rlp, unsigned short *results, bool bSubtract) { int res; if(bSubtract){ res = SBIGUnivDrvCommand(CC_READ_SUBTRACT_LINE, rlp, results); }else{ res = SBIGUnivDrvCommand(CC_READOUT_LINE, rlp, results); } return(res); } //========================================================================== int SbigCam::DumpLines(DumpLinesParams *dlp) { return(SBIGUnivDrvCommand(CC_DUMP_LINES, dlp, 0)); } //========================================================================== int SbigCam::EndReadout(EndReadoutParams *erp) { return(SBIGUnivDrvCommand(CC_END_READOUT, erp, 0)); } //========================================================================== int SbigCam::SetTemperatureRegulation(SetTemperatureRegulationParams *strp) { return(SBIGUnivDrvCommand(CC_SET_TEMPERATURE_REGULATION, strp, 0)); } //========================================================================== int SbigCam::SetTemperatureRegulation(double temperature, bool enable) { int res; SetTemperatureRegulationParams strp; if(CheckLink()){ strp.regulation = enable ? REGULATION_ON : REGULATION_OFF; strp.ccdSetpoint = CalcSetpoint(temperature); res = SBIGUnivDrvCommand(CC_SET_TEMPERATURE_REGULATION, &strp, 0); }else{ res = CE_DEVICE_NOT_OPEN; } return(res); } //========================================================================== int SbigCam::QueryTemperatureStatus( bool &enabled, double &ccdTemp, double &setpointTemp, double &power) { int res; QueryTemperatureStatusResults qtsr; if(CheckLink()){ res = SBIGUnivDrvCommand(CC_QUERY_TEMPERATURE_STATUS, 0, &qtsr); if(res == CE_NO_ERROR){ enabled = qtsr.enabled; ccdTemp = CalcTemperature(CCD_THERMISTOR, qtsr.ccdThermistor); setpointTemp = CalcTemperature(CCD_THERMISTOR, qtsr.ccdSetpoint); power = qtsr.power/255.0; } }else{ res = CE_DEVICE_NOT_OPEN; } return(res); } //========================================================================== unsigned short SbigCam::CalcSetpoint(double temperature) { // Calculate 'setpoint' from the temperature T in degr. of Celsius. double expo = (log(R_RATIO_CCD) * (T0 - temperature)) / DT_CCD; double r = R0 * exp(expo); return((unsigned short)(((MAX_AD / (R_BRIDGE_CCD / r + 1.0)) + 0.5))); } //========================================================================== double SbigCam::CalcTemperature(short thermistorType, short setpoint) { double r, expo, rBridge, rRatio, dt; switch(thermistorType){ case AMBIENT_THERMISTOR: rBridge = R_BRIDGE_AMBIENT; rRatio = R_RATIO_AMBIENT; dt = DT_AMBIENT; break; case CCD_THERMISTOR: default: rBridge = R_BRIDGE_CCD; rRatio = R_RATIO_CCD; dt = DT_CCD; break; } // Calculate temperature T in degr. Celsius from the 'setpoint' r = rBridge / ((MAX_AD / setpoint) - 1.0); expo = log(r / R0) / log(rRatio); return(T0 - dt * expo); } //========================================================================== int SbigCam::ActivateRelay(ActivateRelayParams *arp) { return(SBIGUnivDrvCommand(CC_ACTIVATE_RELAY, arp, 0)); } //========================================================================== int SbigCam::PulseOut(PulseOutParams *pop) { return(SBIGUnivDrvCommand(CC_PULSE_OUT, pop, 0)); } //========================================================================== int SbigCam::TxSerialBytes( TXSerialBytesParams *txsbp, TXSerialBytesResults *txsbr) { return(SBIGUnivDrvCommand(CC_TX_SERIAL_BYTES, txsbp, txsbr)); } //========================================================================== int SbigCam::GetSerialStatus(GetSerialStatusResults *gssr) { return(SBIGUnivDrvCommand(CC_GET_SERIAL_STATUS, 0, gssr)); } //========================================================================== int SbigCam::AoTipTilt(AOTipTiltParams *aottp) { return(SBIGUnivDrvCommand(CC_AO_TIP_TILT, aottp, 0)); } //========================================================================== int SbigCam::AoDelay(AODelayParams *aodp) { return(SBIGUnivDrvCommand(CC_AO_DELAY, aodp, 0)); } //========================================================================== int SbigCam::Cfw(CFWParams *cfwp, CFWResults *cfwr) { return(SBIGUnivDrvCommand(CC_CFW, cfwp, cfwr)); } //========================================================================== int SbigCam::EstablishLink() { int res; EstablishLinkParams elp; EstablishLinkResults elr; elp.sbigUseOnly = 0; if((res = SBIGUnivDrvCommand(CC_ESTABLISH_LINK, &elp, &elr)) == CE_NO_ERROR){ SetCameraType((CAMERA_TYPE)elr.cameraType); SetLinkStatus(true); } return(res); } //========================================================================== int SbigCam::GetCcdInfo(GetCCDInfoParams *gcp, void *gcr) { return(SBIGUnivDrvCommand(CC_GET_CCD_INFO, gcp, gcr)); } //========================================================================== int SbigCam::GetCcdSizeInfo( int ccd, int binning, int &frmW, int &frmH, double &pixW, double &pixH) { int res; GetCCDInfoParams gcp; GetCCDInfoResults0 gcr; gcp.request = ccd; res = SBIGUnivDrvCommand(CC_GET_CCD_INFO, &gcp, &gcr); if(res == CE_NO_ERROR){ frmW = gcr.readoutInfo[binning].width; frmH = gcr.readoutInfo[binning].height; pixW = BcdPixel2double(gcr.readoutInfo[binning].pixelWidth); pixH = BcdPixel2double(gcr.readoutInfo[binning].pixelHeight); } return(res); } //========================================================================== int SbigCam::QueryCommandStatus( QueryCommandStatusParams *qcsp, QueryCommandStatusResults *qcsr) { return(SBIGUnivDrvCommand(CC_QUERY_COMMAND_STATUS, qcsp, qcsr)); } //========================================================================== int SbigCam::MiscellaneousControl(MiscellaneousControlParams *mcp) { return(SBIGUnivDrvCommand(CC_MISCELLANEOUS_CONTROL, mcp, 0)); } //========================================================================== int SbigCam::ReadOffset(ReadOffsetParams *rop, ReadOffsetResults *ror) { return(SBIGUnivDrvCommand(CC_READ_OFFSET, rop, ror)); } //========================================================================== int SbigCam::GetLinkStatus(GetLinkStatusResults *glsr) { return(SBIGUnivDrvCommand(CC_GET_LINK_STATUS, glsr, 0)); } //========================================================================== string SbigCam::GetErrorString(int err) { int res; GetErrorStringParams gesp; GetErrorStringResults gesr; gesp.errorNo = err; res = SBIGUnivDrvCommand(CC_GET_ERROR_STRING, &gesp, &gesr); if(res == CE_NO_ERROR) return(string(gesr.errorString)); char str [128]; sprintf(str, "No error string found! Error code: %d", err); return(string(str)); } //========================================================================== int SbigCam::SetDriverControl(SetDriverControlParams *sdcp) { return(SBIGUnivDrvCommand(CC_SET_DRIVER_CONTROL, sdcp, 0)); } //========================================================================== int SbigCam::GetDriverControl( GetDriverControlParams *gdcp, GetDriverControlResults *gdcr) { return(SBIGUnivDrvCommand(CC_GET_DRIVER_CONTROL, gdcp, gdcr)); } //========================================================================== int SbigCam::UsbAdControl(USBADControlParams *usbadcp) { return(SBIGUnivDrvCommand(CC_USB_AD_CONTROL, usbadcp, 0)); } //========================================================================== int SbigCam::QueryUsb(QueryUSBResults *qusbr) { return(SBIGUnivDrvCommand(CC_QUERY_USB, 0, qusbr)); } //========================================================================== int SbigCam::RwUsbI2c(RWUSBI2CParams *rwusbi2cp) { return(SBIGUnivDrvCommand(CC_RW_USB_I2C, rwusbi2cp, 0)); } //========================================================================== int SbigCam::BitIo(BitIOParams *biop, BitIOResults *bior) { return(SBIGUnivDrvCommand(CC_BIT_IO, biop, bior)); } //========================================================================== string SbigCam::GetCameraName() { int res; string name = "Unknown camera"; GetCCDInfoParams gccdip; GetCCDInfoResults0 gccdir; char *p1, *p2; gccdip.request = CCD_INFO_IMAGING; // request 0 res = SBIGUnivDrvCommand(CC_GET_CCD_INFO, &gccdip, &gccdir); if(res == CE_NO_ERROR){ name = gccdir.name; switch(gccdir.cameraType){ case ST237_CAMERA: if(gccdir.readoutInfo[0].gain >= 0x100) name += 'A'; break; case STL_CAMERA: // driver reports name as "SBIG ST-L-XXX..." p1 = gccdir.name + 5; if((p2 = strchr(p1,' ')) != NULL){ *p2 = '\0'; name = p1; } break; case NO_CAMERA: name = "No camera"; break; default: break; } } return(name); } //========================================================================== string SbigCam::GetCameraID() { string str; GetCCDInfoParams gccdip; GetCCDInfoResults2 gccdir2; gccdip.request = 2; if(GetCcdInfo(&gccdip, (void *)&gccdir2) == CE_NO_ERROR){ str = gccdir2.serialNumber; } return(str); } //========================================================================== int SbigCam::SetDeviceName(const char *name) { int res = CE_NO_ERROR; if(strlen(name) < PATH_MAX){ strcpy(m_dev_name, name); }else{ res = CE_BAD_PARAMETER; } return(res); } //========================================================================== // SBIGUnivDrvCommand: // Bottleneck function for all calls to the driver that logs the command // and error. First it activates our handle and then it calls the driver. // Activating the handle first allows having multiple instances of this // class dealing with multiple cameras on different communications port. // Also allows direct access to the SBIG Universal Driver after the driver // has been opened. int SbigCam::SBIGUnivDrvCommand(PAR_COMMAND command, void *params, void *results) { int res; SetDriverHandleParams sdhp; // Make sure we have a valid handle to the driver. if(GetDriverHandle() == INVALID_HANDLE_VALUE){ res = CE_DRIVER_NOT_OPEN; }else{ // Handle is valid so install it in the driver. sdhp.handle = GetDriverHandle(); res = SBIGUnivDrvCommand(CC_SET_DRIVER_HANDLE, &sdhp, 0); if(res == CE_FAKE_DRIVER) { // The user is using the dummy driver. Tell him to download the real driver IDMessage(DEVICE_NAME, "Error: SBIG Dummy Driver is being used now. You can only control your camera by downloading SBIG driver from INDI website @ indi.sf.net"); } else if(res == CE_NO_ERROR){ res = SBIGUnivDrvCommand(command, params, results); } } return(res); } //========================================================================== bool SbigCam::CheckLink() { if(GetCameraType() != NO_CAMERA && GetLinkStatus()) return(true); return(false); } //========================================================================== int SbigCam::GetNumOfCcdChips() { int res; switch(GetCameraType()){ case ST237_CAMERA: case ST5C_CAMERA: case ST402_CAMERA: res = 1; break; case ST7_CAMERA: case ST8_CAMERA: case ST9_CAMERA: case ST2K_CAMERA: res = 2; break; case STL_CAMERA: res = 3; break; case NO_CAMERA: default: res = 0; break; } return(res); } //========================================================================== bool SbigCam::IsFanControlAvailable() { CAMERA_TYPE camera = GetCameraType(); if(camera == ST5C_CAMERA || camera == ST402_CAMERA) return(false); return(true); } //========================================================================== double SbigCam::BcdPixel2double(ulong bcd) { double value = 0.0; double digit = 0.01; for(int i = 0; i < 8; i++){ value += (bcd & 0x0F) * digit; digit *= 10.0; bcd >>= 4; } return(value); } //========================================================================== void SbigCam::InitVars() { SetFileDescriptor(); SetCameraType(); SetLinkStatus(); SetDeviceName(""); #ifdef INDI // CCD PRODUCT: IUFillText(&m_icam_product_t[0], PRODUCT_NAME_T, PRODUCT_LABEL_T, UNKNOWN_LABEL); IUFillText(&m_icam_product_t[1], PRODUCT_ID_NAME_T, PRODUCT_ID_LABEL_T, UNKNOWN_LABEL); IUFillTextVector( &m_icam_product_tp, m_icam_product_t, NARRAY(m_icam_product_t), DEVICE_NAME, CCD_PRODUCT_NAME_TP, CCD_PRODUCT_LABEL_TP, CAMERA_GROUP, IP_RO, INDI_TIMEOUT, IPS_IDLE); // CCD DEVICE PORT: IUFillText(&m_icam_device_port_t[0], PORT_NAME_T, PORT_LABEL_T, SBIG_USB0); IUFillTextVector( &m_icam_device_port_tp, m_icam_device_port_t, NARRAY(m_icam_device_port_t), DEVICE_NAME, CCD_DEVICE_PORT_NAME_TP, CCD_DEVICE_PORT_LABEL_TP, CAMERA_GROUP, IP_RW, INDI_TIMEOUT, IPS_IDLE); // CCD CONNECTION: IUFillSwitch(&m_icam_connection_s[0], CONNECT_NAME_S, CONNECT_LABEL_S, ISS_OFF); IUFillSwitch(&m_icam_connection_s[1], DISCONNECT_NAME_S, DISCONNECT_LABEL_S, ISS_ON); IUFillSwitchVector(&m_icam_connection_sp, m_icam_connection_s, NARRAY(m_icam_connection_s), DEVICE_NAME, CCD_CONNECTION_NAME_SP, CCD_CONNECTION_LABEL_SP, CAMERA_GROUP, IP_RW, ISR_1OFMANY, INDI_TIMEOUT, IPS_IDLE); // CCD FAN STATE: IUFillSwitch(&m_icam_fan_state_s[0], CCD_FAN_ON_NAME_S, CCD_FAN_ON_LABEL_S, ISS_ON); IUFillSwitch(&m_icam_fan_state_s[1], CCD_FAN_OFF_NAME_S, CCD_FAN_OFF_LABEL_S, ISS_OFF); IUFillSwitchVector(&m_icam_fan_state_sp, m_icam_fan_state_s, NARRAY(m_icam_fan_state_s), DEVICE_NAME, CCD_FAN_NAME_SP, CCD_FAN_LABEL_SP, TEMPERATURE_GROUP, IP_RW, ISR_1OFMANY, INDI_TIMEOUT, IPS_OK); // CCD TEMPERATURE: IUFillNumber( &m_icam_temperature_n[0], CCD_TEMPERATURE_NAME_N, CCD_TEMPERATURE_LABEL_N, "%+.1f", MIN_CCD_TEMP, MAX_CCD_TEMP, CCD_TEMP_STEP, DEF_CCD_TEMP); IUFillNumberVector(&m_icam_temperature_np, m_icam_temperature_n, NARRAY(m_icam_temperature_n), DEVICE_NAME, CCD_TEMPERATURE_NAME_NP, CCD_TEMPERATURE_LABEL_NP, TEMPERATURE_GROUP, IP_RW, INDI_TIMEOUT, IPS_IDLE); // CCD COOLER: IUFillNumber( &m_icam_cooler_n[0], CCD_COOLER_NAME_N, CCD_COOLER_LABEL_N, "%.1f", 0, 0, 0, 0); IUFillNumberVector(&m_icam_cooler_np, m_icam_cooler_n, NARRAY(m_icam_cooler_n), DEVICE_NAME, CCD_COOLER_NAME_NP, CCD_COOLER_LABEL_NP, TEMPERATURE_GROUP, IP_RO, INDI_TIMEOUT, IPS_IDLE); // CCD TEMPERATURE POLLING: IUFillNumber( &m_icam_temperature_polling_n[0], CCD_TEMPERATURE_POLLING_NAME_N, CCD_TEMPERATURE_POLLING_LABEL_N, "%.1f", MIN_POLLING_TIME, MAX_POLLING_TIME, STEP_POLLING_TIME, CUR_POLLING_TIME); IUFillNumberVector(&m_icam_temperature_polling_np, m_icam_temperature_polling_n, NARRAY(m_icam_temperature_polling_n), DEVICE_NAME, CCD_TEMPERATURE_POLLING_NAME_NP, CCD_TEMPERATURE_POLLING_LABEL_NP, TEMPERATURE_GROUP, IP_RW, INDI_TIMEOUT, IPS_IDLE); // CCD TEMPERATURE MSG: IUFillSwitch( &m_icam_temperature_msg_s[0], CCD_TEMPERATURE_MSG_YES_NAME_S, CCD_TEMPERATURE_MSG_YES_LABEL_S, ISS_ON); IUFillSwitch( &m_icam_temperature_msg_s[1], CCD_TEMPERATURE_MSG_NO_NAME_S, CCD_TEMPERATURE_MSG_NO_LABEL_S, ISS_OFF); IUFillSwitchVector(&m_icam_temperature_msg_sp, m_icam_temperature_msg_s, NARRAY(m_icam_temperature_msg_s), DEVICE_NAME, CCD_TEMPERATURE_MSG_NAME_SP, CCD_TEMPERATURE_MSG_LABEL_SP, TEMPERATURE_GROUP, IP_RW, ISR_1OFMANY, INDI_TIMEOUT, IPS_IDLE); // CCD FRAME TYPE: IUFillSwitch( &m_icam_frame_type_s[0], CCD_FRAME_LIGHT_NAME_N, CCD_FRAME_LIGHT_LABEL_N, ISS_ON); IUFillSwitch( &m_icam_frame_type_s[1], CCD_FRAME_DARK_NAME_N, CCD_FRAME_DARK_LABEL_N, ISS_OFF); IUFillSwitch( &m_icam_frame_type_s[2], CCD_FRAME_FLAT_NAME_N, CCD_FRAME_FLAT_LABEL_N, ISS_OFF); IUFillSwitch( &m_icam_frame_type_s[3], CCD_FRAME_BIAS_NAME_N, CCD_FRAME_BIAS_LABEL_N, ISS_OFF); IUFillSwitchVector(&m_icam_frame_type_sp, m_icam_frame_type_s, NARRAY(m_icam_frame_type_s), DEVICE_NAME, CCD_FRAME_TYPE_NAME_NP, CCD_FRAME_TYPE_LABEL_NP, FRAME_GROUP, IP_RW, ISR_1OFMANY, INDI_TIMEOUT, IPS_OK); // CCD REQUEST: IUFillSwitch( &m_icam_ccd_request_s[0], CCD_IMAGING_NAME_S, CCD_IMAGING_LABEL_S, ISS_ON); IUFillSwitch( &m_icam_ccd_request_s[1], CCD_TRACKING_NAME_S, CCD_TRACKING_LABEL_S, ISS_OFF); IUFillSwitch( &m_icam_ccd_request_s[2], CCD_EXT_TRACKING_NAME_S, CCD_EXT_TRACKING_LABEL_S, ISS_OFF); IUFillSwitchVector(&m_icam_ccd_request_sp, m_icam_ccd_request_s, NARRAY(m_icam_ccd_request_s), DEVICE_NAME, CCD_REQUEST_NAME_SP, CCD_REQUEST_LABEL_SP, FRAME_GROUP, IP_RW, ISR_1OFMANY, INDI_TIMEOUT, IPS_OK); // CCD BINNING #ifdef USE_CCD_BINNING_STANDARD_PROPERTY IUFillNumber( &m_icam_ccd_binning_n[0], CCD_HOR_BIN_NAME_N, CCD_HOR_BIN_LABEL_N, "%.0f", CCD_MIN_BIN, CCD_MAX_BIN, 1, 1); IUFillNumber( &m_icam_ccd_binning_n[1], CCD_VER_BIN_NAME_N, CCD_VER_BIN_LABEL_N, "%.0f", CCD_MIN_BIN, CCD_MAX_BIN, 1, 1); IUFillNumberVector(&m_icam_ccd_binning_np, m_icam_ccd_binning_n, NARRAY(m_icam_ccd_binning_n), DEVICE_NAME, CCD_BINNING_NAME_NP, CCD_BINNING_LABEL_NP, FRAME_GROUP, IP_RW, INDI_TIMEOUT, IPS_IDLE); #else IUFillSwitch( &m_icam_binning_mode_s[0], CCD_BIN_1x1_I_NAME_S, CCD_BIN_1x1_I_LABEL_S, ISS_ON); IUFillSwitch( &m_icam_binning_mode_s[1], CCD_BIN_2x2_I_NAME_S, CCD_BIN_2x2_I_LABEL_S, ISS_OFF); IUFillSwitch( &m_icam_binning_mode_s[2], CCD_BIN_3x3_I_NAME_S, CCD_BIN_3x3_I_LABEL_S, ISS_OFF); IUFillSwitch( &m_icam_binning_mode_s[3], CCD_BIN_9x9_I_NAME_S, CCD_BIN_9x9_I_LABEL_S, ISS_OFF); IUFillSwitch( &m_icam_binning_mode_s[4], CCD_BIN_2x2_E_NAME_S, CCD_BIN_2x2_E_LABEL_S, ISS_OFF); IUFillSwitch( &m_icam_binning_mode_s[5], CCD_BIN_3x3_E_NAME_S, CCD_BIN_3x3_E_LABEL_S, ISS_OFF); IUFillSwitchVector(&m_icam_binning_mode_sp, m_icam_binning_mode_s, NARRAY(m_icam_binning_mode_s), DEVICE_NAME, CCD_BINNING_MODE_NAME_SP, CCD_BINNING_MODE_LABEL_SP, FRAME_GROUP, IP_RW, ISR_1OFMANY, INDI_TIMEOUT, IPS_OK); #endif // CCD PIXEL INFO: IUFillNumber( &m_icam_pixel_size_n[0], CCD_PIXEL_WIDTH_NAME_N, CCD_PIXEL_WIDTH_LABEL_N, "%.2f", 0, 0, 0, 0); IUFillNumber( &m_icam_pixel_size_n[1], CCD_PIXEL_HEIGHT_NAME_N, CCD_PIXEL_HEIGHT_LABEL_N, "%.2f", 0, 0, 0, 0); IUFillNumberVector(&m_icam_pixel_size_np, m_icam_pixel_size_n, NARRAY(m_icam_pixel_size_n), DEVICE_NAME, CCD_PIXEL_INFO_NAME_NP, CCD_PIXEL_INFO_LABEL_NP, FRAME_GROUP, IP_RO, INDI_TIMEOUT, IPS_IDLE); // CCD FRAME #ifdef USE_CCD_FRAME_STANDARD_PROPERTY IUFillNumber( &m_icam_ccd_frame_n[0], CCD_FRAME_X_NAME_N, CCD_FRAME_X_LABEL_N, "%.0f", 0,0,0,0); IUFillNumber( &m_icam_ccd_frame_n[1], CCD_FRAME_Y_NAME_N, CCD_FRAME_Y_LABEL_N, "%.0f", 0,0,0,0); IUFillNumber( &m_icam_ccd_frame_n[2], CCD_FRAME_W_NAME_N, CCD_FRAME_W_LABEL_N, "%.0f", 0,0,0,0); IUFillNumber( &m_icam_ccd_frame_n[3], CCD_FRAME_H_NAME_N, CCD_FRAME_H_LABEL_N, "%.0f", 0,0,0,0); IUFillNumberVector(&m_icam_ccd_frame_np, m_icam_ccd_frame_n, NARRAY(m_icam_ccd_frame_n), DEVICE_NAME, CCD_FRAME_NAME_NP, CCD_FRAME_LABEL_NP, FRAME_GROUP, IP_RW, INDI_TIMEOUT, IPS_IDLE); #else // FRAME X: IUFillNumber( &m_icam_frame_x_n[0], CCD_FRAME_X_NAME_N, CCD_FRAME_X_LABEL_N, "%.0f", 0,0,0,0); IUFillNumberVector(&m_icam_frame_x_np, m_icam_frame_x_n, NARRAY(m_icam_frame_x_n), DEVICE_NAME, CCD_FRAME_X_NAME_NP, CCD_FRAME_X_LABEL_NP, FRAME_GROUP, IP_RW, INDI_TIMEOUT, IPS_IDLE); // FRAME Y: IUFillNumber( &m_icam_frame_y_n[0], CCD_FRAME_Y_NAME_N, CCD_FRAME_Y_LABEL_N, "%.0f", 0,0,0,0); IUFillNumberVector(&m_icam_frame_y_np, m_icam_frame_y_n, NARRAY(m_icam_frame_y_n), DEVICE_NAME, CCD_FRAME_Y_NAME_NP, CCD_FRAME_Y_LABEL_NP, FRAME_GROUP, IP_RW, INDI_TIMEOUT, IPS_IDLE); // FRAME W: IUFillNumber( &m_icam_frame_w_n[0], CCD_FRAME_W_NAME_N, CCD_FRAME_W_LABEL_N, "%.0f",0,0,0,0); IUFillNumberVector(&m_icam_frame_w_np, m_icam_frame_w_n, NARRAY(m_icam_frame_w_n), DEVICE_NAME, CCD_FRAME_W_NAME_NP, CCD_FRAME_W_LABEL_NP, FRAME_GROUP, IP_RW, INDI_TIMEOUT, IPS_IDLE); // FRAME H: IUFillNumber( &m_icam_frame_h_n[0], CCD_FRAME_H_NAME_N, CCD_FRAME_H_LABEL_N, "%.0f",0,0,0,0); IUFillNumberVector(&m_icam_frame_h_np, m_icam_frame_h_n, NARRAY(m_icam_frame_h_n), DEVICE_NAME, CCD_FRAME_H_NAME_NP, CCD_FRAME_H_LABEL_NP, FRAME_GROUP, IP_RW, INDI_TIMEOUT, IPS_IDLE); #endif // CFW PRODUCT: IUFillText(&m_icfw_product_t[0], PRODUCT_NAME_T, PRODUCT_LABEL_T, UNKNOWN_LABEL); IUFillText(&m_icfw_product_t[1], PRODUCT_ID_NAME_T, PRODUCT_ID_LABEL_T, UNKNOWN_LABEL); IUFillTextVector( &m_icfw_product_tp, m_icfw_product_t, NARRAY(m_icfw_product_t), DEVICE_NAME, CFW_PRODUCT_NAME_TP, CFW_PRODUCT_LABEL_TP, CFW_GROUP, IP_RO, INDI_TIMEOUT, IPS_IDLE); // CFW_MODEL: IUFillSwitch(&m_icfw_type_s[0], CFW1_NAME_S, CFW1_LABEL_S, ISS_OFF); IUFillSwitch(&m_icfw_type_s[1], CFW2_NAME_S, CFW2_LABEL_S, ISS_OFF); IUFillSwitch(&m_icfw_type_s[2], CFW3_NAME_S, CFW3_LABEL_S, ISS_OFF); IUFillSwitch(&m_icfw_type_s[3], CFW4_NAME_S, CFW4_LABEL_S, ISS_OFF); IUFillSwitch(&m_icfw_type_s[4], CFW5_NAME_S, CFW5_LABEL_S, ISS_OFF); IUFillSwitch(&m_icfw_type_s[5], CFW6_NAME_S, CFW6_LABEL_S, ISS_OFF); IUFillSwitch(&m_icfw_type_s[6], CFW7_NAME_S, CFW7_LABEL_S, ISS_OFF); IUFillSwitch(&m_icfw_type_s[7], CFW8_NAME_S, CFW8_LABEL_S, ISS_OFF); #ifdef USE_CFW_AUTO IUFillSwitch(&m_icfw_type_s[8], CFW9_NAME_S, CFW9_LABEL_S, ISS_OFF); #endif IUFillSwitchVector(&m_icfw_type_sp, m_icfw_type_s, NARRAY(m_icfw_type_s), DEVICE_NAME, CFW_TYPE_NAME_SP, CFW_TYPE_LABEL_SP, CFW_GROUP, IP_RW, ISR_1OFMANY, INDI_TIMEOUT, IPS_IDLE); // CFW CONNECTION: IUFillSwitch(&m_icfw_connection_s[0], CONNECT_NAME_S, CONNECT_LABEL_S, ISS_OFF); IUFillSwitch(&m_icfw_connection_s[1], DISCONNECT_NAME_S, DISCONNECT_LABEL_S, ISS_ON); IUFillSwitchVector(&m_icfw_connection_sp, m_icfw_connection_s, NARRAY(m_icfw_connection_s), DEVICE_NAME, CFW_CONNECTION_NAME_SP, CFW_CONNECTION_LABEL_SP, CFW_GROUP, IP_RW, ISR_1OFMANY, INDI_TIMEOUT, IPS_IDLE); // CFW_SLOT: IUFillNumber( &m_icfw_slot_n[0], CFW_SLOT_NAME_N, CFW_SLOT_LABEL_N, "%.0f", MIN_FILTER_SLOT, MAX_FILTER_SLOT, FILTER_SLOT_STEP, DEF_FILTER_SLOT); IUFillNumberVector(&m_icfw_slot_np, m_icfw_slot_n, NARRAY(m_icfw_slot_n), DEVICE_NAME, CFW_SLOT_NAME_NP, CFW_SLOT_LABEL_NP, CFW_GROUP, IP_RW, INDI_TIMEOUT, IPS_IDLE); // CCD EXPOSE DURATION: IUFillNumber( &m_icam_expose_time_n[0], CCD_EXPOSE_DURATION_NAME_N, CCD_EXPOSE_DURATION_LABEL_N, "%.2f", MIN_EXP_TIME, MAX_EXP_TIME, EXP_TIME_STEP, DEF_EXP_TIME); IUFillNumberVector(&m_icam_expose_time_np, m_icam_expose_time_n, NARRAY(m_icam_expose_time_n), DEVICE_NAME, CCD_EXPOSE_DURATION_NAME_NP, CCD_EXPOSE_DURATION_LABEL_NP, EXPOSURE_GROUP, IP_RW, INDI_TIMEOUT, IPS_IDLE); // BLOB - Binary Large Object: strcpy(m_icam_fits_b.name, BLOB_NAME_B); strcpy(m_icam_fits_b.label, BLOB_LABEL_B); strcpy(m_icam_fits_b.format, BLOB_FORMAT_B); m_icam_fits_b.blob = 0; m_icam_fits_b.bloblen = 0; m_icam_fits_b.size = 0; m_icam_fits_b.bvp = 0; m_icam_fits_b.aux0 = 0; m_icam_fits_b.aux1 = 0; m_icam_fits_b.aux2 = 0; strcpy(m_icam_fits_bp.device, DEVICE_NAME); strcpy(m_icam_fits_bp.name, BLOB_NAME_BP); strcpy(m_icam_fits_bp.label, BLOB_LABEL_BP); strcpy(m_icam_fits_bp.group, EXPOSURE_GROUP); strcpy(m_icam_fits_bp.timestamp, ""); m_icam_fits_bp.p = IP_RO; m_icam_fits_bp.timeout = INDI_TIMEOUT; m_icam_fits_bp.s = IPS_IDLE; m_icam_fits_bp.bp = &m_icam_fits_b; m_icam_fits_bp.nbp = 1; m_icam_fits_bp.aux = 0; // FITS file name: IUFillText(&m_icam_fits_name_t[0], FITS_NAME_T, FITS_LABEL_T, ""); IUFillTextVector( &m_icam_fits_name_tp, m_icam_fits_name_t, NARRAY(m_icam_fits_name_t), DEVICE_NAME, FITS_NAME_TP, FITS_LABEL_TP, EXPOSURE_GROUP, IP_RO, INDI_TIMEOUT, IPS_IDLE); #endif // INDI } //========================================================================== #ifdef INDI void SbigCam::ISGetProperties() { // When a client first connects to the driver, we will offer only 3 basic // properties. After the camera is later detected, we will offer full // set of properties depending on the camera type. // CAMERA GROUP: IDDefText(&m_icam_product_tp, 0); // 1. CCD product IDDefText(&m_icam_device_port_tp, 0); // 2. CCD device port IDDefSwitch(&m_icam_connection_sp, 0); // 3. CCD connection } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::UpdateProperties() { int res = CE_NO_ERROR; string msg; IText *pIText; // TEMPERATURE GROUP: IDDelete(DEVICE_NAME, CCD_FAN_NAME_SP, 0); IDDelete(DEVICE_NAME, CCD_TEMPERATURE_NAME_NP, 0); IDDelete(DEVICE_NAME, CCD_COOLER_NAME_NP, 0); IDDelete(DEVICE_NAME, CCD_TEMPERATURE_POLLING_NAME_NP, 0); IDDelete(DEVICE_NAME, CCD_TEMPERATURE_MSG_NAME_SP, 0); // CFW GROUP: IDDelete(DEVICE_NAME, CFW_PRODUCT_NAME_TP, 0); IDDelete(DEVICE_NAME, CFW_TYPE_NAME_SP, 0); IDDelete(DEVICE_NAME, CFW_CONNECTION_NAME_SP, 0); IDDelete(DEVICE_NAME, CFW_SLOT_NAME_NP, 0); // FRAME GROUP: IDDelete(DEVICE_NAME, CCD_FRAME_TYPE_NAME_NP, 0); IDDelete(DEVICE_NAME, CCD_REQUEST_NAME_SP, 0); IDDelete(DEVICE_NAME, CCD_PIXEL_INFO_NAME_NP, 0); #ifdef USE_CCD_BINNING_STANDARD_PROPERTY IDDelete(DEVICE_NAME, CCD_BINNING_NAME_NP, 0); #else IDDelete(DEVICE_NAME, CCD_BINNING_MODE_NAME_SP, 0); #endif #ifdef USE_CCD_FRAME_STANDARD_PROPERTY IDDelete(DEVICE_NAME, CCD_FRAME_NAME_NP, 0); #else IDDelete(DEVICE_NAME, CCD_FRAME_X_NAME_NP, 0); IDDelete(DEVICE_NAME, CCD_FRAME_Y_NAME_NP, 0); IDDelete(DEVICE_NAME, CCD_FRAME_W_NAME_NP, 0); IDDelete(DEVICE_NAME, CCD_FRAME_H_NAME_NP, 0); #endif // EXPOSURE GROUP: IDDelete(DEVICE_NAME, CCD_EXPOSE_DURATION_NAME_NP, 0); IDDelete(DEVICE_NAME, FITS_NAME_TP, 0); IDDelete(DEVICE_NAME, BLOB_NAME_BP, 0); // Create new properties: if(GetCameraType() == NO_CAMERA){ // Device is closed. We again offer only three basic properties, // namely: CCD_PRODUCT, CCD_DEVICE_PORT & CCD_CONNECTION. // CCD PRODUCT: pIText = IUFindText(&m_icam_product_tp, PRODUCT_NAME_T); if(pIText) IUSaveText(pIText, UNKNOWN_LABEL); pIText = IUFindText(&m_icam_product_tp, PRODUCT_ID_NAME_T); if(pIText) IUSaveText(pIText, UNKNOWN_LABEL); m_icam_product_tp.s = IPS_IDLE; IDSetText(&m_icam_product_tp, 0); // CCD DEVICE PORT: m_icam_device_port_tp.s = IPS_IDLE; IDSetText(&m_icam_device_port_tp, 0); // CCD CONNECTION: m_icam_connection_s[0].s = ISS_OFF; m_icam_connection_s[1].s = ISS_ON; m_icam_connection_sp.s = IPS_IDLE; msg = "SBIG CCD camera is offline."; IDSetSwitch(&m_icam_connection_sp, "%s", msg.c_str()); }else{ // Device is open, so we offer the full set of properties // which are supported by the detected camera. // CCD PRODUCT: msg = GetCameraName(); pIText = IUFindText(&m_icam_product_tp, PRODUCT_NAME_T); if(pIText) IUSaveText(pIText, msg.c_str()); msg = GetCameraID(); pIText = IUFindText(&m_icam_product_tp, PRODUCT_ID_NAME_T); if(pIText) IUSaveText(pIText, msg.c_str()); m_icam_product_tp.s = IPS_OK; IDSetText(&m_icam_product_tp, 0); // CCD DEVICE PORT: IText *pIText = IUFindText(&m_icam_device_port_tp, PORT_NAME_T); if(pIText) IUSaveText(pIText, GetDeviceName()); m_icam_device_port_tp.s = IPS_OK; IDSetText(&m_icam_device_port_tp, 0); // CCD CONNECTION: m_icam_connection_s[0].s = ISS_ON; m_icam_connection_s[1].s = ISS_OFF; m_icam_connection_sp.s = IPS_OK; msg = IUFindText(&m_icam_product_tp, PRODUCT_NAME_T)->text; msg += " is online. SN: "; msg += IUFindText(&m_icam_product_tp, PRODUCT_ID_NAME_T)->text; IDSetSwitch(&m_icam_connection_sp, "%s", msg.c_str()); // CCD FAN: if(IsFanControlAvailable()){ IDDefSwitch(&m_icam_fan_state_sp, 0); } // CCD TEMPERATURE: m_icam_temperature_np.s = IPS_BUSY; IDDefNumber(&m_icam_temperature_np, 0); res = SetTemperatureRegulation(m_icam_temperature_n[0].value); if(res == CE_NO_ERROR){ // Set property to busy and poll in UpdateTemperature for CCD temp IDSetNumber(&m_icam_temperature_np, "Setting CCD temperature to %+.1f [C].", m_icam_temperature_n[0].value); }else{ m_icam_temperature_np.s = IPS_ALERT; IDSetNumber(&m_icam_temperature_np, "Error: Cannot set CCD temperature to %+.1f [C]. %s", m_icam_temperature_n[0].value, GetErrorString(res).c_str()); } // CCD COOLER: m_icam_cooler_np.s = IPS_BUSY; IDDefNumber(&m_icam_cooler_np, 0); // CCD TEMPERATURE POOLING: m_icam_temperature_polling_np.s = IPS_OK; IDDefNumber(&m_icam_temperature_polling_np, 0); // CCD TEMPERATURE MSG: m_icam_temperature_msg_sp.s = IPS_OK; IDDefSwitch(&m_icam_temperature_msg_sp, 0); // CFW PRODUCT: IDDefText(&m_icfw_product_tp, 0); // CFW TYPE: IDDefSwitch(&m_icfw_type_sp, 0); // CFW CONNECTION: IDDefSwitch(&m_icfw_connection_sp, 0); // CFW SLOT: IDDefNumber(&m_icfw_slot_np, 0); // CCD FRAME TYPE: IDDefSwitch(&m_icam_frame_type_sp, 0); // CCD REQUEST: if(GetNumOfCcdChips() > 1) IDDefSwitch(&m_icam_ccd_request_sp, 0); // CCD BINNING: #ifdef USE_CCD_BINNING_STANDARD_PROPERTY IDDefNumber(&m_icam_ccd_binning_np, 0); #else IDDefSwitch(&m_icam_binning_mode_sp, 0); #endif UpdateCcdFrameProperties(); // CCD PIXEL INFO: IDDefNumber(&m_icam_pixel_size_np, 0); // CCD FRAME #ifdef USE_CCD_FRAME_STANDARD_PROPERTY IDDefNumber(&m_icam_ccd_frame_np, 0); #else IDDefNumber(&m_icam_frame_x_np, 0); IDDefNumber(&m_icam_frame_y_np, 0); IDDefNumber(&m_icam_frame_w_np, 0); IDDefNumber(&m_icam_frame_h_np, 0); #endif // CCD EXPOSE DURATION: IDDefNumber(&m_icam_expose_time_np, 0); // CCD BLOB NAME: IDDefBLOB(&m_icam_fits_bp, 0); // CCD FITS NAME: IDDefText(&m_icam_fits_name_tp, 0); } return(res); } #endif // INDI //========================================================================= #ifdef INDI int SbigCam::UpdateCcdFrameProperties(bool bUpdateClient) { int res = CE_NO_ERROR, wCcd, hCcd, ccd, binning; double wPixel, hPixel; if((res = GetSelectedCcdChip(ccd)) != CE_NO_ERROR) return(res); if((res = GetSelectedCcdBinningMode(binning)) != CE_NO_ERROR) return(res); res = GetCcdSizeInfo(ccd, binning, wCcd, hCcd, wPixel, hPixel); if(res == CE_NO_ERROR){ // CCD INFO: m_icam_pixel_size_n[0].value = wPixel; m_icam_pixel_size_n[1].value = hPixel; m_icam_pixel_size_np.s = IPS_OK; // CCD FRAME #ifdef USE_CCD_FRAME_STANDARD_PROPERTY // X m_icam_ccd_frame_n[0].min = 0; m_icam_ccd_frame_n[0].max = wCcd-1; m_icam_ccd_frame_n[0].value = 0; // Y m_icam_ccd_frame_n[1].min = 0; m_icam_ccd_frame_n[1].max = hCcd-1; m_icam_ccd_frame_n[1].value = 0; // WIDTH m_icam_ccd_frame_n[2].min = 1; m_icam_ccd_frame_n[2].max = wCcd; m_icam_ccd_frame_n[2].value = wCcd; // HEIGHT m_icam_ccd_frame_n[3].min = 1; m_icam_ccd_frame_n[3].max = hCcd; m_icam_ccd_frame_n[3].value = hCcd; // STATE m_icam_ccd_frame_np.s = IPS_OK; #else // CCD FRAME X: m_icam_frame_x_n[0].min = 0; m_icam_frame_x_n[0].max = 0; m_icam_frame_x_n[0].value = 0; m_icam_frame_x_np.s = IPS_OK; // CCD FRAME Y: m_icam_frame_y_n[0].min = 0; m_icam_frame_y_n[0].max = 0; m_icam_frame_y_n[0].value = 0; m_icam_frame_y_np.s = IPS_OK; // CCD FRAME W: m_icam_frame_w_n[0].min = 1; m_icam_frame_w_n[0].max = wCcd; m_icam_frame_w_n[0].value = wCcd; m_icam_frame_w_np.s = IPS_OK; // CCD FRAME H: m_icam_frame_h_n[0].min = 1; m_icam_frame_h_n[0].max = hCcd; m_icam_frame_h_n[0].value = hCcd; // STATE m_icam_frame_h_np.s = IPS_OK; #endif if(bUpdateClient){ IDSetNumber(&m_icam_pixel_size_np, 0); #ifdef USE_CCD_FRAME_STANDARD_PROPERTY IDSetNumber(&m_icam_ccd_frame_np, 0); IUUpdateMinMax(&m_icam_ccd_frame_np); #else IDSetNumber(&m_icam_frame_x_np, 0); IDSetNumber(&m_icam_frame_y_np, 0); IDSetNumber(&m_icam_frame_w_np, 0); IDSetNumber(&m_icam_frame_h_np, 0); IUUpdateMinMax(&m_icam_frame_x_np); IUUpdateMinMax(&m_icam_frame_y_np); IUUpdateMinMax(&m_icam_frame_w_np); IUUpdateMinMax(&m_icam_frame_h_np); #endif } } return(res); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::GetSelectedCcdChip(int &ccd_request) { int res = CE_NO_ERROR; ISwitch *p = IUFindOnSwitch(&m_icam_ccd_request_sp); if(p){ if(!strcmp(p->name, CCD_IMAGING_NAME_S)){ ccd_request = CCD_IMAGING; }else if(!strcmp(p->name, CCD_TRACKING_NAME_S)){ ccd_request = CCD_TRACKING; }else if(!strcmp(p->name, CCD_EXT_TRACKING_NAME_S)){ ccd_request = CCD_EXT_TRACKING; }else{ res = CE_BAD_PARAMETER; IDMessage(DEVICE_NAME, "Error: No CCD chip found! " "[m_icam_ccd_request_sp]!"); } }else{ res = CE_OS_ERROR; IDMessage(DEVICE_NAME, "Error: No switch ON found! " "[m_icam_ccd_request_sp]."); } return(res); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::GetSelectedCcdBinningMode(int &binning) { int res = CE_NO_ERROR; #ifdef USE_CCD_BINNING_STANDARD_PROPERTY if((m_icam_ccd_binning_n[0].value == 1)&& (m_icam_ccd_binning_n[1].value == 1)){ binning = CCD_BIN_1x1_I; }else if((m_icam_ccd_binning_n[0].value == 2)&& (m_icam_ccd_binning_n[1].value == 2)){ binning = CCD_BIN_2x2_I; }else if((m_icam_ccd_binning_n[0].value == 3)&& (m_icam_ccd_binning_n[1].value == 3)){ binning = CCD_BIN_3x3_I; }else if((m_icam_ccd_binning_n[0].value == 9)&& (m_icam_ccd_binning_n[1].value == 9)){ binning = CCD_BIN_9x9_I; }else{ res = CE_BAD_PARAMETER; IDMessage(DEVICE_NAME, "Error: Bad CCD binning mode! " "Use: 1x1, 2x2 or 3x3"); } #else ISwitch *p = IUFindOnSwitch(&m_icam_binning_mode_sp); if(p){ if(!strcmp(p->name, CCD_BIN_1x1_I_NAME_S)){ binning = CCD_BIN_1x1_I; }else if(!strcmp(p->name, CCD_BIN_2x2_I_NAME_S)){ binning = CCD_BIN_2x2_I; }else if(!strcmp(p->name, CCD_BIN_3x3_I_NAME_S)){ binning = CCD_BIN_3x3_I; }else if(!strcmp(p->name, CCD_BIN_9x9_I_NAME_S)){ binning = CCD_BIN_9x9_I; }else if(!strcmp(p->name, CCD_BIN_2x2_E_NAME_S)){ binning = CCD_BIN_2x2_E; }else if(!strcmp(p->name, CCD_BIN_3x3_E_NAME_S)){ binning = CCD_BIN_3x3_E; }else{ res = CE_BAD_PARAMETER; IDMessage(DEVICE_NAME, "Error: No CCD binning mode found! " "[m_icam_binning_mode_sp]!"); } }else{ res = CE_OS_ERROR; IDMessage(DEVICE_NAME, "Error: No switch ON found! " "[m_icam_binning_mode_sp]"); } #endif return(res); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::GetSelectedCcdFrameType(string &frame_type) { int res = CE_NO_ERROR; ISwitch *p = IUFindOnSwitch(&m_icam_frame_type_sp); if(p){ frame_type = p->name; }else{ res = CE_OS_ERROR; IDMessage(DEVICE_NAME, "Error: No switch ON found! " "[m_icam_frame_type_sp]"); } return(res); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::GetCcdShutterMode(int &shutter, int ccd) { string frame_type; int res = GetSelectedCcdFrameType(frame_type); if(res != CE_NO_ERROR) return(res); if( !strcmp(frame_type.c_str(), CCD_FRAME_LIGHT_NAME_N) || !strcmp(frame_type.c_str(), CCD_FRAME_FLAT_NAME_N) || !strcmp(frame_type.c_str(), CCD_FRAME_BIAS_NAME_N) ){ if(ccd == CCD_EXT_TRACKING){ shutter = SC_OPEN_EXT_SHUTTER; }else{ shutter = SC_OPEN_SHUTTER; } }else if(!strcmp(frame_type.c_str(), CCD_FRAME_DARK_NAME_N)){ if(ccd == CCD_EXT_TRACKING){ shutter = SC_CLOSE_EXT_SHUTTER; }else{ shutter = SC_CLOSE_SHUTTER; } }else{ res = CE_OS_ERROR; IDMessage(DEVICE_NAME, "Error: Unknown selected CCD frame type! " "[m_icam_frame_type_sp]"); } return(res); } #endif // INDI //========================================================================== #ifdef INDI void SbigCam::ISNewSwitch(const char *name, ISState *states, char *names[], int num) { int res; string str; CFWResults cfwr; // CCD CONNECTION: if(!strcmp(name, m_icam_connection_sp.name)){ IUResetSwitches(&m_icam_connection_sp); IUUpdateSwitches(&m_icam_connection_sp, states, names, num); // Check open/close request: if(m_icam_connection_s[0].s == ISS_ON){ // Open device: if((res = OpenDevice(m_icam_device_port_tp.tp->text)) == CE_NO_ERROR){ // Establish link: if((res = EstablishLink()) == CE_NO_ERROR){ // Link established. UpdateProperties(); }else{ // Establish link error. m_icam_connection_s[0].s = ISS_OFF; m_icam_connection_s[1].s = ISS_ON; m_icam_connection_sp.s = IPS_IDLE; str = "Error: Cannot establish link to SBIG CCD camera. "; str += GetErrorString(res); IDSetSwitch(&m_icam_connection_sp, "%s", str.c_str()); } }else{ // Open device error. m_icam_connection_s[0].s = ISS_OFF; m_icam_connection_s[1].s = ISS_ON; m_icam_connection_sp.s = IPS_IDLE; str = "Error: Cannot open SBIG CCD camera device. "; str += GetErrorString(res); IDSetSwitch(&m_icam_connection_sp, "%s", str.c_str()); } }else{ // Close device. if((res = CloseDevice()) == CE_NO_ERROR){ UpdateProperties(); }else{ // Close device error: m_icam_connection_s[0].s = ISS_ON; m_icam_connection_s[1].s = ISS_OFF; m_icam_connection_sp.s = IPS_ALERT; str = "Error: Cannot close SBIG CCD camera device. "; str += GetErrorString(res); IDSetSwitch(&m_icam_connection_sp, "%s", str.c_str()); } } return; } // CCD REQUEST: if(!strcmp(name, m_icam_ccd_request_sp.name)){ if(CheckConnection(&m_icam_ccd_request_sp) == false) return; IUResetSwitches(&m_icam_ccd_request_sp); IUUpdateSwitches(&m_icam_ccd_request_sp, states, names, num); m_icam_ccd_request_sp.s = IPS_OK; IDSetSwitch(&m_icam_ccd_request_sp, 0); UpdateCcdFrameProperties(true); return; } // CCD FAN: if(!strcmp(name, m_icam_fan_state_sp.name)){ if(CheckConnection(&m_icam_fan_state_sp) == false) return; IUResetSwitches(&m_icam_fan_state_sp); IUUpdateSwitches(&m_icam_fan_state_sp, states, names, num); // Switch FAN ON/OFF: MiscellaneousControlParams mcp; if(m_icam_fan_state_s[0].s == ISS_ON){ mcp.fanEnable = 1; }else{ mcp.fanEnable = 0; } mcp.shutterCommand = SC_LEAVE_SHUTTER; mcp.ledState = LED_OFF; if((res = MiscellaneousControl(&mcp)) == CE_NO_ERROR){ m_icam_fan_state_sp.s = IPS_OK; if(mcp.fanEnable == 1){ str = "Fan turned ON."; }else{ str = "Fan turned OFF."; } }else{ m_icam_fan_state_sp.s = IPS_ALERT; if(mcp.fanEnable == 1){ str = "Error: Cannot turn Fan ON. "; }else{ str = "Error: Cannot turn Fan OFF."; } str += GetErrorString(res); } IDSetSwitch(&m_icam_fan_state_sp, "%s", str.c_str()); return; } // CCD FRAME TYPE: if(!strcmp(name, m_icam_frame_type_sp.name)){ IUResetSwitches(&m_icam_frame_type_sp); IUUpdateSwitches(&m_icam_frame_type_sp, states, names, num); m_icam_frame_type_sp.s = IPS_OK; IDSetSwitch(&m_icam_frame_type_sp, 0); return; } // CCD BINNING: #ifndef USE_CCD_BINNING_STANDARD_PROPERTY if(!strcmp(name, m_icam_binning_mode_sp.name)){ if(CheckConnection(&m_icam_binning_mode_sp) == false) return; IUResetSwitches(&m_icam_binning_mode_sp); IUUpdateSwitches(&m_icam_binning_mode_sp, states, names, num); m_icam_binning_mode_sp.s = IPS_OK; IDSetSwitch(&m_icam_binning_mode_sp, 0); UpdateCcdFrameProperties(true); return; } #endif // CCD TEMPERATURE: if(!strcmp(name, m_icam_temperature_msg_sp.name)){ IUResetSwitches(&m_icam_temperature_msg_sp); IUUpdateSwitches(&m_icam_temperature_msg_sp, states, names, num); m_icam_temperature_msg_sp.s = IPS_OK; IDSetSwitch(&m_icam_temperature_msg_sp, 0); return; } // CFW TYPE: if(!strcmp(name, m_icfw_type_sp.name)){ if(CheckConnection(&m_icfw_type_sp) == false) return; // Allow change of CFW's type only if not already connected. if(m_icfw_connection_s[0].s == ISS_OFF){ IUResetSwitches(&m_icfw_type_sp); IUUpdateSwitches(&m_icfw_type_sp, states, names, num); str = ""; }else{ str = "Cannot change CFW type while connected!"; } m_icfw_type_sp.s = IPS_OK; IDSetSwitch(&m_icfw_type_sp, "%s", str.c_str()); return; } // CFW CONNECTION: if(!strcmp(name, m_icfw_connection_sp.name)){ if(CheckConnection(&m_icfw_connection_sp) == false) return; IUResetSwitches(&m_icfw_connection_sp); IUUpdateSwitches(&m_icfw_connection_sp, states, names, num); m_icfw_connection_sp.s = IPS_BUSY; IDSetSwitch(&m_icfw_connection_sp, 0); if(m_icfw_connection_s[0].s == ISS_ON){ // Open device. if(CfwConnect() == CE_NO_ERROR){ m_icfw_connection_sp.s = IPS_OK; IDSetSwitch(&m_icfw_connection_sp, "CFW connected."); }else{ m_icfw_connection_sp.s = IPS_ALERT; IDSetSwitch(&m_icfw_connection_sp, "CFW connection error!"); } }else{ // Close device. if(CfwDisconnect() == CE_NO_ERROR){ m_icfw_connection_sp.s = IPS_ALERT; IDSetSwitch(&m_icfw_connection_sp, "CFW disconnection error!"); }else{ // Update CFW's Product/ID texts. cfwr.cfwModel = CFWSEL_UNKNOWN; cfwr.cfwPosition = CFWP_UNKNOWN; cfwr.cfwStatus = CFWS_UNKNOWN; cfwr.cfwError = CFWE_DEVICE_NOT_OPEN; cfwr.cfwResult1 = 0; cfwr.cfwResult2 = 0; CfwUpdateProperties(cfwr); // Remove connection text. m_icfw_connection_sp.s = IPS_IDLE; IDSetSwitch(&m_icfw_connection_sp, "CFW disconnected."); } } return; } } #endif // INDI //========================================================================== #ifdef INDI void SbigCam::ISNewText( const char *name, char *texts[], char *names[], int /*num*/) { string str; // CCD DEVICE PORT: if(!strcmp(name, m_icam_device_port_tp.name)){ IText *pIText = IUFindText(&m_icam_device_port_tp, names[0]); if(pIText) IUSaveText(pIText, texts[0]); m_icam_device_port_tp.s = IPS_OK; IDSetText(&m_icam_device_port_tp, 0); } } #endif // INDI //========================================================================== #ifdef INDI void SbigCam::ISNewNumber(const char *name, double values[], char *names[], int num) { int res = CE_NO_ERROR, wCcd, hCcd, ccd, binning; double wPixel, hPixel; // CCD EXPOSE DURATION: if(!strcmp(name, m_icam_expose_time_np.name)){ IUUpdateNumbers(&m_icam_expose_time_np, values, names, num); if(m_icam_expose_time_np.s == IPS_BUSY){ StopExposure(); }else{ StartExposure(); } } // CCD TEMPERATURE: if(!strcmp(name, m_icam_temperature_np.name)){ if(CheckConnection(&m_icam_temperature_np) == false) return; if(values[0] < MIN_CCD_TEMP || values[0] > MAX_CCD_TEMP){ m_icam_temperature_np.s = IPS_IDLE; IDSetNumber(&m_icam_temperature_np, "Error: Bad temperature value! " "Range is [%.1f, %.1f] [C].", MIN_CCD_TEMP, MAX_CCD_TEMP); return; } if((res = SetTemperatureRegulation(values[0])) == CE_NO_ERROR){ // Set property to busy and poll in ISPoll for CCD temp m_icam_temperature_n[0].value = values[0]; m_icam_temperature_np.s = IPS_BUSY; IDSetNumber(&m_icam_temperature_np, "Setting CCD temperature to %+.1f [C].", values[0]); }else{ m_icam_temperature_np.s = IPS_ALERT; IDSetNumber(&m_icam_temperature_np, "Error: Cannot set CCD temperature to %+.1f [C]. %s", values[0], GetErrorString(res).c_str()); } } // CCD TEMPERATURE POOLING: if(!strcmp(name, m_icam_temperature_polling_np.name)){ m_icam_temperature_polling_np.s = IPS_OK; IUUpdateNumbers(&m_icam_temperature_polling_np, values, names, num); IDSetNumber(&m_icam_temperature_polling_np, 0); } // CCD BINNING: #ifdef USE_CCD_BINNING_STANDARD_PROPERTY if(!strcmp(name, m_icam_ccd_binning_np.name)){ m_icam_ccd_binning_np.s = IPS_OK; // Update the values according the actual CCD binning mode possibilities. // HOR_BIN == value[0], VER_BIN == value[1] if(values[0] != values[1]) values[1] = values[0]; IUUpdateNumbers(&m_icam_ccd_binning_np, values, names, num); IDSetNumber(&m_icam_ccd_binning_np, 0); UpdateCcdFrameProperties(true); } #endif // CCD FRAME: #ifdef USE_CCD_FRAME_STANDARD_PROPERTY if(!strcmp(name, m_icam_ccd_frame_np.name)){ m_icam_ccd_frame_np.s = IPS_OK; // Update the values according the actual CCD info. if((res = GetSelectedCcdChip(ccd)) == CE_NO_ERROR){ if((res = GetSelectedCcdBinningMode(binning)) == CE_NO_ERROR){ res = GetCcdSizeInfo(ccd, binning, wCcd, hCcd, wPixel, hPixel); if(res == CE_NO_ERROR){ // CCD_X + CCD_WIDTH if((values[0] + values[2]) >= wCcd){ values[2] = wCcd - values[0]; } // CCD_Y + CCD_HEIGHT if((values[1] + values[3]) >= hCcd){ values[3] = hCcd - values[1]; } } } } IUUpdateNumbers(&m_icam_ccd_frame_np, values, names, num); IDSetNumber(&m_icam_ccd_frame_np, 0); } #else // CCD FRAME X: if(!strcmp(name, m_icam_frame_x_np.name)){ m_icam_frame_x_np.s = IPS_OK; IUUpdateNumbers(&m_icam_frame_x_np, values, names, num); IDSetNumber(&m_icam_frame_x_np, 0); } // CCD FRAME Y: if(!strcmp(name, m_icam_frame_y_np.name)){ m_icam_frame_y_np.s = IPS_OK; IUUpdateNumbers(&m_icam_frame_y_np, values, names, num); IDSetNumber(&m_icam_frame_y_np, 0); } // CCD FRAME W: if(!strcmp(name, m_icam_frame_w_np.name)){ m_icam_frame_w_np.s = IPS_OK; IUUpdateNumbers(&m_icam_frame_w_np, values, names, num); IDSetNumber(&m_icam_frame_w_np, 0); // Update Min/Max of CCD_FRAME_X: m_icam_frame_x_n[0].max = m_icam_frame_w_n[0].max - m_icam_frame_w_n[0].value - 1; m_icam_frame_x_np.s = IPS_OK; IUUpdateMinMax(&m_icam_frame_x_np); } // CCD FRAME H: if(!strcmp(name, m_icam_frame_h_np.name)){ m_icam_frame_h_np.s = IPS_OK; IUUpdateNumbers(&m_icam_frame_h_np, values, names, num); IDSetNumber(&m_icam_frame_h_np, 0); // Update Min/Max of CCD_FRAME_Y: m_icam_frame_y_n[0].max = m_icam_frame_h_n[0].max - m_icam_frame_h_n[0].value - 1; m_icam_frame_y_np.s = IPS_OK; IUUpdateMinMax(&m_icam_frame_y_np); } #endif // CFW SLOT: CFWResults cfwr; int type; char str[64]; if(!strcmp(name, m_icfw_slot_np.name)){ // Use CFW's GOTO only if already connected: if(m_icfw_connection_s[0].s != ISS_ON) return; m_icfw_slot_np.s = IPS_BUSY; IDSetNumber(&m_icfw_slot_np, 0); IUUpdateNumbers(&m_icfw_slot_np, values, names, num); if(CfwGoto(&cfwr) == CE_NO_ERROR){ type = GetCfwSelType(); if(type == CFWSEL_CFW6A || type == CFWSEL_CFW8){ sprintf(str, "CFW position reached."); }else{ sprintf(str, "CFW position %d reached.", cfwr.cfwPosition); } m_icfw_slot_n[0].value = cfwr.cfwPosition; m_icfw_slot_np.s = IPS_OK; }else{ // CFW error occurred, so report all the available infos to the client: CfwShowResults("CFWGoto:", cfwr); m_icfw_slot_np.s = IPS_ALERT; sprintf(str, "Please Connect/Disconnect CFW, than try again..."); } IDSetNumber(&m_icfw_slot_np, "%s", str); } } #endif // INDI //========================================================================== #ifdef INDI bool SbigCam::CheckConnection(ISwitchVectorProperty *vp) { if(m_icam_connection_sp.s != IPS_OK){ IDMessage(DEVICE_NAME, "Cannot change property '%s' while the CCD is offline.", vp->name); vp->s = IPS_IDLE; IDSetSwitch(vp, NULL); return(false); } return(true); } #endif // INDI //========================================================================== #ifdef INDI bool SbigCam::CheckConnection(INumberVectorProperty *vp) { if(m_icam_connection_sp.s != IPS_OK){ IDMessage(DEVICE_NAME, "Cannot change property '%s' while the CCD is offline.", vp->name); vp->s = IPS_IDLE; IDSetNumber(vp, NULL); return(false); } return(true); } #endif // INDI //========================================================================== #ifdef INDI bool SbigCam::CheckConnection(ITextVectorProperty *vp) { if(m_icam_connection_sp.s != IPS_OK){ IDMessage(DEVICE_NAME, "Cannot change property '%s' while the CCD is offline.", vp->name); vp->s = IPS_IDLE; IDSetText(vp, NULL); return(false); } return(true); } #endif // INDI //========================================================================== #ifdef INDI void SbigCam::UpdateTemperature(void *p) { SbigCam *pSbigCam = (SbigCam *)p; if(pSbigCam->CheckLink()) pSbigCam->UpdateTemperature(); IEAddTimer( pSbigCam->GetCcdTemperaturePoolingTime(), SbigCam::UpdateTemperature, pSbigCam); } #endif // INDI //========================================================================== #ifdef INDI void SbigCam::UpdateTemperature() { bool enabled; double ccdTemp, setpointTemp, percentTE, power; // Get temperature status, ignore possible errors. if(QueryTemperatureStatus(enabled, ccdTemp, setpointTemp, percentTE) == CE_NO_ERROR){ // Compare the current temperature against the setpoint value: if(fabs(setpointTemp - ccdTemp) <= TEMP_DIFF){ m_icam_temperature_np.s = IPS_OK; }else{ m_icam_temperature_np.s = IPS_BUSY; } m_icam_temperature_n[0].value = ccdTemp; // Check the TE cooler if inside the range: power = 100.0 * percentTE; if(power <= CCD_COOLER_THRESHOLD){ m_icam_cooler_np.s = IPS_OK; }else{ m_icam_cooler_np.s = IPS_BUSY; } m_icam_cooler_n[0].value = power; // Update the client's properties: if(m_icam_temperature_msg_s[0].s == ISS_ON){ IDSetNumber(&m_icam_temperature_np, "CCD temperature %+.1f [C], TE cooler: %.1f [%%].", ccdTemp, power); }else{ IDSetNumber(&m_icam_temperature_np, 0); } IDSetNumber(&m_icam_cooler_np, 0); } } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::GetCcdTemperaturePoolingTime() { return((int)(m_icam_temperature_polling_n[0].value * 1000)); } #endif // INDI //========================================================================== #ifdef INDI void SbigCam::UpdateExposure(void *p) { SbigCam *pSbigCam = (SbigCam *)p; if(pSbigCam->CheckLink()) pSbigCam->UpdateExposure(); IEAddTimer(POLL_EXPOSURE_MS, SbigCam::UpdateExposure, pSbigCam); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::StartExposure() { int res; // Sanity check: int ccd, binning, shutter; if((res = GetSelectedCcdChip(ccd)) != CE_NO_ERROR) return(res); if((res = GetCcdShutterMode(shutter, ccd)) != CE_NO_ERROR) return(res); if((res = GetSelectedCcdBinningMode(binning))!= CE_NO_ERROR) return(res); // Is the expose time zero ? if(m_icam_expose_time_n[0].value == 0){ m_icam_expose_time_np.s = IPS_ALERT; IDSetNumber(&m_icam_expose_time_np, 0); IDMessage(DEVICE_NAME, "Please set non-zero exposure time and try again."); return(CE_BAD_PARAMETER); } // Save the current temperature because needed for the FITS file: bool enabled; double ccdTemp, setpointTemp, percentTE; res = QueryTemperatureStatus(enabled, ccdTemp, setpointTemp, percentTE); if(res == CE_NO_ERROR){ SaveTemperature(ccdTemp); }else{ SaveTemperature(0.0); } // Save exposure time, necessary for FITS file: SaveExposeTime(m_icam_expose_time_n[0].value); // Calculate an expose time: ulong expTime = (ulong)floor(m_icam_expose_time_n[0].value * 100.0 + 0.5); // Start exposure: StartExposureParams sep; sep.ccd = (unsigned short)ccd; sep.abgState = (unsigned short)ABG_LOW7; sep.openShutter = (unsigned short)shutter; sep.exposureTime = expTime; if((res = StartExposure(&sep)) != CE_NO_ERROR) return(res); // Save start time of the exposure: SetStartExposureTimestamp(timestamp()); // Update client's property: string msg, frame_type; if((res = GetSelectedCcdFrameType(frame_type)) != CE_NO_ERROR) return(res); // Update the expose time property: m_icam_expose_time_np.s = IPS_BUSY; IDSetNumber(&m_icam_expose_time_np, 0); // Update FITS file name: IUFillText(&m_icam_fits_name_t[0], FITS_NAME_T, FITS_LABEL_T, ""); m_icam_fits_name_tp.s = IPS_IDLE; IDSetText(&m_icam_fits_name_tp, 0); // Update BLOB property: SetBlobState(IPS_BUSY); // Update exposure action button properties: if(!strcmp(frame_type.c_str(), CCD_FRAME_LIGHT_NAME_N)){ msg = "LF exposure in progress..."; }else if(!strcmp(frame_type.c_str(), CCD_FRAME_DARK_NAME_N)){ msg = "DF exposure in progress..."; }else if(!strcmp(frame_type.c_str(), CCD_FRAME_FLAT_NAME_N)){ msg = "FF exposure in progress..."; }else if(!strcmp(frame_type.c_str(), CCD_FRAME_BIAS_NAME_N)){ msg = "BF exposure in progress..."; } IDMessage(DEVICE_NAME, "%s", msg.c_str()); return(res); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::StopExposure() { int res, ccd; string msg; if((res = GetSelectedCcdChip(ccd)) != CE_NO_ERROR) return(res); // END_EXPOSURE: EndExposureParams eep; eep.ccd = (unsigned short)ccd; res = EndExposure(&eep); // Update expose time property: m_icam_expose_time_n[0].value = 0; if(res == CE_NO_ERROR){ m_icam_expose_time_np.s = IPS_IDLE; msg = "Exposure cancelled."; }else{ m_icam_expose_time_np.s = IPS_ALERT; msg = "Stop exposure error."; } IDSetNumber(&m_icam_expose_time_np, 0); IDMessage(DEVICE_NAME, "%s", msg.c_str()); // Update BLOB property: SetBlobState(IPS_IDLE); return(res); } #endif // INDI //========================================================================== #ifdef INDI void SbigCam::UpdateExposure() { // If no expose in progress, then return: if(m_icam_expose_time_np.s != IPS_BUSY) return; int ccd; if(GetSelectedCcdChip(ccd) != CE_NO_ERROR) return; EndExposureParams eep; QueryCommandStatusParams qcsp; QueryCommandStatusResults qcsr; // Query command status: qcsp.command = CC_START_EXPOSURE; if(QueryCommandStatus(&qcsp, &qcsr) != CE_NO_ERROR) return; int mask = 12; // Tracking & external tracking CCD chip mask. if(ccd == CCD_IMAGING) mask = 3; // Imaging chip mask. // Check exposure progress: if((qcsr.status & mask) != mask){ // The exposure is still in progress, decrement an // exposure time: if(--m_icam_expose_time_n[0].value < 0){ m_icam_expose_time_n[0].value = 0; } // Update expose propery, but do not change its status now: IDSetNumber(&m_icam_expose_time_np, 0); return; } // Exposure done - update client's property: eep.ccd = ccd; EndExposure(&eep); // Get image size: #ifdef USE_CCD_FRAME_STANDARD_PROPERTY unsigned short left = (unsigned short)m_icam_ccd_frame_n[0].value; unsigned short top = (unsigned short)m_icam_ccd_frame_n[1].value; unsigned short width = (unsigned short)m_icam_ccd_frame_n[2].value; unsigned short height = (unsigned short)m_icam_ccd_frame_n[3].value; #else unsigned short left = (unsigned short)m_icam_frame_x_n[0].value; unsigned short top = (unsigned short)m_icam_frame_y_n[0].value; unsigned short width = (unsigned short)m_icam_frame_w_n[0].value; unsigned short height = (unsigned short)m_icam_frame_h_n[0].value; #endif // Allocate image buffer: //unsigned short **buffer = AllocateBuffer(width, height); unsigned short *buffer = AllocateBuffer(width, height); if(!buffer) return; // Readout CCD: IDMessage(DEVICE_NAME, "CCD readout in progress..."); if(ReadoutCcd(left, top, width, height, buffer) != CE_NO_ERROR){ ReleaseBuffer(height, buffer); IDMessage(DEVICE_NAME, "CCD readout error!"); return; } // Create unige FITS name: string fits_name = CreateFitsName(); // Write FITS: if(WriteFits(fits_name, width, height, buffer) != CE_NO_ERROR){ ReleaseBuffer(height, buffer); IDMessage(DEVICE_NAME, "WriteFits error!"); return; } // Release image buffer: if(ReleaseBuffer(height, buffer) != CE_NO_ERROR){ IDMessage(DEVICE_NAME, "ReleaseBuffer error!"); return; } // Upload FITS file name: IUFillText(&m_icam_fits_name_t[0], FITS_NAME_T, FITS_LABEL_T, fits_name.c_str()); m_icam_fits_name_tp.s = IPS_OK; IDSetText(&m_icam_fits_name_tp, 0); // Upload FITS file data: if(UploadFits(fits_name) != CE_NO_ERROR) return; // Update exposure time properties: m_icam_expose_time_n[0].value = GetExposeTime(); m_icam_expose_time_np.s = IPS_OK; IDSetNumber(&m_icam_expose_time_np, 0); // Update BLOB property: //SetBlobState(IPS_OK); // Send exposure done message: IDMessage(DEVICE_NAME, "CCD exposure done!"); } #endif // INDI //========================================================================== #ifdef INDI unsigned short *SbigCam::AllocateBuffer(unsigned short width, unsigned short height) { unsigned short *buffer = 0; try { // Allocate new image buffer: //size_t wlen = width * sizeof(unsigned short); buffer = new unsigned short [width * height]; memset(buffer, 0, height * width * sizeof(unsigned short)); //memset(buffer, 0, height * sizeof(unsigned short*)); //for(int h = 0; h < height; h++){ // buffer[h] = new unsigned short [width]; // memset(buffer[h], 0, wlen); //} } catch(bad_alloc &exception) { ReleaseBuffer(height, buffer); buffer = 0; IDMessage(DEVICE_NAME, "Error: AllocateBuffer - exception!"); } return(buffer); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::ReleaseBuffer(unsigned short height, unsigned short *buffer) { if(!buffer) return(CE_NO_ERROR); // Release buffer now: //for(int y = 0; y < height; y++){ // if(buffer[y]) delete [] buffer[y]; //} delete [] buffer; buffer = 0; return(CE_NO_ERROR); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::ReadoutCcd( unsigned short left, unsigned short top, unsigned short width, unsigned short height, unsigned short *buffer) { int h, w, ccd, binning, res; if((res = GetSelectedCcdChip(ccd)) != CE_NO_ERROR) return(res); if((res = GetSelectedCcdBinningMode(binning)) != CE_NO_ERROR) return(res); StartReadoutParams srp; srp.ccd = ccd; srp.readoutMode = binning; srp.left = left; srp.top = top; srp.width = width; srp.height = height; if((res = StartReadout(&srp)) != CE_NO_ERROR){ IDMessage(DEVICE_NAME, "ReadoutCcd - StartReadout error!"); return(res); } // Readout lines. ReadoutLineParams rlp; rlp.ccd = ccd; rlp.readoutMode = binning; rlp.pixelStart = left; rlp.pixelLength = width; // Readout CCD row by row: for(h = 0; h < height; h++){ ReadoutLine(&rlp, buffer + (h * width), false); } // Perform little endian to big endian (network order) // conversion since FITS is stored in big endian. /*for(h = 0; h < height; h++){ for(w = 0 ; w < width; w++){ //buffer[h][w] = GET_BIG_ENDIAN(buffer[h][w] - 32768); buffer[h * width + w] = GET_BIG_ENDIAN(buffer[h * width + w]); } }*/ // End readout: EndReadoutParams erp; erp.ccd = ccd; if((res = EndReadout(&erp)) != CE_NO_ERROR){ IDMessage(DEVICE_NAME, "ReadoutCcd - EndReadout error!"); return(res); } return(res); } #endif // INDI //========================================================================== #ifdef INDI string SbigCam::CreateFitsName() { // Create unige FITS name: // Each file name has a form: XY_YYYY-MM-DDTHH:MM:SS.fits // where XY is: LF for taking light frame // DF for taking dark frame // BF for taking bias frame // FF for taking flat field // XX if file type is not recognized. string frame_type; GetSelectedCcdFrameType(frame_type); string file_name = "XX_"; if(!strcmp(frame_type.c_str(), CCD_FRAME_LIGHT_NAME_N)){ file_name = "LF_"; }else if(!strcmp(frame_type.c_str(), CCD_FRAME_DARK_NAME_N)){ file_name = "DF_"; }else if(!strcmp(frame_type.c_str(), CCD_FRAME_FLAT_NAME_N)){ file_name = "FF_"; }else if(!strcmp(frame_type.c_str(), CCD_FRAME_BIAS_NAME_N)){ file_name = "BF_"; } file_name += GetStartExposureTimestamp() + ".fits"; return(file_name); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::WriteFits( string fits_name, unsigned short width, unsigned short height, unsigned short *buffer) { fitsfile *fptr; /* pointer to the FITS file; defined in fitsio.h */ int status=0; long fpixel = 1, naxis = 2, nelements; long naxes[2]; int res = CE_NO_ERROR; naxes[0] = width; naxes[1] = height; nelements = naxes[0] * naxes[1]; /* number of pixels to write */ // Insert ! to overwrite if file already exists fits_name.insert(0, "!"); /* create new file */ if (fits_create_file(&fptr, fits_name.c_str(), &status)) { IDMessage(DEVICE_NAME, "Error: WriteFits - cannot open FITS file for writing."); return(CE_OS_ERROR); } /* Create the primary array image (16-bit short integer pixels */ if (fits_create_img(fptr, USHORT_IMG, naxis, naxes, &status)) { IDMessage(DEVICE_NAME, "Error: WriteFits - cannot create FITS image."); return(CE_OS_ERROR); } CreateFitsHeader(fptr, width, height); /* Write the array of integers to the image */ if (fits_write_img(fptr, TUSHORT, fpixel, nelements, buffer, &status)) { IDMessage(DEVICE_NAME, "Error: WriteFits - write error occurred."); res = CE_OS_ERROR; } fits_close_file(fptr, &status); /* close the file */ fits_report_error(stderr, status); /* print out any error messages */ return(res); } #endif // INDI // FIXME use CFITSIO #if 0 int res = CE_NO_ERROR; // Open FITS file: FITS_FILE *fp; if(!(fp = fits_open(fits_name.c_str(), "w"))){ IDMessage(DEVICE_NAME, "Error: WriteFits - cannot open FITS file for writing."); return(CE_OS_ERROR); } int bpp = sizeof(unsigned short); // Bytes per Pixel int bpsl = bpp * width; // Bytes per Line // Create FITS header: FITS_HDU_LIST *hdu; if((hdu = CreateFitsHeader(fp, width, height)) == 0){ IDMessage(DEVICE_NAME, "Error: WriteFits - creating FITS header failed."); return(CE_OS_ERROR); } // Write FITS header to the file: if(fits_write_header(fp, hdu) < 0){ IDMessage(DEVICE_NAME, "Error: WriteFits - writing to FITS header failed."); return(CE_OS_ERROR); } // Write 16 bit FITS data: long nbytes = 0; for(int h = 0; h < height; h++){ fwrite(buffer[h], 2, width, fp->fp); nbytes += bpsl; } // Write FITS tail: if((nbytes = nbytes % FITS_RECORD_SIZE)){ while(nbytes++ < FITS_RECORD_SIZE) putc(0, fp->fp); } // Check for errors: if(ferror(fp->fp)){ IDMessage(DEVICE_NAME, "Error: WriteFits - write error occurred."); res = CE_OS_ERROR; } // Close FITS file and return: fits_close(fp); return(res); #endif // INDI //========================================================================== #ifdef INDI void SbigCam::CreateFitsHeader(fitsfile *fptr, unsigned int width, unsigned int height) { char card[FLEN_CARD]; int status=0; double temp_val; fits_update_key(fptr, TSTRING, "INSTRUME", m_icam_product_t[0].text, "CCD Name", &status); fits_update_key(fptr, TSTRING, "DETNAM", m_icam_product_t[1].text, "", &status); temp_val = GetLastExposeTime(); fits_update_key(fptr, TDOUBLE, "EXPTIME", &temp_val, "Total Exposure Time (s)", &status); temp_val = GetLastTemperature(); fits_update_key(fptr, TDOUBLE, "CCD-TEMP", &temp_val, "degrees celcius", &status); fits_update_key(fptr, TDOUBLE, "XPIXSZ", &m_icam_pixel_size_n[0].value, "um", &status); fits_update_key(fptr, TDOUBLE, "YPIXSZ", &m_icam_pixel_size_n[0].value, "um", &status); // XBINNING & YBINNING: int binning; if(GetSelectedCcdBinningMode(binning) == CE_NO_ERROR) { switch(binning) { case CCD_BIN_1x1_I: binning = 1; break; case CCD_BIN_2x2_I: case CCD_BIN_2x2_E: binning = 2; break; case CCD_BIN_3x3_I: case CCD_BIN_3x3_E: binning = 3; break; case CCD_BIN_9x9_I: binning = 9; break; default: binning = 0; break; } fits_update_key(fptr, TINT, "XBINNING", &binning, "1=1x1, 2=2x2, etc.", &status); fits_update_key(fptr, TINT, "YBINNING", &binning, "1=1x1, 2=2x2, etc.", &status); } #ifdef USE_CCD_FRAME_STANDARD_PROPERTY // XORGSUBF: fits_update_key(fptr, TINT, "XORGSUBF", &m_icam_ccd_frame_n[0].value, "", &status); // YORGSUBF: fits_update_key(fptr, TINT, "YORGSUBF", &m_icam_ccd_frame_n[1].value, "", &status); #else // XORGSUBF: fits_update_key(fptr, TINT, "XORGSUBF", &m_icam_frame_x_n[0].value, "", &status); fits_update_key(fptr, TINT, "YORGSUBF", &m_icam_frame_y_n[0].value, "", &status); #endif // IMAGETYP: string str; GetSelectedCcdFrameType(str); if(!strcmp(str.c_str(), CCD_FRAME_LIGHT_NAME_N)){ str = "Light Frame"; }else if(!strcmp(str.c_str(), CCD_FRAME_DARK_NAME_N)){ str = "Dark Frame"; }else if(!strcmp(str.c_str(), CCD_FRAME_FLAT_NAME_N)){ str = "Flat Field"; }else if(!strcmp(str.c_str(), CCD_FRAME_BIAS_NAME_N)){ str = "Bias Frame"; }else{ str = "Unknown"; } char frame[64]; strncpy(frame, str.c_str(), 64); fits_update_key(fptr, TSTRING, "IMAGETYP", frame, "Frame Type", &status); } // FIXME use CFITSIO #if 0 FITS_HDU_LIST *SbigCam::CreateFitsHeader(FITS_FILE *fp, unsigned int width, unsigned int height) { FITS_HDU_LIST *hdu_list; char card[FITS_CARD_SIZE]; // Add a new HDU to the list kept by file pointer: if((hdu_list = fits_add_hdu(fp)) == 0) return(0); // SIMPLE: hdu_list->used.simple = 1; // BITPIX: hdu_list->bitpix = 16; // NAXIS: hdu_list->naxis = 2; // NAXIS1: hdu_list->naxisn[0] = width; // NAXIS2: hdu_list->naxisn[1] = height; // OBJECT: // Should be added by caller. // INSTRUME: snprintf(card, FITS_CARD_SIZE, "INSTRUME= '%s'", m_icam_product_t[0].text); fits_add_card (hdu_list, card); // DETNAM: snprintf(card, FITS_CARD_SIZE, "DETNAM = '%s'", m_icam_product_t[1].text); fits_add_card (hdu_list, card); // OBSERVER: // Should be added by caller. // DATE-OBS: snprintf(card, FITS_CARD_SIZE, "DATE-OBS= '%s' /Observation Date UTC", GetStartExposureTimestamp().c_str()); fits_add_card (hdu_list, card); // BZERO: hdu_list->used.bzero = 1; hdu_list->bzero = 32768.0; // BSCALE: hdu_list->used.bscale = 1; hdu_list->bscale = 1.0; // EXPTIME: snprintf(card, FITS_CARD_SIZE, "EXPTIME = %f / [s]", GetLastExposeTime()); fits_add_card (hdu_list, card); // CCD-TEMP: snprintf(card, FITS_CARD_SIZE, "CCD-TEMP= %f / degrees celcius", GetLastTemperature()); fits_add_card (hdu_list, card); // XPIXSZ: snprintf(card, FITS_CARD_SIZE, "XPIXSZ = %f / [um]", m_icam_pixel_size_n[0].value); fits_add_card (hdu_list, card); // YPIXSZ: snprintf(card, FITS_CARD_SIZE, "YPIXSZ = %f / [um]", m_icam_pixel_size_n[1].value); fits_add_card (hdu_list, card); // XBINNING & YBINNING: int binning; if(GetSelectedCcdBinningMode(binning) == CE_NO_ERROR){ switch(binning){ case CCD_BIN_1x1_I: binning = 1; break; case CCD_BIN_2x2_I: case CCD_BIN_2x2_E: binning = 2; break; case CCD_BIN_3x3_I: case CCD_BIN_3x3_E: binning = 3; break; case CCD_BIN_9x9_I: binning = 9; break; default: binning = 0; break; } snprintf(card, FITS_CARD_SIZE, "XBINNING= %d / 1=1x1, 2=2x2, etc.", binning); fits_add_card (hdu_list, card); snprintf(card, FITS_CARD_SIZE, "YBINNING= %d / 1=1x1, 2=2x2, etc.", binning); fits_add_card (hdu_list, card); } #ifdef USE_CCD_FRAME_STANDARD_PROPERTY // XORGSUBF: snprintf(card, FITS_CARD_SIZE, "XORGSUBF= %d", (int)m_icam_ccd_frame_n[0].value); fits_add_card (hdu_list, card); // YORGSUBF: snprintf(card, FITS_CARD_SIZE, "YORGSUBF= %d", (int)m_icam_ccd_frame_n[1].value); fits_add_card (hdu_list, card); #else // XORGSUBF: snprintf(card, FITS_CARD_SIZE, "XORGSUBF= %d", (int)m_icam_frame_x_n[0].value); fits_add_card (hdu_list, card); // YORGSUBF: snprintf(card, FITS_CARD_SIZE, "YORGSUBF= %d", (int)m_icam_frame_y_n[0].value); fits_add_card (hdu_list, card); #endif // EGAIN: // FOCALLEN: // IMAGETYP: string str; GetSelectedCcdFrameType(str); if(!strcmp(str.c_str(), CCD_FRAME_LIGHT_NAME_N)){ str = "Light Frame"; }else if(!strcmp(str.c_str(), CCD_FRAME_DARK_NAME_N)){ str = "Dark Frame"; }else if(!strcmp(str.c_str(), CCD_FRAME_FLAT_NAME_N)){ str = "Flat Field"; }else if(!strcmp(str.c_str(), CCD_FRAME_BIAS_NAME_N)){ str = "Bias Frame"; }else{ str = "Unknown"; } snprintf(card, FITS_CARD_SIZE, "IMAGETYP= '%s' / Frame type", str.c_str()); fits_add_card (hdu_list, card); return (hdu_list); } // FIXME remove this endif #endif #endif // INDI //========================================================================== #ifdef INDI int SbigCam::UploadFits(string fits_name) { struct stat stat_p; if(stat(fits_name.c_str(), &stat_p) < 0){ IDMessage( DEVICE_NAME, "Error: UploadFits - stat %s.", fits_name.c_str()); return(CE_OS_ERROR); } unsigned long total_bytes = stat_p.st_size; unsigned char *fits_data = (unsigned char *) malloc (sizeof(unsigned char) * total_bytes); if(fits_data == 0){ IDMessage( DEVICE_NAME, "Error: UploadFits - low memory. " "Unable to initialize FITS buffers."); return(CE_OS_ERROR); } #ifdef USE_BLOB_COMPRESS unsigned char *compressed_data = (unsigned char *) malloc(sizeof(unsigned char) * total_bytes + total_bytes / 64 + 16 + 3); if(compressed_data == 0){ IDMessage( DEVICE_NAME, "Error: UploadFits - low memory. " "Unable to initialize FITS buffers."); free (fits_data); return(CE_OS_ERROR); } #endif FILE *fits_file = fopen(fits_name.c_str(), "r"); if(fits_file == 0) { free (fits_data); return(CE_OS_ERROR); } // Read FITS file from disk: unsigned int i = 0, nr = 0; for (i=0; i < total_bytes; i+= nr){ nr = fread(fits_data + i, 1, total_bytes - i, fits_file); if(nr <= 0){ IDMessage(DEVICE_NAME, "Error: UploadFits - reading temporary FITS file."); free(compressed_data); return(CE_OS_ERROR); } } fclose(fits_file); #ifdef USE_BLOB_COMPRESS unsigned long compressed_bytes = sizeof(char) * total_bytes + total_bytes / 64 + 16 + 3; // Compress it: int r = compress2(compressed_data, &compressed_bytes, fits_data, total_bytes, 9); if(r != Z_OK){ // This should NEVER happen. IDMessage(DEVICE_NAME, "Error: UploadFits - compression failed: %d", r); return(CE_OS_ERROR); } #endif // Send BLOB: strcpy(m_icam_fits_b.format, BLOB_FORMAT_B); #ifdef USE_BLOB_COMPRESS m_icam_fits_b.blob = compressed_data; m_icam_fits_b.bloblen = compressed_bytes; #else m_icam_fits_b.blob = fits_data; m_icam_fits_b.bloblen = total_bytes; #endif m_icam_fits_b.size = total_bytes; m_icam_fits_bp.s = IPS_OK; //IDMessage(DEVICE_NAME, "--> Format : %s", m_icam_fits_b.format); //IDMessage(DEVICE_NAME, "--> Bytes : %u", m_icam_fits_b.bloblen); //IDMessage(DEVICE_NAME, "--> nbp : %d", m_icam_fits_bp.nbp); //IDMessage(DEVICE_NAME, "--> Size : %u", m_icam_fits_b.size); //IDMessage(DEVICE_NAME, "==> IDSetBLOB start..."); IDSetBLOB(&m_icam_fits_bp, 0); //IDMessage(DEVICE_NAME, "==> IDSetBLOB stop..."); // Remove FITS file from the server site: remove(fits_name.c_str()); // Release memory: free(fits_data); #ifdef USE_BLOB_COMPRESS free(compressed_data); #endif return(CE_NO_ERROR); } #endif // INDI //========================================================================== #ifdef INDI void SbigCam::SetBlobState(IPState state) { strcpy(m_icam_fits_b.format, BLOB_FORMAT_B); m_icam_fits_b.blob = 0; m_icam_fits_b.bloblen = 0; m_icam_fits_b.size = 0; m_icam_fits_bp.s = state; m_icam_fits_bp.bp = &m_icam_fits_b; IDSetBLOB(&m_icam_fits_bp, 0); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::CfwConnect() { int res; CFWResults cfwr; ISwitch *p = IUFindOnSwitch(&m_icfw_type_sp); if(!p) return(CE_OS_ERROR); do{ // 1. CFWC_OPEN_DEVICE: if((res = CfwOpenDevice(&cfwr)) != CE_NO_ERROR){ m_icfw_connection_sp.s = IPS_IDLE; IDMessage(DEVICE_NAME, "CFWC_OPEN_DEVICE error: %s !", GetErrorString(res).c_str()); continue; } // 2. CFWC_INIT: if((res = CfwInit(&cfwr)) != CE_NO_ERROR){ IDMessage( DEVICE_NAME, "CFWC_INIT error: %s !", GetErrorString(res).c_str()); CfwCloseDevice(&cfwr); IDMessage(DEVICE_NAME, "CFWC_CLOSE_DEVICE called."); continue; } // 3. CFWC_GET_INFO: if((res = CfwGetInfo(&cfwr)) != CE_NO_ERROR){ IDMessage(DEVICE_NAME, "CFWC_GET_INFO error!"); continue; } // 4. CfwUpdateProperties: CfwUpdateProperties(cfwr); // 5. Set CFW's filter min/max values: m_icfw_slot_n[0].min = 1; m_icfw_slot_n[0].max = cfwr.cfwResult2; IUUpdateMinMax(&m_icfw_slot_np); }while(0); return(res); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::CfwDisconnect() { CFWResults cfwr; ISwitch *p = IUFindOnSwitch(&m_icfw_type_sp); if(!p) return(CE_OS_ERROR); // Close CFW device: return(CfwCloseDevice(&cfwr)); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::CfwOpenDevice(CFWResults *cfwr) { // Under Linux we always try to open the "sbigcfw" device. There has to be a // symbolic link (ln -s) between the actual device and this name. CFWParams cfwp; int res = CE_NO_ERROR; int cfwModel = GetCfwSelType(); switch(cfwModel){ case CFWSEL_CFW10_SERIAL: cfwp.cfwModel = cfwModel; cfwp.cfwCommand = CFWC_OPEN_DEVICE; res = SBIGUnivDrvCommand(CC_CFW, &cfwp, cfwr); break; default: break; } return(res); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::CfwCloseDevice(CFWResults *cfwr) { CFWParams cfwp; cfwp.cfwModel = GetCfwSelType(); cfwp.cfwCommand = CFWC_CLOSE_DEVICE; return(SBIGUnivDrvCommand(CC_CFW, &cfwp, cfwr)); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::CfwInit(CFWResults *cfwr) { // Try to init CFW maximum three times: int res; CFWParams cfwp; cfwp.cfwModel = GetCfwSelType(); cfwp.cfwCommand = CFWC_INIT; for(int i=0; i < 3; i++){ if((res = SBIGUnivDrvCommand(CC_CFW, &cfwp, cfwr)) == CE_NO_ERROR) break; sleep(1); } if(res != CE_NO_ERROR) return(res); return(CfwGotoMonitor(cfwr)); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::CfwGetInfo(CFWResults *cfwr) { CFWParams cfwp; cfwp.cfwModel = GetCfwSelType(); cfwp.cfwCommand = CFWC_GET_INFO; cfwp.cfwParam1 = CFWG_FIRMWARE_VERSION; return(SBIGUnivDrvCommand(CC_CFW, &cfwp, cfwr)); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::CfwQuery(CFWResults *cfwr) { CFWParams cfwp; cfwp.cfwModel = GetCfwSelType(); cfwp.cfwCommand = CFWC_QUERY; return(SBIGUnivDrvCommand(CC_CFW, &cfwp, cfwr)); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::CfwGoto(CFWResults *cfwr) { int res; CFWParams cfwp; cfwp.cfwModel = GetCfwSelType(); cfwp.cfwCommand = CFWC_GOTO; cfwp.cfwParam1 = (unsigned long)m_icfw_slot_n[0].value; if((res = SBIGUnivDrvCommand(CC_CFW, &cfwp, cfwr)) != CE_NO_ERROR) return(res); return(CfwGotoMonitor(cfwr)); } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::CfwGotoMonitor(CFWResults *cfwr) { int res; do{ if((res = CfwQuery(cfwr)) != CE_NO_ERROR) return(res); }while(cfwr->cfwStatus != CFWS_IDLE); return(res); } #endif // INDI //========================================================================== #ifdef INDI void SbigCam::CfwUpdateProperties(CFWResults cfwr) { char str[64]; bool bClear = false; switch(cfwr.cfwModel){ case CFWSEL_CFW2: sprintf(str, "%s", "CFW - 2"); break; case CFWSEL_CFW5: sprintf(str, "%s", "CFW - 5"); break; case CFWSEL_CFW6A: sprintf(str, "%s", "CFW - 6A"); break; case CFWSEL_CFW8: sprintf(str, "%s", "CFW - 8"); break; case CFWSEL_CFW402: sprintf(str, "%s", "CFW - 402"); break; case CFWSEL_CFW10: sprintf(str, "%s", "CFW - 10"); break; case CFWSEL_CFW10_SERIAL: sprintf(str, "%s", "CFW - 10SA"); break; case CFWSEL_CFWL: sprintf(str, "%s", "CFW - L"); break; default: sprintf(str, "%s", "Unknown"); bClear = true; break; } // Set CFW's product ID: IText *pIText = IUFindText(&m_icfw_product_tp, PRODUCT_NAME_T); if(pIText) IUSaveText(pIText, str); // Set CFW's firmware version: if(bClear){ sprintf(str, "%s", "Unknown"); }else{ sprintf(str, "%d", (int)cfwr.cfwResult1); } pIText = IUFindText(&m_icfw_product_tp, PRODUCT_ID_NAME_T); if(pIText) IUSaveText(pIText, str); m_icfw_product_tp.s = IPS_OK; IDSetText(&m_icfw_product_tp, 0); // Set CFW's filter min/max values: if(!bClear){ m_icfw_slot_n[0].min = 1; m_icfw_slot_n[0].max = cfwr.cfwResult2; IUUpdateMinMax(&m_icfw_slot_np); } } #endif // INDI //========================================================================== #ifdef INDI int SbigCam::GetCfwSelType() { int type = CFWSEL_UNKNOWN;; ISwitch *p = IUFindOnSwitch(&m_icfw_type_sp); if(p){ if(!strcmp(p->name, CFW1_NAME_S)){ type = CFWSEL_CFW2; }else if(!strcmp(p->name, CFW2_NAME_S)){ type = CFWSEL_CFW5; }else if(!strcmp(p->name, CFW3_NAME_S)){ type = CFWSEL_CFW6A; }else if(!strcmp(p->name, CFW4_NAME_S)){ type = CFWSEL_CFW8; }else if(!strcmp(p->name, CFW5_NAME_S)){ type = CFWSEL_CFW402; }else if(!strcmp(p->name, CFW6_NAME_S)){ type = CFWSEL_CFW10; }else if(!strcmp(p->name, CFW7_NAME_S)){ type = CFWSEL_CFW10_SERIAL; }else if(!strcmp(p->name, CFW8_NAME_S)){ type = CFWSEL_CFWL; #ifdef USE_CFW_AUTO }else if(!strcmp(p->name, CFW9_NAME_S)){ type = CFWSEL_AUTO; #endif } } return(type); } #endif // INDI //========================================================================== #ifdef INDI void SbigCam::CfwShowResults(string name, CFWResults cfwr) { IDMessage(DEVICE_NAME, "%s", name.c_str()); IDMessage(DEVICE_NAME, "CFW Model: %d", cfwr.cfwModel); IDMessage(DEVICE_NAME, "CFW Position: %d", cfwr.cfwPosition); IDMessage(DEVICE_NAME, "CFW Status: %d", cfwr.cfwStatus); IDMessage(DEVICE_NAME, "CFW Error: %d", cfwr.cfwError); IDMessage(DEVICE_NAME, "CFW Result1: %ld", cfwr.cfwResult1); IDMessage(DEVICE_NAME, "CFW Result2: %ld", cfwr.cfwResult2); } #endif // INDI //========================================================================== indi-0.5/src/temmadriver.h0000644000175000017500000002137410610474336013403 0ustar jrjr/* Temma INDI driver Copyright (C) 2004 Francois Meyer (dulle @ free.fr) Remi Petitdemange for the temma protocol Reference site is http://dulle.free.fr/alidade/indi.php This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef TEMMADRIVER_H #define TEMMADRIVER_H #define VERSION "Temma indi driver Ver 0.0, fm-2004/10/09" #if 0 bit definition for M message : slew speed and parameters #endif #define HS 0x01 /* high speed */ #define RR 0x02 /* RA right */ #define RL 0x04 /* RA left */ #define DU 0x08 /* DEC up */ #define DD 0x10 /* DEC down */ #define EN 0x20 /* ENC on */ #define BB 0x40 /* Always set */ #if 0 (HS|RR|EN|BB) #endif #define HRAD (M_PI/12) #define DEGRAD (M_PI/180) #define TEMMA_TIMEOUT 1 /* FD timeout in seconds */ /* error codes */ #define SUCCESS (2) /* return value for successful read */ #define ETIMEOUT (-2) /* timeout */ #define EREAD (-3) /* error reading from port */ #define EWRITE (-4) /* error writing to port */ #define ECOMMAND (-5) /* unexpected answer */ /* Definitions */ #define mydev "Temma" /* Device name */ #define MAIN_GROUP "Main Control" /* Group name */ #define COMM_GROUP "Communication" /* Group name */ #define MOVE_GROUP "Movement Control" #define DATETIME_GROUP "Date/Time/Location" #define SLEWSW OnCoordSetS[0].s #define SYNCSW OnCoordSetS[1].s #define TRACKSW OnCoordSetS[2].s #define POWSW (power[0].s==ISS_ON) #define SLEWRATE 1 /* slew rate, degrees/s */ #define POLLMS 1000 /* poll period, ms */ #define latitude geo[0].value /* scope's current rads. */ #define longitude geo[1].value /* scope's current rads. */ #define currentUTC UTC[0].value /* scope's current rads. */ #define currentLST STime[0].value /* scope's current rads. */ #define currentRA eq[0].value /* scope's current RA, rads. */ #define currentDec eq[1].value /* scope's current Dec, rads. */ #define temmaRA eqtem[0].value /* scope's current RA, rads. */ #define temmaDec eqtem[1].value /* scope's current Dec, rads. */ int openPort(const char *portID); int portRead(char *buf, int nbytes, int timeout); int portWrite(char * buf); int TemmareadOut(int timeout); static void mountInit(void); void ISGetProperties (const char *dev); void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n); void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); double calcLST(char *strlst); int TemmaConnect(const char *device) ; int TemmaDisconnect(void) ; int set_CometTracking(int RArate, int DECrate); int TemmaabortSlew(void) ; int do_TemmaGOTO(void) ; int extractRA(char *buf); int extractDEC(char *buf); int get_TemmaCurrentpos(char *buffer); int set_TemmaCurrentpos(void) ; int do_TemmaSLEW(char mode); int get_TemmaVERSION(char *buffer); int get_TemmaGOTOstatus(char *buffer); int get_TemmaBOTHcorrspeed(char *buffer); int get_TemmaDECcorrspeed(char *buffer); int set_TemmaDECcorrspeed(char *buffer); int get_TemmaRAcorrspeed(char *buffer); int set_TemmaRAcorrspeed(char *buffer); int get_TemmaLatitude(char *buffer); int set_TemmaLatitude(char *buffer); int get_TemmaLST(char *buffer); int set_TemmaLST(char *buffer); int set_TemmaStandbyState(int on); int get_TemmaStandbyState(unsigned char *buffer); int get_TemmaCometTracking(char *buffer); int set_TemmaCometTracking(char *buffer); int set_TemmaSolarRate(void); int set_TemmaStellarRate(void); int switch_Temmamountside(void); static void disconnectMount (void); static void connectMount (void); static void readMountcurrentpos (void *); /***************************/ /* RA motor control switch */ /***************************/ static ISwitch RAmotor[] = { {"RUN", "On", ISS_OFF, 0, 0}, {"STOP", "Off", ISS_ON, 0, 0} }; static ISwitchVectorProperty RAmotorSw = { mydev, "RA motor", "RA motor", MOVE_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE, RAmotor, NARRAY(RAmotor), "", 0}; /*****************************/ /* Track mode control switch */ /*****************************/ static ISwitch trackmode[] = { {"Sidereal", "Sidereal", ISS_ON, 0, 0}, {"Lunar", "Lunar", ISS_OFF, 0, 0}, {"Comet", "Comet", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty trackmodeSw = { mydev, "Tracking mode", "Tracking mode", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, trackmode, NARRAY(trackmode), "", 0}; /*****************************/ /* Power control switch */ /*****************************/ static ISwitch power[] = { {"CONNECT", "On", ISS_OFF, 0, 0}, {"DISCONNECT", "Off", ISS_ON, 0, 0}, }; static ISwitchVectorProperty powSw = { mydev, "CONNECTION", "Connection", MAIN_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE, power, NARRAY(power), "", 0}; /*******************************/ /* Temma version text property */ /*******************************/ static IText TemmaVersionT[] = {{"VERSION", "Version", 0, 0, 0, 0}}; static ITextVectorProperty TemmaVersion = { mydev, "VERSION", "Temma version", COMM_GROUP, IP_RO, 0, IPS_OK, TemmaVersionT, NARRAY(TemmaVersionT), "", 0}; /*******************************/ /* Driver notes text property */ /*******************************/ static IText TemmaNoteT[] = {{"Note", "", 0, 0, 0, 0}, {"Feedback", "", 0, 0,0 ,0}}; static ITextVectorProperty TemmaNoteTP = { mydev, "Temma Driver", "", MAIN_GROUP, IP_RO, 0, IPS_OK, TemmaNoteT, NARRAY(TemmaNoteT), "", 0}; /*******************************/ /* Port names text property */ /*******************************/ static IText PortT[] = {{"PORT", "Port", 0, 0, 0, 0}}; static ITextVectorProperty Port = { mydev, "DEVICE_PORT", "Ports", COMM_GROUP, IP_RW, 0, IPS_OK, PortT, NARRAY(PortT), "", 0}; /*******************************/ /* EQUATORIAL_COORD RW property */ /*******************************/ static INumber eq[] = { {"RA" ,"RA H:M:S" , "%10.6m", 0, 24, 0, 0, 0, 0, 0}, {"DEC", "Dec D:M:S", "%10.6m", -90, 90, 0, 0, 0, 0, 0} }; static INumberVectorProperty eqNum = { mydev, "EQUATORIAL_EOD_COORD", "Equatorial JNow", MAIN_GROUP , IP_RW, 0, IPS_IDLE, eq, NARRAY(eq), "", 0}; /*******************************/ /* MOUNT_COORD RO property */ /*******************************/ static INumber eqtem[] = { {"RA", "RA H:M:S", "%10.6m", 0, 24, 0, 0, 0, 0, 0}, {"DEC", "Dec D:M:S", "%10.6m", -90, 90, 0, 0, 0, 0, 0} }; static INumberVectorProperty eqTemma = { mydev, "Temma", "Mount coordinates", MAIN_GROUP , IP_RO, 0, IPS_IDLE, eqtem, NARRAY(eqtem), "", 0}; /* Traccking correction parameters (i.e. to track comets) */ static INumber comet[] = { {"RAcorrspeed","Comet RA motion arcmin/day","%+5d",-21541,21541,0,0,0,0,0}, {"DECcor rspeed", "Comet DEC motion arcmin/day", "%+4d", -600, 600,0, 0., 0, 0, 0} }; static INumberVectorProperty cometNum = { mydev, "COMET_TRACKING", "Comet tracking parameters", MOVE_GROUP, IP_RW, 0, IPS_IDLE, comet, NARRAY(comet), "", 0}; /* Date & Time */ static INumber UTC[] = { {"UTC", "UTC", "%10.6m" , 0.,0.,0.,0., 0, 0, 0}}; INumberVectorProperty Time = { mydev, "TIME_UTC", "UTC Time", DATETIME_GROUP, IP_RW, 0, IPS_IDLE, UTC, NARRAY(UTC), "", 0}; static INumber STime[] = { {"LST", "Sidereal time", "%10.6m" , 0.,0.,0.,0., 0, 0, 0}}; INumberVectorProperty SDTime = { mydev, "TIME_LST", "Sidereal Time", DATETIME_GROUP, IP_RW, 0, IPS_IDLE, STime, NARRAY(STime), "", 0}; static ISwitch OnCoordSetS[] = { {"SLEW", "Goto", ISS_OFF, 0, 0 }, {"SYNC", "Sync", ISS_ON, 0 , 0}, {"TRACK", "Track", ISS_OFF, 0, 0 }}; static ISwitchVectorProperty OnCoordSetSw = { mydev, "ON_COORD_SET", "On Set", MAIN_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, OnCoordSetS, NARRAY(OnCoordSetS), "", 0}; static ISwitch abortSlewS[] = { {"ABORT", "Abort", ISS_OFF, 0, 0 }}; static ISwitchVectorProperty abortSlewSw = { mydev, "ABORT_MOTION", "******* ABORT GOTO *********", MAIN_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, abortSlewS, NARRAY(abortSlewS), "", 0}; /* geographic location */ static INumber geo[] = { {"LAT", "Lat. D:M:S +N", "%10.6m", -90., 90., 0., 0., 0, 0, 0}, {"LONG", "Long. D:M:S +E", "%10.6m", 0., 360., 0., 0., 0, 0, 0} }; static INumberVectorProperty geoNum = { mydev, "GEOGRAPHIC_COORD", "Geographic Location", DATETIME_GROUP, IP_RW, 0., IPS_IDLE, geo, NARRAY(geo), "", 0}; #endif indi-0.5/src/stv.c0000644000175000017500000014253210610506255011667 0ustar jrjr#if 0 STV Driver Copyright (C) 2006 Markus Wildi, markus.wildi@datacomm.ch This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301 USA #endif /* Standard headers */ #include #include #include #include #include #ifndef _WIN32 #include #endif /* INDI Core headers */ #include "indidevapi.h" /* INDI Eventloop mechanism */ #include "eventloop.h" /* INDI Common Routines/RS232 */ #include "indicom.h" /* Fits */ #include "cfitsio/fitsio.h" /* STV's definitions */ #include "stvdriver.h" /* Definitions */ #define mydev "STV Guider" /* Device name */ #define CONNECTION_GROUP "Connection" /* Group name */ #define SETTINGS_GROUP "Setings" /* Group name */ #define BUTTONS_GROUP "Buttons and Knobs" /* Button Pannel */ #define IMAGE_GROUP "Download" /* Button Pannel */ #define currentBuffer BufferN[0].value #define currentX WindowingN[0].value #define currentY WindowingN[1].value #define currentLines WindowingN[2].value #define currentLength WindowingN[3].value #define currentCompression CompressionS[0].s static int compression= OFF ; static int acquiring= OFF ; static int guiding= OFF ; static int processing= OFF ; /* Fits (fli_ccd project) */ enum STVFrames { LIGHT_FRAME = 0, BIAS_FRAME, DARK_FRAME, FLAT_FRAME }; #define TEMPFILE_LEN 16 /* Image (fli_ccd project)*/ typedef struct { int width; int height; int frameType; int expose; unsigned short *img; } img_t; static img_t *STVImg; /* Function adapted from fli_ccd project */ void addFITSKeywords(fitsfile *fptr, IMAGE_INFO *image_info) ; int writeFITS(const char* filename, IMAGE_INFO *image_info, char errmsg[]) ; void uploadFile(const char* filename) ; /* File descriptor and call back id */ int fd ; static int cb= -1 ; char tracking_buf[1024] ; /* Function prototypes */ int ISTerminateTXDisplay(void) ; int ISRestoreTXDisplay(void) ; int ISMessageImageInfo( int buffer, IMAGE_INFO *image_info) ; int ISRequestImageData( int compression, int buffer, int x_offset, int y_offset, int length, int lines) ; int STV_LRRotaryDecrease(void) ; int STV_LRRotaryIncrease(void) ; int STV_UDRotaryDecrease(void) ; int STV_UDRotaryIncrease(void) ; int STV_AKey(void) ; int STV_BKey(void) ; int STV_Setup(void) ; int STV_Interrupt(void) ; int STV_Focus(void) ; int STV_Image(void) ; int STV_Monitor(void) ; int STV_Calibrate(void) ; int STV_Track(void) ; int STV_Display(void) ; int STV_FileOps(void) ; int STV_RequestImageInfo(int imagebuffer, IMAGE_INFO *image_info) ; int STV_BufferStatus(int buffer) ; int STV_RequestImage( int compression, int buffer, int x_offset, int y_offset, int *length, int *lines, int image[][320], IMAGE_INFO *image_info) ; int STV_Download( void) ; int STV_TXDisplay(void) ; int STV_TerminateTXDisplay(void) ; int STV_RequestAck(void) ; unsigned int STV_GetBits( unsigned int x, int p, int n) ; int STV_PrintBuffer( unsigned char *cmdbuf, int n ); void handleError(ISwitchVectorProperty *svp, int err, const char *msg) ; static void ISInit() ; void ISCallBack(void) ; int init_serial(char *device_name, int bit_rate, int word_size, int parity, int stop_bits) ; int STV_ReceivePacket( unsigned char *buf, int mode) ; int STV_Connect( char *device, int baud) ; int STV_SetDateTime( char *times) ; double STV_SetCCDTemperature(double set_value) ; static IText StatusT[]= { {"STATUS", "This driver", "is experimental, contact markus.wildi@datacomm.ch", 0, 0, 0}, }; static ITextVectorProperty StatusTP= { mydev, "STAUS", "Status", CONNECTION_GROUP, IP_RO, ISR_1OFMANY, IPS_IDLE, StatusT, NARRAY(StatusT), "", 0 } ; /* RS 232 Connection */ static ISwitch PowerS[] = { {"CONNECT", "Connect", ISS_OFF, 0, 0}, {"DISCONNECT", "Disconnect", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty PowerSP = { mydev, "CONNECTION", "Connection", CONNECTION_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0 }; /* Serial Port */ static IText PortT[]= { {"PORT", "Port", NULL, 0, 0, 0}, {"SPEED", "Speed", NULL, 0, 0, 0} }; static ITextVectorProperty PortTP= { mydev, "DEVICE_PORT", "Port", CONNECTION_GROUP, IP_RW, ISR_1OFMANY, IPS_IDLE, PortT, NARRAY(PortT), "", 0 } ; static ISwitch TXDisplayS[]= { {"1", "On", ISS_ON, 0, 0}, {"2", "Off", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty TXDisplaySP= { mydev, "Update Display", "Update Display", CONNECTION_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, TXDisplayS, NARRAY(TXDisplayS), "", 0 } ; static IText DisplayCT[]= { {"DISPLAYC1", "Line 1", NULL, 0, 0, 0}, {"DISPLAYC2", "Line 2", NULL, 0, 0, 0} }; static ITextVectorProperty DisplayCTP= { mydev, "DISPLAYC", "Display", CONNECTION_GROUP, IP_RO, ISR_1OFMANY, IPS_IDLE, DisplayCT, NARRAY(DisplayCT), "", 0 } ; static IText DisplayBT[]= { {"DISPLAYB1", "Line 1", NULL, 0, 0, 0}, {"DISPLAYB2", "Line 2", NULL, 0, 0, 0} }; static ITextVectorProperty DisplayBTP= { mydev, "DISPLAYB", "Display", BUTTONS_GROUP, IP_RO, ISR_1OFMANY, IPS_IDLE, DisplayBT, NARRAY(DisplayBT), "", 0 } ; static IText DisplayDT[]= { {"DISPLAYD1", "Line 1", NULL, 0, 0, 0}, {"DISPLAYD2", "Line 2", NULL, 0, 0, 0} }; static ITextVectorProperty DisplayDTP= { mydev, "DISPLAYD", "Display", IMAGE_GROUP, IP_RO, ISR_1OFMANY, IPS_IDLE, DisplayDT, NARRAY(DisplayDT), "", 0 } ; /* Setings */ static IText UTCT[] = {{"UTC", "UTC", NULL, 0, 0, 0}}; ITextVectorProperty UTCTP = { mydev, "TIME_UTC", "UTC Time", SETTINGS_GROUP, IP_RW, 0, IPS_IDLE, UTCT, NARRAY(UTCT), "", 0}; static INumber SetCCDTemperatureN[]= { { "TEMPERATURE", "Cel. -55.1, +25.2", "%6.1f", -55.8, 25.2, 0.,16., 0, 0, 0}, } ; static INumberVectorProperty SetCCDTemperatureNP= { mydev, "CCD_TEMPERATURE", "CCD Temperature", SETTINGS_GROUP, IP_RW, ISR_1OFMANY, IPS_IDLE, SetCCDTemperatureN, NARRAY(SetCCDTemperatureN), "", 0 } ; /* Buttons */ static ISwitch ControlS[]= { {"1", "Parameter", ISS_OFF, 0, 0}, {"2", "Increase", ISS_OFF, 0, 0}, {"3", "Decrease", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty ControlSP= { mydev, "ParaButtons", "Control", BUTTONS_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, ControlS, NARRAY(ControlS), "", 0 } ; static ISwitch ValueS[]= { {"1", "Value", ISS_OFF, 0, 0}, {"2", "Increase", ISS_OFF, 0, 0}, {"3", "Decrease", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty ValueSP= { mydev, "ValueButtons", "Control", BUTTONS_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, ValueS, NARRAY(ValueS), "", 0 } ; static ISwitch AuxiliaryS[]= { {"1", "Setup", ISS_OFF, 0, 0}, {"2", "Interrupt", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty AuxiliarySP= { mydev, "Auxilliary", "", BUTTONS_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, AuxiliaryS, NARRAY(AuxiliaryS), "", 0 } ; static ISwitch AcquireS[]= { {"1", "Focus", ISS_OFF, 0, 0}, {"2", "Image", ISS_OFF, 0, 0}, {"3", "Monitor", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty AcquireSP= { mydev, "Acquire", "", BUTTONS_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, AcquireS, NARRAY(AcquireS), "", 0 } ; static ISwitch GuideS[]= { {"1", "Calibrate", ISS_OFF, 0, 0}, {"2", "Track", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty GuideSP= { mydev, "Guide", "", BUTTONS_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, GuideS, NARRAY(GuideS), "", 0 } ; static ISwitch ProcessS[]= { {"1", "Display/Crosshairs", ISS_OFF, 0, 0}, {"2", "File Ops", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty ProcessSP= { mydev, "Process", "", BUTTONS_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, ProcessS, NARRAY(ProcessS), "", 0 } ; static ISwitch CompressionS[]= { {"1", "On", ISS_OFF, 0, 0}, {"2", "Off", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty CompressionSP= { mydev, "Compression", "", IMAGE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, CompressionS, NARRAY(CompressionS), "", 0 } ; static ISwitch BufferStatusS[]= { {"1", "Status", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty BufferStatusSP= { mydev, "Buffers", "", IMAGE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, BufferStatusS, NARRAY(BufferStatusS), "", 0 } ; static INumber BufferN[]= { { "A0", "Number 1 - 32", "%6.0f", 1., 32., 0.,32., 0, 0, 0}, } ; static INumberVectorProperty BufferNP= { mydev, "BUFFER_Number", "Buffer", IMAGE_GROUP, IP_RW, ISR_1OFMANY, IPS_IDLE, BufferN, NARRAY(BufferN), "", 0 } ; static INumber WindowingN[]= { { "X", "Offset x", "%6.0f", 0., 199., 0., 0., 0, 0, 0}, { "Y", "Offset y", "%6.0f", 0., 319., 0., 0., 0, 0, 0}, { "HEIGHT", "Lines", "%6.0f", 1., 200., 0., 200., 0, 0, 0}, { "WIDTH", "Length", "%6.0f", 1., 320., 0., 320., 0, 0, 0}, } ; static INumberVectorProperty WindowingNP= { mydev, "CCD_FRAME", "Windowing", IMAGE_GROUP, IP_RW, ISR_1OFMANY, IPS_IDLE, WindowingN, NARRAY(WindowingN), "", 0 } ; static ISwitch ImageInfoS[]= { {"1", "One Image", ISS_OFF, 0, 0}, {"2", "All Images", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty ImageInfoSP= { mydev, "Information", "", IMAGE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, ImageInfoS, NARRAY(ImageInfoS), "", 0 } ; static ISwitch DownloadS[]= { {"1", "One Image", ISS_OFF, 0, 0}, {"2", "All Images", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty DownloadSP= { mydev, "Download", "", IMAGE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, DownloadS, NARRAY(DownloadS), "", 0 } ; /* BLOB for sending image */ static IBLOB imageB= {"CCD1", "Image", "", 0, 0, 0, 0, 0, 0, 0}; static IBLOBVectorProperty imageBP= {mydev, "Image", "Image", IMAGE_GROUP, IP_RO, 0, IPS_IDLE, &imageB, 1, "", 0}; /* Initlization routine */ static void ISInit() { static int isInit= 0; if( isInit) return; IUSaveText( &PortT[0], "/dev/ttyUSB0"); IUSaveText( &PortT[1], "115200"); if(( DisplayCT[0].text= malloc( 1024))== NULL){ fprintf(stderr,"3:Memory allocation error"); return; } if((DisplayCT[1].text = malloc( 1024))== NULL){ fprintf(stderr,"4:Memory allocation error"); return; } if(( DisplayBT[0].text= malloc( 1024))== NULL){ fprintf(stderr,"5:Memory allocation error"); return; } if(( DisplayBT[1].text= malloc( 1024))== NULL){ fprintf(stderr,"5:Memory allocation error"); return; } if(( DisplayDT[0].text= malloc( 1024))== NULL){ fprintf(stderr,"7:Memory allocation error"); return; } if(( DisplayDT[1].text= malloc( 1024))== NULL){ fprintf(stderr,"8:Memory allocation error"); return; } if(( STVImg= malloc( sizeof(img_t)))== NULL){ fprintf(stderr,"9:Memory allocation error"); return; } isInit = 1; } void ISResetButtons( char *message) { ControlSP.s= IPS_IDLE ; IUResetSwitches(&ControlSP); IDSetSwitch(&ControlSP, NULL); ValueSP.s= IPS_IDLE ; IUResetSwitches(&ValueSP); IDSetSwitch(&ValueSP, NULL); AuxiliarySP.s= IPS_IDLE ; IUResetSwitches(&AuxiliarySP); IDSetSwitch(&AuxiliarySP, NULL); AcquireSP.s= IPS_IDLE ; IUResetSwitches(&AcquireSP); IDSetSwitch(&AcquireSP, NULL); GuideSP.s= IPS_IDLE ; IUResetSwitches(&GuideSP); IDSetSwitch(&GuideSP, NULL); ProcessSP.s= IPS_IDLE ; IUResetSwitches(&ProcessSP); IDSetSwitch(&ProcessSP, NULL); ImageInfoSP.s= IPS_IDLE ; IUResetSwitches(&ImageInfoSP); IDSetSwitch(&ImageInfoSP, NULL); BufferStatusSP.s= IPS_IDLE ; IUResetSwitches(&BufferStatusSP); IDSetSwitch(&BufferStatusSP, NULL); /* SP.s= IPS_IDLE ; */ /* IUResetSwitches(&SP); */ /* IDSetSwitch(&SP, NULL); */ DownloadSP.s= IPS_IDLE ; IUResetSwitches(&DownloadSP); IDSetSwitch(&DownloadSP, "%s", message); return ; } /* This function is called when ever the file handle fd provides data */ void ISCallBack() { int res ; int k,l,m ; unsigned char buf[1024] ; IERmCallback( cb) ; cb = -1 ; /* fprintf( stderr, "ISCallBack\n") ; */ /* if(( counter++ % 4) ==0){ */ /* fprintf( stderr, ".") ; */ /* } */ if( PowerS[0].s == ISS_ON) { res= STV_ReceivePacket( buf, guiding) ; /* res= STV_PrintBuffer(buf,res) ; */ DisplayCTP.s= IPS_IDLE ; IDSetText( &DisplayCTP, NULL) ; DisplayBTP.s= IPS_IDLE ; IDSetText( &DisplayBTP, NULL) ; DisplayDTP.s= IPS_IDLE ; IDSetText( &DisplayDTP, NULL) ; switch ((int) buf[1]) { /* STV cmd byte */ case DISPLAY_ECHO: if( res < 0 ) { DisplayCTP.s= IPS_ALERT ; IDSetText( &DisplayCTP, NULL) ; DisplayBTP.s= IPS_ALERT ; IDSetText( &DisplayBTP, NULL) ; DisplayDTP.s= IPS_ALERT ; IDSetText( &DisplayDTP, NULL) ; IDMessage(mydev, "Error while reading, continuing\n"); } else { l= 0 ; m= 0 ; /* replace unprintable characters and format the string */ for( k= 0; k < 24; k++) { if( buf[k+ 6]== 0x5e) { /* first line */ DisplayCT[0].text[l-1]= 0x50 ; /* P */ DisplayCT[0].text[l++] = 0x6b ; /* k */ } else if( buf[k+ 6]== 0xd7) { DisplayCT[0].text[l++]= 0x28 ; /* "(x,y) " */ DisplayCT[0].text[l++]= 0x78 ; DisplayCT[0].text[l++]= 0x2c ; DisplayCT[0].text[l++]= 0x79 ; DisplayCT[0].text[l++]= 0x29 ; DisplayCT[0].text[l++]= 0x20 ; } else if( buf[k+ 6] >29 && buf[k+ 6] < 127) { DisplayCT[0].text[l++]= buf[k+ 6] ; } else { /* fprintf(stderr, "LINE 1%2x, %2x, %2x, %c %c %c\n", buf[k+ 5], buf[k+ 6], buf[k+ 7], buf[k+ 5], buf[k+ 6], buf[k+ 7]) ; */ DisplayCT[0].text[l++]= 0x20 ; } if( buf[k+ 30]== 0xb0){ /* second line */ DisplayCT[1].text[m++]= 0x43 ; /* Celsius */ } else if( buf[k+ 30] >29 && buf[k +30] < 127) { DisplayCT[1].text[m++]=buf[k + 30] ; } else { /* fprintf(stderr, "LINE 2 %2x, %2x, %2x, %c %c %c\n", buf[k+ 29], buf[k+ 30], buf[k+ 31], buf[k+ 29], buf[k+ 30], buf[k+ 31]) ; */ DisplayCT[1].text[m++]= 0x20 ; } } DisplayCT[0].text[l]= 0 ; DisplayCT[1].text[m]= 0 ; strcpy(DisplayBT[0].text, DisplayCT[0].text) ; strcpy(DisplayBT[1].text, DisplayCT[1].text) ; strcpy(DisplayDT[0].text, DisplayCT[0].text) ; strcpy(DisplayDT[1].text, DisplayCT[1].text) ; DisplayCTP.s= IPS_OK ; IDSetText( &DisplayCTP, NULL) ; DisplayBTP.s= IPS_OK ; IDSetText( &DisplayBTP, NULL) ; DisplayDTP.s= IPS_OK ; IDSetText( &DisplayDTP, NULL) ; } break ; case REQUEST_DOWNLOAD: /* fprintf(stderr, "STV says REQUEST_DOWNLOAD\n") ; */ if( TXDisplayS[0].s == ISS_ON) { res= STV_Download() ; imageB.blob = NULL; imageB.bloblen = 0; imageB.size = 0; imageBP.s = IPS_ALERT; IDSetBLOB (&imageBP, NULL); IDMessage( mydev, "Switch off display read out manually first (Update Display: Off\n)") ; } else { tcflush(fd, TCIOFLUSH); usleep( 100000) ; res= ISRequestImageData( 1, 31, 0, 0, 320, 200) ; /* Download the on screen image (buffer 32 -1) */ } /*fprintf(stderr, "STV END REQUEST_DOWNLOAD\n") ; */ break ; case REQUEST_DOWNLOAD_ALL: IDMessage(mydev, "REQUEST_DOWNLOAD_ALL initiated at the STV not implemented") ; break ; case ACK: if( cb == -1) { strcpy(DisplayCT[0].text, "Key press acknowledged") ; strcpy(DisplayBT[0].text, DisplayCT[0].text) ; strcpy(DisplayDT[0].text, DisplayCT[0].text) ; DisplayCTP.s= IPS_OK ; IDSetText( &DisplayCTP, NULL) ; DisplayBTP.s= IPS_OK ; IDSetText( &DisplayBTP, NULL) ; DisplayDTP.s= IPS_OK ; IDSetText( &DisplayDTP, NULL) ; } break ; case NACK: /*fprintf(stderr, "STV says NACK!!") ; */ IDMessage(mydev, "STV says NACK!") ; break ; case REQUEST_BUFFER_STATUS: IDMessage(mydev, "Request Buffer status seen, ignoring\n") ; break ; default: if( guiding== ON) {/* While STV is tracking, it send time, brightnes, centroid x,y */ IDMessage( mydev, "Tracking: %s", tracking_buf) ; } else { /*fprintf(stderr, "STV ISCallBack: Unknown response 0x%2x\n", buf[1]) ; */ IDLog("ISCallBack: Unknown response 0x%2x\n", buf[1]) ; } break ; } } cb= IEAddCallback( fd, (IE_CBF *)ISCallBack, NULL) ; } /* Client retrieves properties */ void ISGetProperties (const char *dev) { /* #1 Let's make sure everything has been initialized properly */ ISInit(); /* #2 Let's make sure that the client is asking for the properties of our device, otherwise ignore */ if (dev && strcmp (mydev, dev)) return; /* #3 Tell the client to create new properties */ /* Connection tab */ IDDefText(&DisplayCTP, NULL) ; IDDefSwitch(&PowerSP, NULL) ; IDDefText(&PortTP, NULL) ; IDDefSwitch(&TXDisplaySP, NULL) ; IDDefText(&StatusTP, NULL) ; /* Settings Tab */ IDDefText(&UTCTP, NULL) ; IDDefNumber(&SetCCDTemperatureNP, NULL) ; /* Buttons tab */ IDDefText(&DisplayBTP, NULL) ; IDDefSwitch(&ControlSP, NULL) ; IDDefSwitch(&ValueSP, NULL) ; IDDefSwitch(&AuxiliarySP, NULL) ; IDDefSwitch(&AcquireSP, NULL) ; IDDefSwitch(&GuideSP, NULL) ; IDDefSwitch(&ProcessSP, NULL) ; /* Image tab */ IDDefText(&DisplayDTP, NULL) ; /* "direct" read out does not work well IDDefSwitch(&BufferStatusSP, NULL) ; */ IDDefSwitch(&BufferStatusSP, NULL) ; IDDefSwitch(&ImageInfoSP, NULL); IDDefNumber(&BufferNP, NULL); IDDefSwitch(&DownloadSP, NULL) ; IDDefSwitch(&CompressionSP, NULL) ; IDDefNumber(&WindowingNP, NULL); IDDefBLOB(&imageBP, NULL); } /* Client sets new switch */ void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { int i, j ; int res = 0; int baud ; IMAGE_INFO image_info ; ISwitch *sp ; int lower_buffer = 0; int upper_buffer = 0 ; /*fprintf(stderr, "ISNewSwitch\n") ; */ /* #1 Let's make sure everything has been initialized properly */ ISInit(); /* #2 Let's make sure that the client is asking to update the properties of our device, otherwise ignore */ if (dev && strcmp (dev, mydev)) return; /* #3 Now let's check if the property the client wants to change is the PowerSP (name: CONNECTION) property*/ if( !strcmp (name, PowerSP.name)) { /* A. We reset all switches (in this case CONNECT and DISCONNECT) to ISS_OFF */ IUResetSwitches(&PowerSP); /* B. We update the switches by sending their names and updated states IUUpdateSwitches function */ IUUpdateSwitches(&PowerSP, states, names, n); /* C. We try to establish a connection to our device or terminate it*/ int res= 0 ; switch (PowerS[0].s) { case ISS_ON: if(( res= strcmp( "9600", PortT[1].text)) ==0) { baud= 9600 ; } else if(( res= strcmp( "19200", PortT[1].text)) ==0) { baud= 19200 ; } else if( (res= strcmp( "38400", PortT[1].text)) ==0) { baud= 38400 ; } else if(( res= strcmp( "57600", PortT[1].text)) ==0) { baud= 57600 ; } else if(( res= strcmp( "115200", PortT[1].text)) ==0) { baud= 115200 ; } else { IUSaveText(&PortT[1], "9600"); IDSetText(&PortTP, "Wrong RS 232 value: %s, defaulting to 9600 baud", PortT[1].text); return ; } if(( fd= STV_Connect( PortT[0].text, baud))== -1) { PowerSP.s = IPS_ALERT; IUResetSwitches( &PowerSP); IDSetSwitch( &PowerSP, "Error connecting to port %s", PortT[0].text); return; } else { cb= IEAddCallback( fd, (IE_CBF *)ISCallBack, NULL) ; /* The SBIG manual says one can request an ACK, never saw it, even not on a RS 232 tester */ if(( res= STV_RequestAck()) != 0) { fprintf( stderr, "COULD not write an ACK\n") ; } /* Second trial: start reading out the display */ if((res= STV_TXDisplay()) != 0) { fprintf(stderr, "STV: Could not write %d\n", res) ; return ; } } PowerSP.s = IPS_OK ; IDSetSwitch(&PowerSP, "STV is online, port: %s, baud rate: %s", PortT[0].text, PortT[1].text) ; PortTP.s = IPS_OK ; IDSetText(&PortTP, NULL); break; case ISS_OFF: IERmCallback( cb) ; cb = -1 ; /* Close the serial port */ tty_disconnect(fd); ISResetButtons(NULL) ; GuideSP.s= IPS_IDLE ; IUResetSwitches(&GuideSP); IDSetSwitch(&GuideSP, NULL); TXDisplaySP.s= IPS_IDLE ; IUResetSwitches(&TXDisplaySP); IDSetSwitch(&TXDisplaySP, NULL); DisplayCTP.s = IPS_IDLE; IDSetText (&DisplayCTP, NULL); DisplayBTP.s = IPS_IDLE; IDSetText (&DisplayBTP, NULL); DisplayDTP.s = IPS_IDLE; IDSetText (&DisplayDTP, NULL); PortTP.s = IPS_IDLE ; IDSetText(&PortTP, NULL) ; imageB.blob = NULL; imageB.bloblen = 0; imageB.size = 0; imageBP.s = IPS_IDLE; IDSetBLOB (&imageBP, NULL); PowerSP.s = IPS_IDLE; IUResetSwitches(&PowerSP); IDSetSwitch(&PowerSP, "STV is offline"); break; } return ; } else if( !strcmp (name, AuxiliarySP.name)) { /* Setup und interrupt buttons */ ISResetButtons(NULL) ; IUResetSwitches(&AuxiliarySP); IUUpdateSwitches(&AuxiliarySP, states, names, n); for( i = 0; i < n; i++) { sp = IUFindSwitch (&AuxiliarySP, names[i]) ; if( sp == &AuxiliaryS[0]){ res= STV_Setup() ; } else if( sp == &AuxiliaryS[1]){ res= STV_Interrupt() ; } } if( res== 0) { AuxiliarySP.s= IPS_OK ; IUResetSwitches(&AuxiliarySP) ; IDSetSwitch(&AuxiliarySP, NULL) ; } else { AuxiliarySP.s= IPS_ALERT ; IUResetSwitches(&AuxiliarySP) ; IDSetSwitch(&AuxiliarySP, "Check connection") ; } } else if( !strcmp (name, ControlSP.name)) { /* Parameter, value and the rotary knobs */ ISResetButtons(NULL) ; IUResetSwitches(&ControlSP); IUUpdateSwitches(&ControlSP, states, names, n); acquiring= OFF ; guiding= OFF ; processing= OFF ; for( i = 0; i < n; i++) { sp = IUFindSwitch (&ControlSP, names[i]) ; /* If the state found is ControlS[0] then process it */ if( sp == &ControlS[0]){ res= STV_AKey() ; } else if( sp == &ControlS[1]){ res= STV_UDRotaryIncrease() ; } else if( sp == &ControlS[2]){ res= STV_UDRotaryDecrease() ; } } if( res== 0) { ControlSP.s= IPS_OK ; IUResetSwitches(&ControlSP) ; IDSetSwitch(&ControlSP, NULL) ; } else { ControlSP.s= IPS_ALERT ; IUResetSwitches(&ControlSP) ; IDSetSwitch(&ControlSP, "Check connection") ; } } else if( !strcmp (name, ValueSP.name)) { /* Button Value, left/right knob */ ISResetButtons(NULL) ; IUResetSwitches(&ValueSP); IUUpdateSwitches(&ValueSP, states, names, n); acquiring= OFF ; guiding= OFF ; processing= OFF ; for( i = 0; i < n; i++) { sp = IUFindSwitch (&ValueSP, names[i]) ; if( sp == &ValueS[0]){ res= STV_BKey() ; } else if( sp == &ValueS[1]){ res= STV_LRRotaryIncrease() ; } else if( sp == &ValueS[2]){ res= STV_LRRotaryDecrease() ; } } if( res== 0) { ValueSP.s= IPS_OK ; IUResetSwitches(&ValueSP) ; IDSetSwitch(&ValueSP, NULL) ; } else { ValueSP.s= IPS_ALERT ; IUResetSwitches(&ValueSP) ; IDSetSwitch(&ValueSP, "Check connection") ; } } else if( !strcmp (name, AcquireSP.name)) { /* Focus, Image Monitor buttons */ ISResetButtons(NULL) ; IUResetSwitches(&AcquireSP); IUUpdateSwitches(&AcquireSP, states, names, n); acquiring= ON ; guiding= OFF ; processing= OFF ; for( i = 0; i < n; i++) { sp = IUFindSwitch (&AcquireSP, names[i]) ; if( sp == &AcquireS[0]){ res= STV_Focus() ; } else if( sp == &AcquireS[1]){ res= STV_Image() ; } else if( sp == &AcquireS[2]){ res= STV_Monitor() ; } } if( res== 0) { AcquireSP.s= IPS_OK ; IUResetSwitches(&AcquireSP) ; IDSetSwitch(&AcquireSP, NULL) ; } else { AcquireSP.s= IPS_ALERT ; IUResetSwitches(&AcquireSP) ; IDSetSwitch(&AcquireSP, "Check connection") ; } } else if( !strcmp (name, GuideSP.name)) { /* Calibrate, Track buttons */ ISResetButtons(NULL) ; IUResetSwitches(&GuideSP); IUUpdateSwitches(&GuideSP, states, names, n); acquiring= OFF ; guiding= ON ; processing= OFF ; for( i = 0; i < n; i++) { sp = IUFindSwitch (& GuideSP, names[i]) ; if( sp == & GuideS[0]){ res= STV_Calibrate() ; } else if( sp == &GuideS[1]){ res= STV_Track() ; } } if( res== 0) { GuideSP.s= IPS_OK ; IUResetSwitches(&GuideSP) ; IDSetSwitch(&GuideSP, NULL) ; } else { GuideSP.s= IPS_ALERT ; IUResetSwitches(&GuideSP) ; IDSetSwitch(&GuideSP, "Check connection") ; } } else if( !strcmp (name, ProcessSP.name)) { ISResetButtons(NULL) ; IUResetSwitches(&ProcessSP); IUUpdateSwitches(&ProcessSP, states, names, n); acquiring= OFF ; guiding= OFF ; processing= ON ; for( i = 0; i < n; i++) { sp = IUFindSwitch (&ProcessSP, names[i]) ; if( sp == &ProcessS[0]){ res= STV_Display() ; } else if( sp == &ProcessS[1]){ res= STV_FileOps() ; } } if( res== 0) { ProcessSP.s= IPS_OK ; IUResetSwitches(&ProcessSP) ; IDSetSwitch(&ProcessSP, NULL) ; } else { ProcessSP.s= IPS_ALERT ; IUResetSwitches(&ProcessSP) ; IDSetSwitch(&ProcessSP, "Check connection") ; } } else if( !strcmp (name, ImageInfoSP.name)) { acquiring= OFF ; guiding= OFF ; processing= OFF ; /* Read out the image buffer and display a short message if it is empty or not */ res= ISTerminateTXDisplay() ; for( i = 0; i < n; i++) { sp = IUFindSwitch( &ImageInfoSP, names[i]) ; if( sp == &ImageInfoS[0]){ if(( res= STV_RequestImageInfo( currentBuffer- 1, &image_info))== 0 ) { ISMessageImageInfo( (int)currentBuffer- 1, &image_info) ; } else { IDMessage( mydev, "Buffer %2d is empty", (int)currentBuffer) ; } break ; } else if( sp == &ImageInfoS[1]){ for( i= 0; i < 32 ; i++) { if(( res= STV_RequestImageInfo( i, &image_info))== 0 ) { ISMessageImageInfo( i, &image_info) ; } else { IDMessage( mydev, "Buffer %2d is empty", i+ 1) ; } } break ; } } if( res== 0) { ImageInfoSP.s= IPS_OK ; IUResetSwitches( &ImageInfoSP) ; IDSetSwitch( &ImageInfoSP, NULL) ; } else { ImageInfoSP.s= IPS_ALERT ; IUResetSwitches( &ImageInfoSP) ; /*IDSetSwitch( &ImageInfoSP, "Check connection") ; */ IDSetSwitch( &ImageInfoSP, NULL) ; } res= STV_Interrupt() ; /* STV initiates a download that we do not want */ res= ISRestoreTXDisplay() ; } else if( !strcmp (name, CompressionSP.name)) { acquiring= OFF ; guiding= OFF ; processing= OFF ; /* Enable or disable compression for image download */ ISResetButtons(NULL) ; IUResetSwitches(&CompressionSP); IUUpdateSwitches(&CompressionSP, states, names, n); for( i = 0; i < n; i++) { sp = IUFindSwitch (&CompressionSP, names[i]) ; if( sp == &CompressionS[0]){ CompressionS[0].s= ISS_ON ; } else if( sp == &CompressionS[1]){ CompressionS[1].s= ISS_ON ; } } CompressionSP.s= IPS_OK ; IDSetSwitch(&CompressionSP, NULL) ; } else if( !strcmp (name, BufferStatusSP.name)) { ISResetButtons(NULL) ; BufferStatusSP.s= IPS_ALERT ; IUResetSwitches(&BufferStatusSP) ; IDSetSwitch(&BufferStatusSP, "Wait...") ; if( ( AcquireSP.s != OFF) || ( GuideSP.s != OFF) || ( ProcessSP.s != OFF)) { acquiring= OFF ; guiding= OFF ; processing= OFF ; ISResetButtons( "Interrupting ongoing image acquisition, calibration or tracking\n") ; AcquireSP.s= IPS_IDLE ; IUResetSwitches(&AcquireSP); IDSetSwitch(&AcquireSP, NULL); GuideSP.s= IPS_IDLE ; IUResetSwitches(&GuideSP); IDSetSwitch(&GuideSP, NULL); ProcessSP.s= IPS_IDLE ; IUResetSwitches(&ProcessSP); IDSetSwitch(&ProcessSP, NULL); ImageInfoSP.s= IPS_IDLE ; IUResetSwitches(&ImageInfoSP); IDSetSwitch(&ImageInfoSP, NULL); res= STV_Interrupt() ; usleep(100000) ; res= STV_Interrupt() ; } acquiring= OFF ; guiding= OFF ; processing= OFF ; sp = IUFindSwitch (&BufferStatusSP, names[0]) ; if((res= ISTerminateTXDisplay()) != 0) { fprintf(stderr, "STV Buffer can not terminate TX %d\n", res) ; } if( sp == &BufferStatusS[0]) { for( i= 31; i > -1; i--) { usleep( 50000) ; if(( res= STV_BufferStatus( i))== 0) { IDMessage( mydev, "Buffer %2d: image present", i+ 1) ; } else { IDMessage( mydev, "Buffer %2d: empty", i+ 1) ; } } } BufferStatusS[0].s= ISS_OFF ; if( 0 <= res) { BufferStatusSP.s= IPS_OK ; IUResetSwitches(&BufferStatusSP) ; IDSetSwitch(&BufferStatusSP, NULL) ; } else { BufferStatusSP.s= IPS_ALERT ; IUResetSwitches(&BufferStatusSP) ; IDSetSwitch(&BufferStatusSP, "Check connection") ; } res= ISRestoreTXDisplay() ; res= STV_Interrupt() ; } else if( !strcmp (name, DownloadSP.name)) { /* Download images */ /* Downloading while the STV is occupied is not working */ if( ( AcquireSP.s != OFF) || ( GuideSP.s != OFF) || ( ProcessSP.s != OFF)) { ISResetButtons( "Interrupting ongoing image acquisition, calibration or tracking\n") ; AcquireSP.s= IPS_IDLE ; IUResetSwitches(&AcquireSP); IDSetSwitch(&AcquireSP, NULL); GuideSP.s= IPS_IDLE ; IUResetSwitches(&GuideSP); IDSetSwitch(&GuideSP, NULL); ProcessSP.s= IPS_IDLE ; IUResetSwitches(&ProcessSP); IDSetSwitch(&ProcessSP, NULL); ImageInfoSP.s= IPS_IDLE ; IUResetSwitches(&ImageInfoSP); IDSetSwitch(&ImageInfoSP, NULL); res= STV_Interrupt() ; usleep(100000) ; res= STV_Interrupt() ; } acquiring= OFF ; guiding= OFF ; processing= OFF ; if((res= ISTerminateTXDisplay()) != 0) { fprintf(stderr, "STV Buffer can not terminate TX %d\n", res) ; } DownloadSP.s= IPS_ALERT ; IUResetSwitches(&DownloadSP) ; IDSetSwitch(&DownloadSP, NULL) ; compression= OFF ; if( CompressionS[0].s == ISS_ON) { compression= ON ; } for( i = 0; i < n; i++) { sp = IUFindSwitch (&DownloadSP, names[i]) ; if( sp == &DownloadS[0]){ lower_buffer= currentBuffer- 2 ; upper_buffer= currentBuffer- 1 ; } else if( sp == &DownloadS[1]){ lower_buffer= -1 ; upper_buffer= 31 ; } } for( j= upper_buffer ; j> lower_buffer ; j--) { if((res= ISRequestImageData( compression, j, currentX, currentY, currentLength, currentLines)) != 0) { if( res== 1) { IDMessage( mydev, "Buffer %2.0f: empty", (double)(j+ 1)) ; } else { break ; } } } if( res== 0) { IDMessage( mydev, "STV waits for SYNC TIME Do it! Setting time, PLEASE WAIT!") ; if((res= STV_SetDateTime(NULL)) == 0) { UTCTP.s= IPS_OK ; IDSetText( &UTCTP, "Time set to UTC now") ; } else { UTCTP.s= IPS_ALERT ; IDSetText( &UTCTP, "Error setting time, check connection") ; } DownloadSP.s= IPS_OK ; IUResetSwitches(&DownloadSP) ; IDSetSwitch(&DownloadSP, NULL) ; } else { /* res could be -1 (STV_RequestImageData) */ DownloadSP.s= IPS_ALERT ; IUResetSwitches(&DownloadSP) ; IDSetSwitch(&DownloadSP, "Check connection") ; IDSetSwitch(&DownloadSP, NULL) ; } res= ISRestoreTXDisplay() ; res= STV_Interrupt() ; IDMessage( mydev, "You may continue NOW") ; } else if( !strcmp (name, TXDisplaySP.name)) { acquiring= OFF ; guiding= OFF ; processing= OFF ; ISResetButtons(NULL) ; IUResetSwitches(&TXDisplaySP); IUUpdateSwitches(&TXDisplaySP, states, names, n); for( i = 0; i < n; i++) { sp= IUFindSwitch (&TXDisplaySP, names[i]) ; if( sp == &TXDisplayS[0]){ if((res= STV_TXDisplay()) == 0) { TXDisplaySP.s= IPS_OK ; IDSetSwitch( &TXDisplaySP, "Reading out display") ; DisplayCTP.s = IPS_OK ; IDSetText( &DisplayCTP, NULL); DisplayBTP.s = IPS_OK ; IDSetText( &DisplayBTP, NULL); DisplayDTP.s = IPS_OK ; IDSetText( &DisplayDTP, NULL); } } else if( sp== &TXDisplayS[1]){ DisplayCTP.s = IPS_IDLE ; DisplayBTP.s = IPS_IDLE ; DisplayDTP.s = IPS_IDLE ; if((res= STV_TerminateTXDisplay()) == 0) { TXDisplaySP.s = IPS_OK ; IDSetSwitch( &TXDisplaySP, "Stopping display read out") ; DisplayCTP.s = IPS_IDLE ; IUSaveText(&DisplayCT[0], " "); /* reset client's display */ IUSaveText(&DisplayCT[1], " "); IDSetText( &DisplayCTP, NULL); DisplayBTP.s = IPS_IDLE ; IUSaveText(&DisplayBT[0], " "); /* reset client's display */ IUSaveText(&DisplayBT[1], " "); IDSetText( &DisplayBTP, NULL); DisplayDTP.s = IPS_IDLE ; IUSaveText(&DisplayDT[0], " "); /* reset client's display */ IUSaveText(&DisplayDT[1], " "); IDSetText( &DisplayDTP, NULL); } } } if( res != 0) { TXDisplaySP.s= IPS_ALERT ; IUResetSwitches(&TXDisplaySP) ; IDSetSwitch(&TXDisplaySP, "Check connection") ; } } } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { int res ; IText *tp ; /*fprintf(stderr, "ISNewText\n") ; */ /* #1 Let's make sure everything has been initialized properly */ ISInit(); /* #2 Let's make sure that the client is asking to update the properties of our device, otherwise ignore */ if ( dev && strcmp( dev, mydev)) return; if( !strcmp (name, PortTP.name)) { if (IUUpdateTexts(&PortTP, texts, names, n) < 0) return; PortTP.s = IPS_OK; if (PowerS[0].s == ISS_ON){ PortTP.s = IPS_ALERT; IDSetText(&PortTP, "STV is already online"); } /* JM: Don't forget to send acknowledgment */ IDSetText(&PortTP, NULL); } else if( !strcmp (name, UTCTP.name)) { ISResetButtons(NULL) ; tp= IUFindText (&UTCTP, names[0]) ; if((res= ISTerminateTXDisplay()) != 0) { fprintf(stderr, "STV Buffer can not terminate TX %d\n", res) ; } if( tp == &UTCT[0]) { /* JM: FIXME why the time stamp is not sent? */ if((res= STV_SetDateTime(NULL)) == 0) { UTCTP.s= IPS_OK ; IDSetText( &UTCTP, "Time set to UTC") ; } else { UTCTP.s= IPS_ALERT ; IDSetText( &UTCTP, "Error setting time, check connection") ; } } res= ISRestoreTXDisplay() ; } } /* Client sets new number */ void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { int res ; double ccd_temperature ; /*fprintf(stderr, "ISNewNumber\n") ; */ /* #1 Let's make sure everything has been initialized properly */ ISInit(); /* #2 Let's make sure that the client is asking to update the properties of our device, otherwise ignore */ if ( dev && strcmp( dev, mydev)) return; if (PowerS[0].s != ISS_ON){ PowerSP.s = IPS_ALERT; IDSetSwitch( &PowerSP, NULL) ; IDMessage("STV is offline", NULL); return ; } if( !strcmp (name, BufferNP.name)) { INumber *buffer = IUFindNumber( &BufferNP, names[0]) ; if( buffer == &BufferN[0]) { currentBuffer= values[0] ; /* Check the boundaries, this is incomplete at the moment */ BufferNP.s = IPS_OK ; IDSetNumber(&BufferNP, NULL) ; } } else if( !strcmp (name, WindowingNP.name)) { INumber *buffer = IUFindNumber( &WindowingNP, names[0]) ; if( buffer == &WindowingN[0]) { currentX = values[0] ; currentY = values[1] ; currentLines = values[2] ; currentLength= values[3] ; WindowingNP.s = IPS_OK ; IDSetNumber(&WindowingNP, NULL) ; } } else if( !strcmp (name, SetCCDTemperatureNP.name)) { if((res= ISTerminateTXDisplay()) != 0) { fprintf(stderr, "STV Buffer can not terminate TX %d\n", res) ; } INumber *np= IUFindNumber (&SetCCDTemperatureNP, names[0]) ; if( np == &SetCCDTemperatureN[0]) { if((ccd_temperature= STV_SetCCDTemperature(values[0])) != 0) { /* STV has no 0 C setting */ SetCCDTemperatureNP.s= IPS_OK ; SetCCDTemperatureN[0].value= ccd_temperature; IDSetNumber( &SetCCDTemperatureNP, "CCD Temperature set to %g", SetCCDTemperatureN[0].value) ; } else { SetCCDTemperatureNP.s= IPS_ALERT ; IDSetNumber( &SetCCDTemperatureNP, "Error setting CCD temperature, check connection") ; } } res= ISRestoreTXDisplay() ; } } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n){} int writeFITS(const char* filename, IMAGE_INFO *image_info, char errmsg[]) { fitsfile *fptr; /* pointer to the FITS file; defined in fitsio.h */ int status; long fpixel = 1, naxis = 2, nelements; long naxes[2]; char filename_rw[TEMPFILE_LEN+1]; naxes[0] = STVImg->width; naxes[1] = STVImg->height; /* Append ! to file name to over write it.*/ snprintf(filename_rw, TEMPFILE_LEN+1, "!%s", filename); status = 0; /* initialize status before calling fitsio routines */ fits_create_file(&fptr, filename_rw, &status); /* create new file */ /* Create the primary array image (16-bit short integer pixels */ fits_create_img(fptr, USHORT_IMG, naxis, naxes, &status); addFITSKeywords(fptr, image_info); nelements = naxes[0] * naxes[1]; /* number of pixels to write */ /* Write the array of integers to the image */ fits_write_img(fptr, TUSHORT, fpixel, nelements, STVImg->img, &status); fits_close_file(fptr, &status); /* close the file */ fits_report_error(stderr, status); /* print out any error messages */ /* Success */ /*ExposeTimeNP.s = IPS_OK; */ /*IDSetNumber(&ExposeTimeNP, NULL); */ uploadFile(filename); return status; } void addFITSKeywords(fitsfile *fptr, IMAGE_INFO *image_info) { int status=0; char binning_s[32]; char frame_s[32]; char date_obs_s[64] ; char tmp[32] ; image_info->pixelSize= 7.4 ; /* microns */ if( image_info->binning== 1) { snprintf(binning_s, 32, "(%1.0f x %1.0f)", 1., 1.); } else if( image_info->binning== 2) { snprintf(binning_s, 32, "(%1.0f x %1.0f)", 2., 2.); } else if( image_info->binning== 3) { snprintf(binning_s, 32, "(%1.0f x %1.0f)", 3., 3.); } else { fprintf( stderr, "Error in binning information: %d\n", image_info->binning) ; } strcpy(frame_s, "Light"); /* ToDo: assign the frame type */ /* switch (STVImg->frameType) */ /* { */ /* case LIGHT_FRAME: */ /* strcpy(frame_s, "Light"); */ /* break; */ /* case BIAS_FRAME: */ /* strcpy(frame_s, "Bias"); */ /* break; */ /* case FLAT_FRAME: */ /* strcpy(frame_s, "Flat Field"); */ /* break; */ /* case DARK_FRAME: */ /* strcpy(frame_s, "Dark"); */ /* break; */ /* } */ fits_update_key(fptr, TDOUBLE, "CCD-TEMP", &(image_info->ccdTemp), "CCD Temperature (Celcius)", &status); fits_update_key(fptr, TDOUBLE, "EXPOSURE", &(image_info->exposure ), "Total Exposure Time (ms)", &status); fits_update_key(fptr, TDOUBLE, "PIX-SIZ", &(image_info->pixelSize), "Pixel Size (microns)", &status); fits_update_key(fptr, TSTRING, "BINNING", binning_s, "Binning HOR x VER", &status); fits_update_key(fptr, TSTRING, "FRAME", frame_s, "Frame Type", &status); fits_update_key(fptr, TDOUBLE, "DATAMIN", &(image_info->minValue), "Minimum value", &status); fits_update_key(fptr, TDOUBLE, "DATAMAX", &(image_info->maxValue), "Maximum value", &status); fits_update_key(fptr, TSTRING, "INSTRUME", "SBIG STV", "CCD Name", &status); sprintf( tmp, "%4d-",image_info->year) ; strcpy( date_obs_s,tmp ) ; if( image_info->month< 10) { sprintf( tmp, "0%1d-", image_info->month) ; } else { sprintf( tmp, "%2d-", image_info->month) ; } strcat( date_obs_s, tmp) ; if( image_info->day< 10) { sprintf( tmp, "0%1dT", image_info->day) ; } else { sprintf( tmp, "%2dT", image_info->day) ; } strcat( date_obs_s, tmp) ; if( image_info->hours< 10) { sprintf( tmp, "0%1d:", image_info->hours) ; } else { sprintf( tmp, "%2d:", image_info->hours) ; } strcat( date_obs_s, tmp) ; if( image_info->minutes< 10) { sprintf( tmp, "0%1d:",image_info->minutes) ; } else { sprintf( tmp, "%2d:", image_info->minutes) ; } strcat( date_obs_s, tmp) ; if( image_info->seconds< 10) { sprintf( tmp, "0%1d:", image_info->seconds) ; } else { sprintf( tmp, "%2d:", image_info->seconds) ; } strcat( date_obs_s, tmp) ; fits_update_key(fptr, TSTRING, "DATE-OBS", date_obs_s, "Observing date (YYYY-MM-DDThh:mm:ss UT", &status); fits_write_date(fptr, &status); } void uploadFile(const char* filename) { FILE * fitsFile; unsigned char *fitsData, *compressedData; int r=0; unsigned int i =0, nr = 0; uLongf compressedBytes=0; uLong totalBytes; struct stat stat_p; if ( -1 == stat (filename, &stat_p)) { IDLog("Error occurred attempting to stat file.\n"); return; } totalBytes = stat_p.st_size; fitsData = (unsigned char *) malloc (sizeof(unsigned char) * totalBytes); compressedData = (unsigned char *) malloc (sizeof(unsigned char) * totalBytes + totalBytes / 64 + 16 + 3); if (fitsData == NULL || compressedData == NULL) { if (fitsData) free(fitsData); if (compressedData) free(compressedData); IDLog("Error! low memory. Unable to initialize fits buffers.\n"); return; } fitsFile = fopen(filename, "r"); if (fitsFile == NULL) return; /* #1 Read file from disk */ for (i=0; i < totalBytes; i+= nr) { nr = fread(fitsData + i, 1, totalBytes - i, fitsFile); if (nr <= 0) { IDLog("Error reading temporary FITS file.\n"); return; } } fclose(fitsFile); compressedBytes = sizeof(char) * totalBytes + totalBytes / 64 + 16 + 3; /* #2 Compress it */ r = compress2(compressedData, &compressedBytes, fitsData, totalBytes, 9); if (r != Z_OK) { /* this should NEVER happen */ IDLog("internal error - compression failed: %d\n", r); return; } /* #3 Send it */ imageB.blob = compressedData; imageB.bloblen = compressedBytes; imageB.size = totalBytes; strcpy(imageB.format, ".fits.z"); imageBP.s = IPS_OK; IDSetBLOB (&imageBP, NULL); free (fitsData); free (compressedData); } int ISTerminateTXDisplay(void) { int res = 0; res= STV_Interrupt() ; /* with out it hangs */ usleep(100000) ; IERmCallback( cb) ; cb = -1 ; if( TXDisplayS[0].s == ISS_ON) { TXDisplaySP.s = IPS_BUSY ; IDSetSwitch(&TXDisplaySP, "Stopping display read out"); DisplayCTP.s = IPS_IDLE ; IUSaveText(&DisplayCT[0], " "); /* reset client's display */ IUSaveText(&DisplayCT[1], " "); IDSetText( &DisplayCTP, NULL); DisplayBTP.s = IPS_IDLE ; IUSaveText(&DisplayBT[0], " "); /* reset client's display */ IUSaveText(&DisplayBT[1], " "); IDSetText( &DisplayBTP, NULL); DisplayDTP.s = IPS_IDLE ; IUSaveText(&DisplayDT[0], " "); /* reset client's display */ IUSaveText(&DisplayDT[1], " "); IDSetText( &DisplayDTP, NULL); if(( res= STV_TerminateTXDisplay()) != 0){ fprintf( stderr, "STV: error writing TTXD %d\n", res) ; } } else { res= 0 ; } usleep(500000) ; /* make sure that everything is discarded */ tcflush(fd, TCIOFLUSH); return res ; } int ISRestoreTXDisplay(void) { int res ; cb= IEAddCallback( fd, (IE_CBF *)ISCallBack, NULL) ; if( TXDisplayS[0].s == ISS_ON) { usleep(500000) ; /* STV need a little rest */ res= STV_TXDisplay() ; TXDisplaySP.s = IPS_OK ; IDSetSwitch(&TXDisplaySP, "Starting Display read out"); DisplayCTP.s = IPS_OK; IDSetText (&DisplayCTP, NULL); DisplayBTP.s = IPS_OK; IDSetText (&DisplayBTP, NULL); DisplayDTP.s = IPS_OK; IDSetText (&DisplayDTP, NULL); } return res ; } int ISMessageImageInfo( int buffer, IMAGE_INFO *image_info) { buffer++ ; /* IDMessage( mydev, "B%2d: descriptor:%d\n", buffer, image_info->descriptor) ; */ /* IDMessage( mydev, "B%2d: height:%d\n", buffer, image_info->height) ; */ /* IDMessage( mydev, "B%2d: width:%d\n", buffer, image_info->width) ; */ /* IDMessage( mydev, "B%2d: top:%d\n", buffer, image_info->top) ; */ /* IDMessage( mydev, "B%2d: left:%d\n", buffer, image_info->left) ; */ IDMessage( mydev, "B%2d: Exposure:%6.3f, Height:%2d, Width:%2d, CCD Temperature:%3.1f\n", buffer, image_info->exposure, image_info->height, image_info->width, image_info->ccdTemp) ; /* IDMessage( mydev, "B%2d: noExposure:%d\n", buffer, image_info->noExposure) ; */ /* IDMessage( mydev, "B%2d: analogGain:%d\n", buffer, image_info->analogGain) ; */ /* IDMessage( mydev, "B%2d: digitalGain:%d\n", buffer, image_info->digitalGain) ; */ /* IDMessage( mydev, "B%2d: focalLength:%d\n", buffer, image_info->focalLength) ; */ /* IDMessage( mydev, "B%2d: aperture:%d\n", buffer, image_info->aperture) ; */ /* IDMessage( mydev, "B%2d: packedDate:%d\n", buffer, image_info->packedDate) ; */ IDMessage( mydev, "B%2d: Year:%4d, Month: %2d, Day:%2d\n", buffer, image_info->year, image_info->month, image_info->day) ; /* IDMessage( mydev, "B%2d: Day:%d\n", buffer, image_info->day) ; */ /* IDMessage( mydev, "B%2d: Month:%d\n", buffer, image_info->month) ; */ /* IDMessage( mydev, "B%2d: packedTime:%d\n", buffer, image_info->packedTime) ; */ /* IDMessage( mydev, "B%2d: Seconds:%d\n", buffer, image_info->seconds) ; */ /* IDMessage( mydev, "B%2d: minutes:%d\n", buffer, image_info->minutes) ; */ IDMessage( mydev, "B%2d: Hours:%2d, Minutes:%2d, Seconds:%d\n", buffer, image_info->hours, image_info->minutes, image_info->seconds) ; /* IDMessage( mydev, "B%2d: ccdTemp:%f\n", buffer, image_info->ccdTemp) ; */ /* IDMessage( mydev, "B%2d: siteID:%d\n", buffer, image_info->siteID) ; */ /* IDMessage( mydev, "B%2d: eGain:%d\n", buffer, image_info->eGain) ; */ /* IDMessage( mydev, "B%2d: background:%d\n", buffer, image_info->background) ; */ /* IDMessage( mydev, "B%2d: range :%d\n", buffer, image_info->range ) ; */ /* IDMessage( mydev, "B%2d: pedestal:%d\n", buffer, image_info->pedestal) ; */ /* IDMessage( mydev, "B%2d: ccdTop :%d\n", buffer, image_info->ccdTop) ; */ /* IDMessage( mydev, "B%2d: ccdLeft:%d\n", buffer, image_info->ccdLeft) ; */ return 0 ; } int ISRequestImageData( int compression, int buffer, int x_offset, int y_offset, int length, int lines) { int res ; int i, k ; int img_size ; char errmsg[1024] ; int image[320][320] ; IMAGE_INFO image_info ; for(i= 0 ; i < 320 ; i++) { for(k= 0 ; k < 320 ; k++) { image[i][k]= -1 ; } } res= STV_RequestImage( compression, buffer, x_offset, y_offset, &length, &lines, image, &image_info) ; if( res== 0) { STVImg->width= length; STVImg->height= lines ; img_size = STVImg->width * STVImg->height * sizeof(unsigned short); STVImg->img= malloc (img_size); for(i= 0 ; i < STVImg->height ; i++) { /* x */ for(k= 0 ; k < STVImg->width ; k++) { /* y */ STVImg->img[ STVImg->width* i + k]= (unsigned short)image[i][k] ; /* Uncomment this line in case of doubts about decompressed values and compare */ /* both sets. */ /*fprintf( stderr, "Line: %d %d %d %d\n", i, k, image[i][k], STVImg->img[ STVImg->width* i + k]) ; */ if(STVImg->img[ STVImg->width* i + k] < image_info.minValue) { image_info.minValue= STVImg->img[ STVImg->width* i + k] ; } if(STVImg->img[ STVImg->width* i + k] > image_info.maxValue) { image_info.maxValue= STVImg->img[ STVImg->width* i + k] ; } } } writeFITS( "FITS.fits", &image_info, errmsg) ; /*fprintf( stderr, "Fits writing message: %s\n", errmsg) ; */ free( STVImg->img) ; } return res ; } void ISUpdateDisplay( int buffer, int line) { if( !(( line+1) % 10)) { sprintf( DisplayCT[0].text, "Buffer %2d line: %3d", buffer+1, line+ 1) ; strcpy( DisplayBT[0].text, DisplayCT[0].text) ; strcpy( DisplayDT[0].text, DisplayCT[0].text) ; DisplayCTP.s= IPS_OK ; IDSetText( &DisplayCTP, NULL) ; DisplayBTP.s= IPS_OK ; IDSetText( &DisplayBTP, NULL) ; DisplayDTP.s= IPS_OK ; IDSetText( &DisplayDTP, NULL) ; } else if(( line+1)== 1) { /* first time */ IDMessage( mydev, "Image download started") ; } else if( line < 0) { /* last line */ line= -line ; sprintf( DisplayCT[0].text, "Buffer %2d line: %3d", buffer+1, line+ 1) ; strcpy( DisplayBT[0].text, DisplayCT[0].text) ; strcpy( DisplayDT[0].text, DisplayCT[0].text) ; DisplayCTP.s= IPS_OK ; IDSetText( &DisplayCTP, NULL) ; DisplayBTP.s= IPS_OK ; IDSetText( &DisplayBTP, NULL) ; DisplayDTP.s= IPS_OK ; IDSetText( &DisplayDTP, NULL) ; IDMessage( mydev, "Image download ended, buffer %2d line: %3d", buffer+1, line) ; } } indi-0.5/src/cfitsio/0000755000175000017500000000000011017761434012344 5ustar jrjrindi-0.5/src/cfitsio/getcoluj.c0000644000175000017500000021637110610474375014341 0ustar jrjr/* This file, getcoluj.c, contains routines that read data elements from */ /* a FITS image or table, with unsigned long data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvuj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned long nulval, /* I - value for undefined pixels */ unsigned long *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; unsigned long nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TULONG, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluj(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfuj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned long *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TULONG, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluj(fptr, 2, row, firstelem, nelem, 1, 2, 0L, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2duj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned long nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3duj(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3duj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned long nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; unsigned long nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TULONG, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcluj(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcluj(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvuj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned long nulval, /* I - value to set undefined pixels */ unsigned long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; unsigned long nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvuj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TULONG, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvuj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcluj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfuj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned long *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; unsigned long nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TULONG, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcluj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpuj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ unsigned long *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluj(fptr, 1, row, firstelem, nelem, 1, 1, 0L, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvuj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned long nulval, /* I - value for null pixels */ unsigned long *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfuj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned long *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { unsigned long dummy = 0; ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcluj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ unsigned long nulval, /* I - value for null pixels if nultyp = 1 */ unsigned long *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int nulcheck; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ if (tcode == TLONG) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) &array[next], status); fffi4u4((INT32BIT *) &array[next], ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8u4( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1u4((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2u4((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4u4((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8u4((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstru4((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgcluj).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgcluj).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1u4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (unsigned long) input[ii]; /* copy input */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2u4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4u4(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; Process the array of data in reverse order, to handle the case where the input data is 4-bytes and the output is 8-bytes and the conversion is being done in place in the same array. */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 2147483648.) { /* Instead of adding 2147483648, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = ntodo - 1; ii >= 0; ii--) output[ii] = ( *(unsigned int *) &input[ii] ) ^ 0x80000000; } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = ntodo - 1; ii >= 0; ii--) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned long) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = ntodo - 1; ii >= 0; ii--) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 2147483648.) { for (ii = ntodo - 1; ii >= 0; ii--) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = ( *(unsigned int *) &input[ii] ) ^ 0x80000000; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = ntodo - 1; ii >= 0; ii--) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned long) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = ntodo - 1; ii >= 0; ii--) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8u4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > ULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > ULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4u4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8u4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstru4(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ unsigned long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DULONG_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DULONG_MAX) { *status = OVERFLOW_ERR; output[ii] = ULONG_MAX; } else output[ii] = (unsigned long) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } indi-0.5/src/cfitsio/putcoluk.c0000644000175000017500000010415210610474375014364 0ustar jrjr/* This file, putcolk.c, contains routines that write data elements to */ /* a FITS image or table, with 'unsigned int' datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppruk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; unsigned int nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TUINT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcluk(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnuk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values that are written */ unsigned int nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; unsigned int nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TUINT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnuk(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2duk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3duk(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3duk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TUINT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcluk(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcluk(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssuk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ unsigned int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TUINT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcluk(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpuk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcluk(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcluk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* call the 'short' or 'long' version of this routine, if possible */ if (sizeof(int) == sizeof(short)) ffpclui(fptr, colnum, firstrow, firstelem, nelem, (unsigned short *) array, status); else if (sizeof(int) == sizeof(long)) ffpcluj(fptr, colnum, firstrow, firstelem, nelem, (unsigned long *) array, status); else { /* This is a special case: sizeof(int) is not equal to sizeof(short) or sizeof(long). This occurs on Alpha OSF systems where short = 2 bytes, int = 4 bytes, and long = 8 bytes. */ buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONG): /* convert the raw data before writing to FITS file */ ffuintfi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TLONGLONG): ffuintfi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffuintfi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffuintfi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffuintfr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffuintfr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffuintfstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpcluk).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } } /* end of Dec ALPHA special case */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned int *array, /* I - array of values to write */ unsigned int nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcluk(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcluk(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcluk(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfi1(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfi2(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfi4(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 2147483648.) { /* Instead of subtracting 2147483648, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(int *) &input[ii] ) ^ 0x80000000; } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > INT32_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfi8(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfr4(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfr8(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffuintfstr(unsigned int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } indi-0.5/src/cfitsio/putcolk.c0000644000175000017500000010525610610474375014205 0ustar jrjr/* This file, putcolk.c, contains routines that write data elements to */ /* a FITS image or table, with 'int' datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; int nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TINT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclk(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *array, /* I - array of values that are written */ int nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; int nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TINT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnk(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dk(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TINT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclk(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclk(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ int *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TINT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclk(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ int *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclk(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclk( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* call the 'short' or 'long' version of this routine, if possible */ if (sizeof(int) == sizeof(short)) ffpcli(fptr, colnum, firstrow, firstelem, nelem, (short *) array, status); else if (sizeof(int) == sizeof(long)) ffpclj(fptr, colnum, firstrow, firstelem, nelem, (long *) array, status); else { /* This is a special case: sizeof(int) is not equal to sizeof(short) or sizeof(long). This occurs on Alpha OSF systems where short = 2 bytes, int = 4 bytes, and long = 8 bytes. */ buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TLONG) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONG): if (writeraw) { /* write raw input bytes without conversion */ ffpi4b(fptr, ntodo, incre, (INT32BIT *) &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffintfi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); } break; case (TLONGLONG): ffintfi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffintfi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffintfi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffintfr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffintfr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffintfstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpclk).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } } /* end of Dec ALPHA special case */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnk( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *array, /* I - array of values to write */ int nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclk(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclk(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclk(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfi1(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfi2(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfi4(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo * sizeof(int) ); } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfi8(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfr4(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfr8(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffintfstr(int *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } indi-0.5/src/cfitsio/putkey.c0000644000175000017500000031675010610474375014050 0ustar jrjr/* This file, putkey.c, contains routines that write keywords to */ /* a FITS header. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include /* stddef.h is apparently needed to define size_t */ #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffcrim(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ long *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* create an IMAGE extension following the current HDU. If the current HDU is empty (contains no header keywords), then simply write the required image (or primary array) keywords to the current HDU. */ { if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* create new extension if current header is not empty */ if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) ffcrhd(fptr, status); /* write the required header keywords */ ffphpr(fptr, TRUE, bitpix, naxis, naxes, 0, 1, TRUE, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffcrimll(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ LONGLONG *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* create an IMAGE extension following the current HDU. If the current HDU is empty (contains no header keywords), then simply write the required image (or primary array) keywords to the current HDU. */ { if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* create new extension if current header is not empty */ if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) ffcrhd(fptr, status); /* write the required header keywords */ ffphprll(fptr, TRUE, bitpix, naxis, naxes, 0, 1, TRUE, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffcrtb(fitsfile *fptr, /* I - FITS file pointer */ int tbltype, /* I - type of table to create */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ char *extnm, /* I - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* Create a table extension in a FITS file. */ { LONGLONG naxis1 = 0; long *tbcol = 0; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* create new extension if current header is not empty */ if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) ffcrhd(fptr, status); if ((fptr->Fptr)->curhdu == 0) /* have to create dummy primary array */ { ffcrim(fptr, 16, 0, tbcol, status); ffcrhd(fptr, status); } if (tbltype == BINARY_TBL) { /* write the required header keywords. This will write PCOUNT = 0 */ ffphbn(fptr, naxis2, tfields, ttype, tform, tunit, extnm, 0, status); } else if (tbltype == ASCII_TBL) { /* write the required header keywords */ /* default values for naxis1 and tbcol will be calculated */ ffphtb(fptr, naxis1, naxis2, tfields, ttype, tbcol, tform, tunit, extnm, status); } else *status = NOT_TABLE; return(*status); } /*-------------------------------------------------------------------------*/ int ffpktp(fitsfile *fptr, /* I - FITS file pointer */ const char *filename, /* I - name of template file */ int *status) /* IO - error status */ /* read keywords from template file and append to the FITS file */ { FILE *diskfile; char card[FLEN_CARD], template[161]; char keyname[FLEN_KEYWORD], newname[FLEN_KEYWORD]; int keytype; size_t slen; if (*status > 0) /* inherit input status value if > 0 */ return(*status); diskfile = fopen(filename,"r"); if (!diskfile) /* couldn't open file */ { ffpmsg("ffpktp could not open the following template file:"); ffpmsg(filename); return(*status = FILE_NOT_OPENED); } while (fgets(template, 160, diskfile) ) /* get next template line */ { template[160] = '\0'; /* make sure string is terminated */ slen = strlen(template); /* get string length */ template[slen - 1] = '\0'; /* over write the 'newline' char */ if (ffgthd(template, card, &keytype, status) > 0) /* parse template */ break; strncpy(keyname, card, 8); keyname[8] = '\0'; if (keytype == -2) /* rename the card */ { strncpy(newname, &card[40], 8); newname[8] = '\0'; ffmnam(fptr, keyname, newname, status); } else if (keytype == -1) /* delete the card */ { ffdkey(fptr, keyname, status); } else if (keytype == 0) /* update the card */ { ffucrd(fptr, keyname, card, status); } else if (keytype == 1) /* append the card */ { ffprec(fptr, card, status); } else /* END card; stop here */ { break; } } fclose(diskfile); /* close the template file */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpky( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ char *keyname, /* I - name of keyword to write */ void *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes a keyword value with the datatype specified by the 2nd argument. */ { char errmsg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TSTRING) { ffpkys(fptr, keyname, (char *) value, comm, status); } else if (datatype == TBYTE) { ffpkyj(fptr, keyname, (LONGLONG) *(unsigned char *) value, comm, status); } else if (datatype == TSBYTE) { ffpkyj(fptr, keyname, (LONGLONG) *(signed char *) value, comm, status); } else if (datatype == TUSHORT) { ffpkyj(fptr, keyname, (LONGLONG) *(unsigned short *) value, comm, status); } else if (datatype == TSHORT) { ffpkyj(fptr, keyname, (LONGLONG) *(short *) value, comm, status); } else if (datatype == TUINT) { ffpkyg(fptr, keyname, (double) *(unsigned int *) value, 0, comm, status); } else if (datatype == TINT) { ffpkyj(fptr, keyname, (LONGLONG) *(int *) value, comm, status); } else if (datatype == TLOGICAL) { ffpkyl(fptr, keyname, *(int *) value, comm, status); } else if (datatype == TULONG) { ffpkyg(fptr, keyname, (double) *(unsigned long *) value, 0, comm, status); } else if (datatype == TLONG) { ffpkyj(fptr, keyname, (LONGLONG) *(long *) value, comm, status); } else if (datatype == TLONGLONG) { ffpkyj(fptr, keyname, *(LONGLONG *) value, comm, status); } else if (datatype == TFLOAT) { ffpkye(fptr, keyname, *(float *) value, -7, comm, status); } else if (datatype == TDOUBLE) { ffpkyd(fptr, keyname, *(double *) value, -15, comm, status); } else if (datatype == TCOMPLEX) { ffpkyc(fptr, keyname, (float *) value, -7, comm, status); } else if (datatype == TDBLCOMPLEX) { ffpkym(fptr, keyname, (double *) value, -15, comm, status); } else { sprintf(errmsg, "Bad keyword datatype code: %d (ffpky)", datatype); ffpmsg(errmsg); *status = BAD_DATATYPE; } return(*status); } /*-------------------------------------------------------------------------*/ int ffprec(fitsfile *fptr, /* I - FITS file pointer */ const char *card, /* I - string to be written */ int *status) /* IO - error status */ /* write a keyword record (80 bytes long) to the end of the header */ { char tcard[FLEN_CARD]; size_t len, ii; long nblocks; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ( ((fptr->Fptr)->datastart - (fptr->Fptr)->headend) == 80) /* no room */ { nblocks = 1; if (ffiblk(fptr, nblocks, 0, status) > 0) /* insert 2880-byte block */ return(*status); } strncpy(tcard,card,80); tcard[80] = '\0'; len = strlen(tcard); for (ii=len; ii < 80; ii++) /* fill card with spaces if necessary */ tcard[ii] = ' '; for (ii=0; ii < 8; ii++) /* make sure keyword name is uppercase */ tcard[ii] = toupper(tcard[ii]); fftkey(tcard, status); /* test keyword name contains legal chars */ fftrec(tcard, status); /* test rest of keyword for legal chars */ ffmbyt(fptr, (fptr->Fptr)->headend, IGNORE_EOF, status); /* move to end */ ffpbyt(fptr, 80, tcard, status); /* write the 80 byte card */ if (*status <= 0) (fptr->Fptr)->headend += 80; /* update end-of-header position */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyu( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) a null-valued keyword and comment into the FITS header. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring," "); /* create a dummy value string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword */ ffprec(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpkys( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. The value string will be truncated at 68 characters which is the maximum length that will fit on a single FITS keyword. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffs2c(value, valstring, status); /* put quotes around the string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword */ ffprec(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpkls( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. This routine is a modified version of ffpkys which supports the HEASARC long string convention and can write arbitrarily long string keyword values. The value is continued over multiple keywords that have the name COMTINUE without an equal sign in column 9 of the card. This routine also supports simple string keywords which are less than 69 characters in length. */ { char valstring[FLEN_CARD]; char card[FLEN_CARD]; char tstring[FLEN_CARD], *cptr; int next, remain, vlen, nquote, nchar, namelen, contin, tstatus = -1; if (*status > 0) /* inherit input status value if > 0 */ return(*status); remain = maxvalue(strlen(value), 1); /* no. of chars to write (at least 1) */ /* count the number of single quote characters are in the string */ tstring[0] = '\0'; strncat(tstring, value, 68); /* copy 1st part of string to temp buff */ nquote = 0; cptr = strchr(tstring, '\''); /* search for quote character */ while (cptr) /* search for quote character */ { nquote++; /* increment no. of quote characters */ cptr++; /* increment pointer to next character */ cptr = strchr(cptr, '\''); /* search for another quote char */ } cptr = keyname; while(*cptr == ' ') /* skip over leading spaces in name */ cptr++; /* determine the number of characters that will fit on the line */ /* Note: each quote character is expanded to 2 quotes */ namelen = strlen(cptr); if (namelen <= 8 && (fftkey(cptr, &tstatus) <= 0) ) { /* This a normal 8-character FITS keyword */ nchar = 68 - nquote; /* max of 68 chars fit in a FITS string value */ } else { /* This a HIERARCH keyword */ if (FSTRNCMP(cptr, "HIERARCH ", 9) && FSTRNCMP(cptr, "hierarch ", 9)) nchar = 66 - nquote - namelen; else nchar = 75 - nquote - namelen; /* don't count 'HIERARCH' twice */ } contin = 0; next = 0; /* pointer to next character to write */ while (remain > 0) { tstring[0] = '\0'; strncat(tstring, &value[next], nchar); /* copy string to temp buff */ ffs2c(tstring, valstring, status); /* put quotes around the string */ if (remain > nchar) /* if string is continued, put & as last char */ { vlen = strlen(valstring); nchar -= 1; /* outputting one less character now */ if (valstring[vlen-2] != '\'') valstring[vlen-2] = '&'; /* over write last char with & */ else { /* last char was a pair of single quotes, so over write both */ valstring[vlen-3] = '&'; valstring[vlen-1] = '\0'; } } if (contin) /* This is a CONTINUEd keyword */ { ffmkky("CONTINUE", valstring, comm, card, status); /* make keyword */ strncpy(&card[8], " ", 2); /* overwrite the '=' */ } else { ffmkky(keyname, valstring, comm, card, status); /* make keyword */ } ffprec(fptr, card, status); /* write the keyword */ contin = 1; remain -= nchar; next += nchar; if (remain > 0) { /* count the number of single quote characters in next section */ tstring[0] = '\0'; strncat(tstring, &value[next], 68); /* copy next part of string */ nquote = 0; cptr = strchr(tstring, '\''); /* search for quote character */ while (cptr) /* search for quote character */ { nquote++; /* increment no. of quote characters */ cptr++; /* increment pointer to next character */ cptr = strchr(cptr, '\''); /* search for another quote char */ } nchar = 68 - nquote; /* max number of chars to write this time */ } } return(*status); } /*--------------------------------------------------------------------------*/ int ffplsw( fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Write the LONGSTRN keyword and a series of related COMMENT keywords which document that this FITS header may contain long string keyword values which are continued over multiple keywords using the HEASARC long string keyword convention. If the LONGSTRN keyword already exists then this routine simple returns without doing anything. */ { char valstring[FLEN_VALUE], comm[FLEN_COMMENT]; int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = 0; if (ffgkys(fptr, "LONGSTRN", valstring, comm, &tstatus) == 0) return(*status); /* keyword already exists, so just return */ ffpkys(fptr, "LONGSTRN", "OGIP 1.0", "The HEASARC Long String Convention may be used.", status); ffpcom(fptr, " This FITS file may contain long string keyword values that are", status); ffpcom(fptr, " continued over multiple keywords. The HEASARC convention uses the &", status); ffpcom(fptr, " character at the end of each substring which is then continued", status); ffpcom(fptr, " on the next keyword which has the name CONTINUE.", status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyl( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ int value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Values equal to 0 will result in a False FITS keyword; any other non-zero value will result in a True FITS keyword. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffl2c(value, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyj( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ LONGLONG value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an integer keyword value. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffi2c(value, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyf( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ float value, /* I - keyword value */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes a fixed float keyword value. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffr2f(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkye( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ float value, /* I - keyword value */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an exponential float keyword value. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffr2e(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyg( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ double value, /* I - keyword value */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes a fixed double keyword value.*/ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffd2f(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyd( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ double value, /* I - keyword value */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an exponential double keyword value.*/ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffd2e(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyc( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ float *value, /* I - keyword value (real, imaginary) */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an complex float keyword value. Format = (realvalue, imagvalue) */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffr2e(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2e(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkym( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ double *value, /* I - keyword value (real, imaginary) */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an complex double keyword value. Format = (realvalue, imagvalue) */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffd2e(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2e(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkfc( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ float *value, /* I - keyword value (real, imaginary) */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an complex float keyword value. Format = (realvalue, imagvalue) */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffr2f(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2f(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkfm( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ double *value, /* I - keyword value (real, imaginary) */ int decim, /* I - number of decimal places to display */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) the keyword, value and comment into the FITS header. Writes an complex double keyword value. Format = (realvalue, imagvalue) */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffd2f(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2f(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffpkyt( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ long intval, /* I - integer part of value */ double fraction, /* I - fractional part of value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Write (put) a 'triple' precision keyword where the integer and fractional parts of the value are passed in separate parameters to increase the total amount of numerical precision. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; char fstring[20], *cptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (fraction > 1. || fraction < 0.) { ffpmsg("fraction must be between 0. and 1. (ffpkyt)"); return(*status = BAD_F2C); } ffi2c(intval, valstring, status); /* convert integer to string */ ffd2f(fraction, 16, fstring, status); /* convert to 16 decimal string */ cptr = strchr(fstring, '.'); /* find the decimal point */ strcat(valstring, cptr); /* append the fraction to the integer */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffprec(fptr, card, status); /* write the keyword*/ return(*status); } /*-----------------------------------------------------------------*/ int ffpcom( fitsfile *fptr, /* I - FITS file pointer */ const char *comm, /* I - comment string */ int *status) /* IO - error status */ /* Write 1 or more COMMENT keywords. If the comment string is too long to fit on a single keyword (72 chars) then it will automatically be continued on multiple CONTINUE keywords. */ { char card[FLEN_CARD]; int len, ii; if (*status > 0) /* inherit input status value if > 0 */ return(*status); len = strlen(comm); ii = 0; for (; len > 0; len -= 72) { strcpy(card, "COMMENT "); strncat(card, &comm[ii], 72); ffprec(fptr, card, status); ii += 72; } return(*status); } /*-----------------------------------------------------------------*/ int ffphis( fitsfile *fptr, /* I - FITS file pointer */ const char *history, /* I - history string */ int *status) /* IO - error status */ /* Write 1 or more HISTORY keywords. If the history string is too long to fit on a single keyword (72 chars) then it will automatically be continued on multiple HISTORY keywords. */ { char card[FLEN_CARD]; int len, ii; if (*status > 0) /* inherit input status value if > 0 */ return(*status); len = strlen(history); ii = 0; for (; len > 0; len -= 72) { strcpy(card, "HISTORY "); strncat(card, &history[ii], 72); ffprec(fptr, card, status); ii += 72; } return(*status); } /*-----------------------------------------------------------------*/ int ffpdat( fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Write the DATE keyword into the FITS header. If the keyword already exists then the date will simply be updated in the existing keyword. */ { int timeref; char date[30], tmzone[10], card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffgstm(date, &timeref, status); if (timeref) /* GMT not available on this machine */ strcpy(tmzone, " Local"); else strcpy(tmzone, " UT"); strcpy(card, "DATE = '"); strcat(card, date); strcat(card, "' / file creation date (YYYY-MM-DDThh:mm:ss"); strcat(card, tmzone); strcat(card, ")"); ffucrd(fptr, "DATE", card, status); return(*status); } /*-------------------------------------------------------------------*/ int ffverifydate(int year, /* I - year (0 - 9999) */ int month, /* I - month (1 - 12) */ int day, /* I - day (1 - 31) */ int *status) /* IO - error status */ /* Verify that the date is valid */ { int ndays[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; char errmsg[81]; if (year < 0 || year > 9999) { sprintf(errmsg, "input year value = %d is out of range 0 - 9999", year); ffpmsg(errmsg); return(*status = BAD_DATE); } else if (month < 1 || month > 12) { sprintf(errmsg, "input month value = %d is out of range 1 - 12", month); ffpmsg(errmsg); return(*status = BAD_DATE); } if (ndays[month] == 31) { if (day < 1 || day > 31) { sprintf(errmsg, "input day value = %d is out of range 1 - 31 for month %d", day, month); ffpmsg(errmsg); return(*status = BAD_DATE); } } else if (ndays[month] == 30) { if (day < 1 || day > 30) { sprintf(errmsg, "input day value = %d is out of range 1 - 30 for month %d", day, month); ffpmsg(errmsg); return(*status = BAD_DATE); } } else { if (day < 1 || day > 28) { if (day == 29) { /* year is a leap year if it is divisible by 4 but not by 100, except years divisible by 400 are leap years */ if ((year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0) return (*status); sprintf(errmsg, "input day value = %d is out of range 1 - 28 for February %d (not leap year)", day, year); ffpmsg(errmsg); } else { sprintf(errmsg, "input day value = %d is out of range 1 - 28 (or 29) for February", day); ffpmsg(errmsg); } return(*status = BAD_DATE); } } return(*status); } /*-----------------------------------------------------------------*/ int ffgstm( char *timestr, /* O - returned system date and time string */ int *timeref, /* O - GMT = 0, Local time = 1 */ int *status) /* IO - error status */ /* Returns the current date and time in format 'yyyy-mm-ddThh:mm:ss'. */ { time_t tp; struct tm *ptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); time(&tp); ptr = gmtime(&tp); /* get GMT (= UTC) time */ if (timeref) { if (ptr) *timeref = 0; /* returning GMT */ else *timeref = 1; /* returning local time */ } if (!ptr) /* GMT not available on this machine */ ptr = localtime(&tp); strftime(timestr, 25, "%Y-%m-%dT%H:%M:%S", ptr); return(*status); } /*-----------------------------------------------------------------*/ int ffdt2s(int year, /* I - year (0 - 9999) */ int month, /* I - month (1 - 12) */ int day, /* I - day (1 - 31) */ char *datestr, /* O - date string: "YYYY-MM-DD" */ int *status) /* IO - error status */ /* Construct a date character string */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); *datestr = '\0'; if (ffverifydate(year, month, day, status) > 0) { ffpmsg("invalid date (ffdt2s)"); return(*status); } if (year >= 1900 && year <= 1998) /* use old 'dd/mm/yy' format */ sprintf(datestr, "%.2d/%.2d/%.2d", day, month, year - 1900); else /* use the new 'YYYY-MM-DD' format */ sprintf(datestr, "%.4d-%.2d-%.2d", year, month, day); return(*status); } /*-----------------------------------------------------------------*/ int ffs2dt(char *datestr, /* I - date string: "YYYY-MM-DD" or "dd/mm/yy" */ int *year, /* O - year (0 - 9999) */ int *month, /* O - month (1 - 12) */ int *day, /* O - day (1 - 31) */ int *status) /* IO - error status */ /* Parse a date character string into year, month, and day values */ { int slen, lyear, lmonth, lday; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (year) *year = 0; if (month) *month = 0; if (day) *day = 0; if (!datestr) { ffpmsg("error: null input date string (ffs2dt)"); return(*status = BAD_DATE); /* Null datestr pointer ??? */ } slen = strlen(datestr); if (slen == 8 && datestr[2] == '/' && datestr[5] == '/') { if (isdigit((int) datestr[0]) && isdigit((int) datestr[1]) && isdigit((int) datestr[3]) && isdigit((int) datestr[4]) && isdigit((int) datestr[6]) && isdigit((int) datestr[7]) ) { /* this is an old format string: "dd/mm/yy" */ lyear = atoi(&datestr[6]) + 1900; lmonth = atoi(&datestr[3]); lday = atoi(datestr); if (year) *year = lyear; if (month) *month = lmonth; if (day) *day = lday; } else { ffpmsg("input date string has illegal format (ffs2dt):"); ffpmsg(datestr); return(*status = BAD_DATE); } } else if (slen >= 10 && datestr[4] == '-' && datestr[7] == '-') { if (isdigit((int) datestr[0]) && isdigit((int) datestr[1]) && isdigit((int) datestr[2]) && isdigit((int) datestr[3]) && isdigit((int) datestr[5]) && isdigit((int) datestr[6]) && isdigit((int) datestr[8]) && isdigit((int) datestr[9]) ) { if (slen > 10 && datestr[10] != 'T') { ffpmsg("input date string has illegal format (ffs2dt):"); ffpmsg(datestr); return(*status = BAD_DATE); } /* this is a new format string: "yyyy-mm-dd" */ lyear = atoi(datestr); lmonth = atoi(&datestr[5]); lday = atoi(&datestr[8]); if (year) *year = lyear; if (month) *month = lmonth; if (day) *day = lday; } else { ffpmsg("input date string has illegal format (ffs2dt):"); ffpmsg(datestr); return(*status = BAD_DATE); } } else { ffpmsg("input date string has illegal format (ffs2dt):"); ffpmsg(datestr); return(*status = BAD_DATE); } if (ffverifydate(lyear, lmonth, lday, status) > 0) { ffpmsg("invalid date (ffs2dt)"); } return(*status); } /*-----------------------------------------------------------------*/ int fftm2s(int year, /* I - year (0 - 9999) */ int month, /* I - month (1 - 12) */ int day, /* I - day (1 - 31) */ int hour, /* I - hour (0 - 23) */ int minute, /* I - minute (0 - 59) */ double second, /* I - second (0. - 60.9999999) */ int decimals, /* I - number of decimal points to write */ char *datestr, /* O - date string: "YYYY-MM-DDThh:mm:ss.ddd" */ /* or "hh:mm:ss.ddd" if year, month day = 0 */ int *status) /* IO - error status */ /* Construct a date and time character string */ { int width; char errmsg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); *datestr='\0'; if (year != 0 || month != 0 || day !=0) { if (ffverifydate(year, month, day, status) > 0) { ffpmsg("invalid date (fftm2s)"); return(*status); } } if (hour < 0 || hour > 23) { sprintf(errmsg, "input hour value is out of range 0 - 23: %d (fftm2s)", hour); ffpmsg(errmsg); return(*status = BAD_DATE); } else if (minute < 0 || minute > 59) { sprintf(errmsg, "input minute value is out of range 0 - 59: %d (fftm2s)", minute); ffpmsg(errmsg); return(*status = BAD_DATE); } else if (second < 0. || second >= 61) { sprintf(errmsg, "input second value is out of range 0 - 60.999: %f (fftm2s)", second); ffpmsg(errmsg); return(*status = BAD_DATE); } else if (decimals > 25) { sprintf(errmsg, "input decimals value is out of range 0 - 25: %d (fftm2s)", decimals); ffpmsg(errmsg); return(*status = BAD_DATE); } if (decimals == 0) width = 2; else width = decimals + 3; if (decimals < 0) { /* a negative decimals value means return only the date, not time */ sprintf(datestr, "%.4d-%.2d-%.2d", year, month, day); } else if (year == 0 && month == 0 && day == 0) { /* return only the time, not the date */ sprintf(datestr, "%.2d:%.2d:%0*.*f", hour, minute, width, decimals, second); } else { /* return both the time and date */ sprintf(datestr, "%.4d-%.2d-%.2dT%.2d:%.2d:%0*.*f", year, month, day, hour, minute, width, decimals, second); } return(*status); } /*-----------------------------------------------------------------*/ int ffs2tm(char *datestr, /* I - date string: "YYYY-MM-DD" */ /* or "YYYY-MM-DDThh:mm:ss.ddd" */ /* or "dd/mm/yy" */ int *year, /* O - year (0 - 9999) */ int *month, /* O - month (1 - 12) */ int *day, /* O - day (1 - 31) */ int *hour, /* I - hour (0 - 23) */ int *minute, /* I - minute (0 - 59) */ double *second, /* I - second (0. - 60.9999999) */ int *status) /* IO - error status */ /* Parse a date character string into date and time values */ { int slen; char errmsg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (year) *year = 0; if (month) *month = 0; if (day) *day = 0; if (hour) *hour = 0; if (minute) *minute = 0; if (second) *second = 0.; if (!datestr) { ffpmsg("error: null input date string (ffs2tm)"); return(*status = BAD_DATE); /* Null datestr pointer ??? */ } if (datestr[2] == '/' || datestr[4] == '-') { /* Parse the year, month, and date */ if (ffs2dt(datestr, year, month, day, status) > 0) return(*status); slen = strlen(datestr); if (slen == 8 || slen == 10) return(*status); /* OK, no time fields */ else if (slen < 19) { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } else if (datestr[10] == 'T' && datestr[13] == ':' && datestr[16] == ':') { if (isdigit((int) datestr[11]) && isdigit((int) datestr[12]) && isdigit((int) datestr[14]) && isdigit((int) datestr[15]) && isdigit((int) datestr[17]) && isdigit((int) datestr[18]) ) { if (slen > 19 && datestr[19] != '.') { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } /* this is a new format string: "yyyy-mm-ddThh:mm:ss.dddd" */ if (hour) *hour = atoi(&datestr[11]); if (minute) *minute = atoi(&datestr[14]); if (second) *second = atof(&datestr[17]); } else { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } } } else /* no date fields */ { if (datestr[2] == ':' && datestr[5] == ':') /* time string */ { if (isdigit((int) datestr[0]) && isdigit((int) datestr[1]) && isdigit((int) datestr[3]) && isdigit((int) datestr[4]) && isdigit((int) datestr[6]) && isdigit((int) datestr[7]) ) { /* this is a time string: "hh:mm:ss.dddd" */ if (hour) *hour = atoi(&datestr[0]); if (minute) *minute = atoi(&datestr[3]); if (second) *second = atof(&datestr[6]); } else { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } } else { ffpmsg("input date string has illegal format:"); ffpmsg(datestr); return(*status = BAD_DATE); } } if (hour) if (*hour < 0 || *hour > 23) { sprintf(errmsg, "hour value is out of range 0 - 23: %d (ffs2tm)", *hour); ffpmsg(errmsg); return(*status = BAD_DATE); } if (minute) if (*minute < 0 || *minute > 59) { sprintf(errmsg, "minute value is out of range 0 - 59: %d (ffs2tm)", *minute); ffpmsg(errmsg); return(*status = BAD_DATE); } if (second) if (*second < 0 || *second >= 61.) { sprintf(errmsg, "second value is out of range 0 - 60.9999: %f (ffs2tm)", *second); ffpmsg(errmsg); return(*status = BAD_DATE); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsdt( int *day, int *month, int *year, int *status ) { /* This routine is included for backward compatibility with the Fortran FITSIO library. ffgsdt : Get current System DaTe (GMT if available) Return integer values of the day, month, and year Function parameters: day Day of the month month Numerical month (1=Jan, etc.) year Year (1999, 2000, etc.) status output error status */ time_t now; struct tm *date; now = time( NULL ); date = gmtime(&now); /* get GMT (= UTC) time */ if (!date) /* GMT not available on this machine */ { date = localtime(&now); } *day = date->tm_mday; *month = date->tm_mon + 1; *year = date->tm_year + 1900; /* tm_year is defined as years since 1900 */ return( *status ); } /*--------------------------------------------------------------------------*/ int ffpkns( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ char *value[], /* I - array of pointers to keyword values */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes string keywords. The value strings will be truncated at 68 characters, and the HEASARC long string keyword convention is not supported by this routine. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkys(fptr, keyname, value[ii], tcomment, status); else ffpkys(fptr, keyname, value[ii], comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknl( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ int *value, /* I - array of keyword values */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes logical keywords Values equal to zero will be written as a False FITS keyword value; any other non-zero value will result in a True FITS keyword. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyl(fptr, keyname, value[ii], tcomment, status); else ffpkyl(fptr, keyname, value[ii], comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknj( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ long *value, /* I - array of keyword values */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Write integer keywords */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyj(fptr, keyname, value[ii], tcomment, status); else ffpkyj(fptr, keyname, value[ii], comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknjj( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ LONGLONG *value, /* I - array of keyword values */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Write integer keywords */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyj(fptr, keyname, value[ii], tcomment, status); else ffpkyj(fptr, keyname, value[ii], comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknf( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ float *value, /* I - array of keyword values */ int decim, /* I - number of decimals to display */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes fixed float values. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyf(fptr, keyname, value[ii], decim, tcomment, status); else ffpkyf(fptr, keyname, value[ii], decim, comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpkne( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ float *value, /* I - array of keyword values */ int decim, /* I - number of decimals to display */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes exponential float values. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkye(fptr, keyname, value[ii], decim, tcomment, status); else ffpkye(fptr, keyname, value[ii], decim, comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpkng( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ double *value, /* I - array of keyword values */ int decim, /* I - number of decimals to display */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes fixed double values. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyg(fptr, keyname, value[ii], decim, tcomment, status); else ffpkyg(fptr, keyname, value[ii], decim, comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpknd( fitsfile *fptr, /* I - FITS file pointer */ char *keyroot, /* I - root name of keywords to write */ int nstart, /* I - starting index number */ int nkey, /* I - number of keywords to write */ double *value, /* I - array of keyword values */ int decim, /* I - number of decimals to display */ char *comm[], /* I - array of pointers to keyword comment */ int *status) /* IO - error status */ /* Write (put) an indexed array of keywords with index numbers between NSTART and (NSTART + NKEY -1) inclusive. Writes exponential double values. */ { char keyname[FLEN_KEYWORD], tcomment[FLEN_COMMENT]; int ii, jj, repeat, len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check if first comment string is to be repeated for all the keywords */ /* by looking to see if the last non-blank character is a '&' char */ repeat = 0; if (comm) { len = strlen(comm[0]); while (len > 0 && comm[0][len - 1] == ' ') len--; /* ignore trailing blanks */ if (comm[0][len - 1] == '&') { len = minvalue(len, FLEN_COMMENT); tcomment[0] = '\0'; strncat(tcomment, comm[0], len-1); /* don't copy the final '&' char */ repeat = 1; } } else { repeat = 1; tcomment[0] = '\0'; } for (ii=0, jj=nstart; ii < nkey; ii++, jj++) { ffkeyn(keyroot, jj, keyname, status); if (repeat) ffpkyd(fptr, keyname, value[ii], decim, tcomment, status); else ffpkyd(fptr, keyname, value[ii], decim, comm[ii], status); if (*status > 0) return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffptdm( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int naxis, /* I - number of axes in the data array */ long naxes[], /* I - length of each data axis */ int *status) /* IO - error status */ /* write the TDIMnnn keyword describing the dimensionality of a column */ { char keyname[FLEN_KEYWORD], tdimstr[FLEN_VALUE], comm[FLEN_COMMENT]; char value[80], message[81]; int ii; long totalpix = 1, repeat; tcolumn *colptr; if (*status > 0) return(*status); if (colnum < 1 || colnum > 999) { ffpmsg("column number is out of range 1 - 999 (ffptdm)"); return(*status = BAD_COL_NUM); } if (naxis < 1) { ffpmsg("naxis is less than 1 (ffptdm)"); return(*status = BAD_DIMEN); } /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ( (fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg( "Error: The TDIMn keyword is only allowed in BINTABLE extensions (ffptdm)"); return(*status = NOT_BTABLE); } strcpy(tdimstr, "("); /* start constructing the TDIM value */ for (ii = 0; ii < naxis; ii++) { if (ii > 0) strcat(tdimstr, ","); /* append the comma separator */ if (naxes[ii] < 0) { ffpmsg("one or more TDIM values are less than 0 (ffptdm)"); return(*status = BAD_TDIM); } sprintf(value, "%ld", naxes[ii]); strcat(tdimstr, value); /* append the axis size */ totalpix *= naxes[ii]; } colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* point to the specified column number */ if ((long) colptr->trepeat != totalpix) { /* There is an apparent inconsistency between TDIMn and TFORMn. */ /* The colptr->trepeat value may be out of date, so re-read */ /* the TFORMn keyword to be sure. */ ffkeyn("TFORM", colnum, keyname, status); /* construct TFORMn name */ ffgkys(fptr, keyname, value, NULL, status); /* read TFORMn keyword */ ffbnfm(value, NULL, &repeat, NULL, status); /* parse the repeat count */ if (*status > 0 || repeat != totalpix) { sprintf(message, "column vector length, %ld, does not equal TDIMn array size, %ld", (long) colptr->trepeat, totalpix); ffpmsg(message); return(*status = BAD_TDIM); } } strcat(tdimstr, ")" ); /* append the closing parenthesis */ strcpy(comm, "size of the multidimensional array"); ffkeyn("TDIM", colnum, keyname, status); /* construct TDIMn name */ ffpkys(fptr, keyname, tdimstr, comm, status); /* write the keyword */ return(*status); } /*--------------------------------------------------------------------------*/ int ffptdmll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int naxis, /* I - number of axes in the data array */ LONGLONG naxes[], /* I - length of each data axis */ int *status) /* IO - error status */ /* write the TDIMnnn keyword describing the dimensionality of a column */ { char keyname[FLEN_KEYWORD], tdimstr[FLEN_VALUE], comm[FLEN_COMMENT]; char value[80], message[81]; int ii; LONGLONG totalpix = 1, repeat; tcolumn *colptr; if (*status > 0) return(*status); if (colnum < 1 || colnum > 999) { ffpmsg("column number is out of range 1 - 999 (ffptdm)"); return(*status = BAD_COL_NUM); } if (naxis < 1) { ffpmsg("naxis is less than 1 (ffptdm)"); return(*status = BAD_DIMEN); } /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ( (fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg( "Error: The TDIMn keyword is only allowed in BINTABLE extensions (ffptdm)"); return(*status = NOT_BTABLE); } strcpy(tdimstr, "("); /* start constructing the TDIM value */ for (ii = 0; ii < naxis; ii++) { if (ii > 0) strcat(tdimstr, ","); /* append the comma separator */ if (naxes[ii] < 0) { ffpmsg("one or more TDIM values are less than 0 (ffptdm)"); return(*status = BAD_TDIM); } /* cast to double because the 64-bit int conversion character in */ /* sprintf is platform dependent ( %lld, %ld, %I64d ) */ sprintf(value, "%.0f", (double) naxes[ii]); strcat(tdimstr, value); /* append the axis size */ totalpix *= naxes[ii]; } colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* point to the specified column number */ if ( colptr->trepeat != totalpix) { /* There is an apparent inconsistency between TDIMn and TFORMn. */ /* The colptr->trepeat value may be out of date, so re-read */ /* the TFORMn keyword to be sure. */ ffkeyn("TFORM", colnum, keyname, status); /* construct TFORMn name */ ffgkys(fptr, keyname, value, NULL, status); /* read TFORMn keyword */ ffbnfmll(value, NULL, &repeat, NULL, status); /* parse the repeat count */ if (*status > 0 || repeat != totalpix) { sprintf(message, "column vector length, %.0f, does not equal TDIMn array size, %.0f", (double) (colptr->trepeat), (double) totalpix); ffpmsg(message); return(*status = BAD_TDIM); } } strcat(tdimstr, ")" ); /* append the closing parenthesis */ strcpy(comm, "size of the multidimensional array"); ffkeyn("TDIM", colnum, keyname, status); /* construct TDIMn name */ ffpkys(fptr, keyname, tdimstr, comm, status); /* write the keyword */ return(*status); } /*--------------------------------------------------------------------------*/ int ffphps( fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - number of bits per data value pixel */ int naxis, /* I - number of axes in the data array */ long naxes[], /* I - length of each data axis */ int *status) /* IO - error status */ /* write STANDARD set of required primary header keywords */ { int simple = 1; /* does file conform to FITS standard? 1/0 */ long pcount = 0; /* number of group parameters (usually 0) */ long gcount = 1; /* number of random groups (usually 1 or 0) */ int extend = 1; /* may FITS file have extensions? */ ffphpr(fptr, simple, bitpix, naxis, naxes, pcount, gcount, extend, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffphpsll( fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - number of bits per data value pixel */ int naxis, /* I - number of axes in the data array */ LONGLONG naxes[], /* I - length of each data axis */ int *status) /* IO - error status */ /* write STANDARD set of required primary header keywords */ { int simple = 1; /* does file conform to FITS standard? 1/0 */ LONGLONG pcount = 0; /* number of group parameters (usually 0) */ LONGLONG gcount = 1; /* number of random groups (usually 1 or 0) */ int extend = 1; /* may FITS file have extensions? */ ffphprll(fptr, simple, bitpix, naxis, naxes, pcount, gcount, extend, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffphpr( fitsfile *fptr, /* I - FITS file pointer */ int simple, /* I - does file conform to FITS standard? 1/0 */ int bitpix, /* I - number of bits per data value pixel */ int naxis, /* I - number of axes in the data array */ long naxes[], /* I - length of each data axis */ LONGLONG pcount, /* I - number of group parameters (usually 0) */ LONGLONG gcount, /* I - number of random groups (usually 1 or 0) */ int extend, /* I - may FITS file have extensions? */ int *status) /* IO - error status */ /* write required primary header keywords */ { int ii; LONGLONG naxesll[20]; for (ii = 0; (ii < naxis) && (ii < 20); ii++) naxesll[ii] = naxes[ii]; ffphprll(fptr, simple, bitpix, naxis, naxesll, pcount, gcount, extend, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffphprll( fitsfile *fptr, /* I - FITS file pointer */ int simple, /* I - does file conform to FITS standard? 1/0 */ int bitpix, /* I - number of bits per data value pixel */ int naxis, /* I - number of axes in the data array */ LONGLONG naxes[], /* I - length of each data axis */ LONGLONG pcount, /* I - number of group parameters (usually 0) */ LONGLONG gcount, /* I - number of random groups (usually 1 or 0) */ int extend, /* I - may FITS file have extensions? */ int *status) /* IO - error status */ /* write required primary header keywords */ { int ii; long longbitpix, tnaxes[20]; char name[FLEN_KEYWORD], comm[FLEN_COMMENT], message[FLEN_ERRMSG]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status = HEADER_NOT_EMPTY); if (naxis != 0) /* never try to compress a null image */ { if ( (fptr->Fptr)->request_compress_type ) { for (ii = 0; ii < naxis; ii++) tnaxes[ii] = (long) naxes[ii]; /* write header for a compressed image */ imcomp_init_table(fptr, bitpix, naxis, tnaxes, 1, status); return(*status); } } if ((fptr->Fptr)->curhdu == 0) { /* write primary array header */ if (simple) strcpy(comm, "file does conform to FITS standard"); else strcpy(comm, "file does not conform to FITS standard"); ffpkyl(fptr, "SIMPLE", simple, comm, status); } else { /* write IMAGE extension header */ strcpy(comm, "IMAGE extension"); ffpkys(fptr, "XTENSION", "IMAGE", comm, status); } longbitpix = bitpix; /* test for the 2 special cases that represent unsigned integers */ if (longbitpix == USHORT_IMG) longbitpix = SHORT_IMG; else if (longbitpix == ULONG_IMG) longbitpix = LONG_IMG; if (longbitpix != BYTE_IMG && longbitpix != SHORT_IMG && longbitpix != LONG_IMG && longbitpix != LONGLONG_IMG && longbitpix != FLOAT_IMG && longbitpix != DOUBLE_IMG) { sprintf(message, "Illegal value for BITPIX keyword: %d", bitpix); ffpmsg(message); return(*status = BAD_BITPIX); } strcpy(comm, "number of bits per data pixel"); if (ffpkyj(fptr, "BITPIX", longbitpix, comm, status) > 0) return(*status); if (naxis < 0 || naxis > 999) { sprintf(message, "Illegal value for NAXIS keyword: %d", naxis); ffpmsg(message); return(*status = BAD_NAXIS); } strcpy(comm, "number of data axes"); ffpkyj(fptr, "NAXIS", naxis, comm, status); strcpy(comm, "length of data axis "); for (ii = 0; ii < naxis; ii++) { if (naxes[ii] < 0) { sprintf(message, "Illegal negative value for NAXIS%d keyword: %.0f", ii + 1, (double) (naxes[ii])); ffpmsg(message); return(*status = BAD_NAXES); } sprintf(&comm[20], "%d", ii + 1); ffkeyn("NAXIS", ii + 1, name, status); ffpkyj(fptr, name, naxes[ii], comm, status); } if ((fptr->Fptr)->curhdu == 0) /* the primary array */ { if (extend) { /* only write EXTEND keyword if value = true */ strcpy(comm, "FITS dataset may contain extensions"); ffpkyl(fptr, "EXTEND", extend, comm, status); } if (pcount < 0) { ffpmsg("pcount value is less than 0"); return(*status = BAD_PCOUNT); } else if (gcount < 1) { ffpmsg("gcount value is less than 1"); return(*status = BAD_GCOUNT); } else if (pcount > 0 || gcount > 1) { /* only write these keyword if non-standard values */ strcpy(comm, "random group records are present"); ffpkyl(fptr, "GROUPS", 1, comm, status); strcpy(comm, "number of random group parameters"); ffpkyj(fptr, "PCOUNT", pcount, comm, status); strcpy(comm, "number of random groups"); ffpkyj(fptr, "GCOUNT", gcount, comm, status); } /* write standard block of self-documentating comments */ ffprec(fptr, "COMMENT FITS (Flexible Image Transport System) format is defined in 'Astronomy", status); ffprec(fptr, "COMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H", status); } else /* an IMAGE extension */ { /* image extension; cannot have random groups */ if (pcount != 0) { ffpmsg("image extensions must have pcount = 0"); *status = BAD_PCOUNT; } else if (gcount != 1) { ffpmsg("image extensions must have gcount = 1"); *status = BAD_GCOUNT; } else { strcpy(comm, "required keyword; must = 0"); ffpkyj(fptr, "PCOUNT", 0, comm, status); strcpy(comm, "required keyword; must = 1"); ffpkyj(fptr, "GCOUNT", 1, comm, status); } } /* Write the BSCALE and BZERO keywords, if an unsigned integer image */ if (bitpix == USHORT_IMG) { strcpy(comm, "offset data range to that of unsigned short"); ffpkyg(fptr, "BZERO", 32768., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(fptr, "BSCALE", 1.0, 0, comm, status); } else if (bitpix == ULONG_IMG) { strcpy(comm, "offset data range to that of unsigned long"); ffpkyg(fptr, "BZERO", 2147483648., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(fptr, "BSCALE", 1.0, 0, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffphtb(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis1, /* I - width of row in the table */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ long *tbcol, /* I - byte offset in row to each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ char *extnm, /* I - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* Put required Header keywords into the ASCII TaBle: */ { int ii, ncols, gotmem = 0; long rowlen; /* must be 'long' because it is passed to ffgabc */ char tfmt[30], name[FLEN_KEYWORD], comm[FLEN_COMMENT]; if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (*status > 0) return(*status); else if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status = HEADER_NOT_EMPTY); else if (naxis1 < 0) return(*status = NEG_WIDTH); else if (naxis2 < 0) return(*status = NEG_ROWS); else if (tfields < 0 || tfields > 999) return(*status = BAD_TFIELDS); rowlen = (long) naxis1; if (!tbcol || !tbcol[0] || (!naxis1 && tfields)) /* spacing not defined? */ { /* allocate mem for tbcol; malloc can have problems allocating small */ /* arrays, so allocate at least 20 bytes */ ncols = maxvalue(5, tfields); tbcol = (long *) calloc(ncols, sizeof(long)); if (tbcol) { gotmem = 1; /* calculate width of a row and starting position of each column. */ /* Each column will be separated by 1 blank space */ ffgabc(tfields, tform, 1, &rowlen, tbcol, status); } } ffpkys(fptr, "XTENSION", "TABLE", "ASCII table extension", status); ffpkyj(fptr, "BITPIX", 8, "8-bit ASCII characters", status); ffpkyj(fptr, "NAXIS", 2, "2-dimensional ASCII table", status); ffpkyj(fptr, "NAXIS1", rowlen, "width of table in characters", status); ffpkyj(fptr, "NAXIS2", naxis2, "number of rows in table", status); ffpkyj(fptr, "PCOUNT", 0, "no group parameters (required keyword)", status); ffpkyj(fptr, "GCOUNT", 1, "one data group (required keyword)", status); ffpkyj(fptr, "TFIELDS", tfields, "number of fields in each row", status); for (ii = 0; ii < tfields; ii++) /* loop over every column */ { if ( *(ttype[ii]) ) /* optional TTYPEn keyword */ { sprintf(comm, "label for field %3d", ii + 1); ffkeyn("TTYPE", ii + 1, name, status); ffpkys(fptr, name, ttype[ii], comm, status); } if (tbcol[ii] < 1 || tbcol[ii] > rowlen) *status = BAD_TBCOL; sprintf(comm, "beginning column of field %3d", ii + 1); ffkeyn("TBCOL", ii + 1, name, status); ffpkyj(fptr, name, tbcol[ii], comm, status); strcpy(tfmt, tform[ii]); /* required TFORMn keyword */ ffupch(tfmt); ffkeyn("TFORM", ii + 1, name, status); ffpkys(fptr, name, tfmt, "Fortran-77 format of field", status); if (tunit) { if (tunit[ii] && *(tunit[ii]) ) /* optional TUNITn keyword */ { ffkeyn("TUNIT", ii + 1, name, status); ffpkys(fptr, name, tunit[ii], "physical unit of field", status) ; } } if (*status > 0) break; /* abort loop on error */ } if (extnm) { if (extnm[0]) /* optional EXTNAME keyword */ ffpkys(fptr, "EXTNAME", extnm, "name of this ASCII table extension", status); } if (*status > 0) ffpmsg("Failed to write ASCII table header keywords (ffphtb)"); if (gotmem) free(tbcol); return(*status); } /*--------------------------------------------------------------------------*/ int ffphbn(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ char *extnm, /* I - value of EXTNAME keyword, if any */ LONGLONG pcount, /* I - size of the variable length heap area */ int *status) /* IO - error status */ /* Put required Header keywords into the Binary Table: */ { int ii, datatype, iread = 0; long repeat, width; LONGLONG naxis1; char tfmt[30], name[FLEN_KEYWORD], comm[FLEN_COMMENT]; char *cptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status = HEADER_NOT_EMPTY); else if (naxis2 < 0) return(*status = NEG_ROWS); else if (pcount < 0) return(*status = BAD_PCOUNT); else if (tfields < 0 || tfields > 999) return(*status = BAD_TFIELDS); ffpkys(fptr, "XTENSION", "BINTABLE", "binary table extension", status); ffpkyj(fptr, "BITPIX", 8, "8-bit bytes", status); ffpkyj(fptr, "NAXIS", 2, "2-dimensional binary table", status); naxis1 = 0; for (ii = 0; ii < tfields; ii++) /* sum the width of each field */ { ffbnfm(tform[ii], &datatype, &repeat, &width, status); if (datatype == TSTRING) naxis1 += repeat; /* one byte per char */ else if (datatype == TBIT) naxis1 += (repeat + 7) / 8; else if (datatype > 0) naxis1 += repeat * (datatype / 10); else if (tform[ii][0] == 'P' || tform[ii][1] == 'P') /* this is a 'P' variable length descriptor (neg. datatype) */ naxis1 += 8; else /* this is a 'Q' variable length descriptor (neg. datatype) */ naxis1 += 16; if (*status > 0) break; /* abort loop on error */ } ffpkyj(fptr, "NAXIS1", naxis1, "width of table in bytes", status); ffpkyj(fptr, "NAXIS2", naxis2, "number of rows in table", status); /* the initial value of PCOUNT (= size of the variable length array heap) should always be zero. If any variable length data is written, then the value of PCOUNT will be updated when the HDU is closed */ ffpkyj(fptr, "PCOUNT", 0, "size of special data area", status); ffpkyj(fptr, "GCOUNT", 1, "one data group (required keyword)", status); ffpkyj(fptr, "TFIELDS", tfields, "number of fields in each row", status); for (ii = 0; ii < tfields; ii++) /* loop over every column */ { if ( *(ttype[ii]) ) /* optional TTYPEn keyword */ { sprintf(comm, "label for field %3d", ii + 1); ffkeyn("TTYPE", ii + 1, name, status); ffpkys(fptr, name, ttype[ii], comm, status); } strcpy(tfmt, tform[ii]); /* required TFORMn keyword */ ffupch(tfmt); ffkeyn("TFORM", ii + 1, name, status); strcpy(comm, "data format of field"); ffbnfm(tfmt, &datatype, &repeat, &width, status); if (datatype == TSTRING) { strcat(comm, ": ASCII Character"); /* Do sanity check to see if an ASCII table format was used, */ /* e.g., 'A8' instead of '8A', or a bad unit width eg '8A9'. */ /* Don't want to return an error status, so write error into */ /* the keyword comment. */ cptr = strchr(tfmt,'A'); cptr++; if (cptr) iread = sscanf(cptr,"%ld", &width); if (iread == 1 && (width > repeat)) { if (repeat == 1) strcpy(comm, "ERROR?? USING ASCII TABLE SYNTAX BY MISTAKE??"); else strcpy(comm, "rAw FORMAT ERROR! UNIT WIDTH w > COLUMN WIDTH r"); } } else if (datatype == TBIT) strcat(comm, ": BIT"); else if (datatype == TBYTE) strcat(comm, ": BYTE"); else if (datatype == TLOGICAL) strcat(comm, ": 1-byte LOGICAL"); else if (datatype == TSHORT) strcat(comm, ": 2-byte INTEGER"); else if (datatype == TUSHORT) strcat(comm, ": 2-byte INTEGER"); else if (datatype == TLONG) strcat(comm, ": 4-byte INTEGER"); else if (datatype == TLONGLONG) strcat(comm, ": 8-byte INTEGER"); else if (datatype == TULONG) strcat(comm, ": 4-byte INTEGER"); else if (datatype == TFLOAT) strcat(comm, ": 4-byte REAL"); else if (datatype == TDOUBLE) strcat(comm, ": 8-byte DOUBLE"); else if (datatype == TCOMPLEX) strcat(comm, ": COMPLEX"); else if (datatype == TDBLCOMPLEX) strcat(comm, ": DOUBLE COMPLEX"); else if (datatype < 0) strcat(comm, ": variable length array"); if (abs(datatype) == TSBYTE) /* signed bytes */ { /* Replace the 'S' with an 'B' in the TFORMn code */ cptr = tfmt; while (*cptr != 'S') cptr++; *cptr = 'B'; ffpkys(fptr, name, tfmt, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", ii + 1, name, status); strcpy(comm, "offset for signed bytes"); ffpkyg(fptr, name, -128., 0, comm, status); ffkeyn("TSCAL", ii + 1, name, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, name, 1., 0, comm, status); } else if (abs(datatype) == TUSHORT) { /* Replace the 'U' with an 'I' in the TFORMn code */ cptr = tfmt; while (*cptr != 'U') cptr++; *cptr = 'I'; ffpkys(fptr, name, tfmt, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", ii + 1, name, status); strcpy(comm, "offset for unsigned integers"); ffpkyg(fptr, name, 32768., 0, comm, status); ffkeyn("TSCAL", ii + 1, name, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, name, 1., 0, comm, status); } else if (abs(datatype) == TULONG) { /* Replace the 'V' with an 'J' in the TFORMn code */ cptr = tfmt; while (*cptr != 'V') cptr++; *cptr = 'J'; ffpkys(fptr, name, tfmt, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", ii + 1, name, status); strcpy(comm, "offset for unsigned integers"); ffpkyg(fptr, name, 2147483648., 0, comm, status); ffkeyn("TSCAL", ii + 1, name, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, name, 1., 0, comm, status); } else { ffpkys(fptr, name, tfmt, comm, status); } if (tunit) { if (tunit[ii] && *(tunit[ii]) ) /* optional TUNITn keyword */ { ffkeyn("TUNIT", ii + 1, name, status); ffpkys(fptr, name, tunit[ii], "physical unit of field", status); } } if (*status > 0) break; /* abort loop on error */ } if (extnm) { if (extnm[0]) /* optional EXTNAME keyword */ ffpkys(fptr, "EXTNAME", extnm, "name of this binary table extension", status); } if (*status > 0) ffpmsg("Failed to write binary table header keywords (ffphbn)"); return(*status); } /*--------------------------------------------------------------------------*/ int ffphext(fitsfile *fptr, /* I - FITS file pointer */ char *xtension, /* I - value for the XTENSION keyword */ int bitpix, /* I - value for the BIXPIX keyword */ int naxis, /* I - value for the NAXIS keyword */ long naxes[], /* I - value for the NAXISn keywords */ LONGLONG pcount, /* I - value for the PCOUNT keyword */ LONGLONG gcount, /* I - value for the GCOUNT keyword */ int *status) /* IO - error status */ /* Put required Header keywords into a conforming extension: */ { char message[FLEN_ERRMSG],comm[81], name[20]; int ii; if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (*status > 0) return(*status); else if ((fptr->Fptr)->headend != (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status = HEADER_NOT_EMPTY); if (naxis < 0 || naxis > 999) { sprintf(message, "Illegal value for NAXIS keyword: %d", naxis); ffpmsg(message); return(*status = BAD_NAXIS); } ffpkys(fptr, "XTENSION", xtension, "extension type", status); ffpkyj(fptr, "BITPIX", bitpix, "number of bits per data pixel", status); ffpkyj(fptr, "NAXIS", naxis, "number of data axes", status); strcpy(comm, "length of data axis "); for (ii = 0; ii < naxis; ii++) { if (naxes[ii] < 0) { sprintf(message, "Illegal negative value for NAXIS%d keyword: %.0f", ii + 1, (double) (naxes[ii])); ffpmsg(message); return(*status = BAD_NAXES); } sprintf(&comm[20], "%d", ii + 1); ffkeyn("NAXIS", ii + 1, name, status); ffpkyj(fptr, name, naxes[ii], comm, status); } ffpkyj(fptr, "PCOUNT", pcount, " ", status); ffpkyj(fptr, "GCOUNT", gcount, " ", status); if (*status > 0) ffpmsg("Failed to write extension header keywords (ffphext)"); return(*status); } /*--------------------------------------------------------------------------*/ int ffi2c(LONGLONG ival, /* I - value to be converted to a string */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert value to a null-terminated formatted string. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; #if defined(_MSC_VER) /* Microsoft Visual C++ 6.0 uses '%I64d' syntax for 8-byte integers */ if (sprintf(cval, "%I64d", ival) < 0) #elif (USE_LL_SUFFIX == 1) if (sprintf(cval, "%lld", ival) < 0) #else if (sprintf(cval, "%ld", ival) < 0) #endif { ffpmsg("Error in ffi2c converting integer to string"); *status = BAD_I2C; } return(*status); } /*--------------------------------------------------------------------------*/ int ffl2c(int lval, /* I - value to be converted to a string */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status ) */ /* convert logical value to a null-terminated formatted string. If the input value == 0, then the output character is the letter F, else the output character is the letter T. The output string is null terminated. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (lval) strcpy(cval,"T"); else strcpy(cval,"F"); return(*status); } /*--------------------------------------------------------------------------*/ int ffs2c(char *instr, /* I - null terminated input string */ char *outstr, /* O - null terminated quoted output string */ int *status) /* IO - error status */ /* convert an input string to a quoted string. Leading spaces are significant. FITS string keyword values must be at least 8 chars long so pad out string with spaces if necessary. Example: km/s ==> 'km/s ' Single quote characters in the input string will be replace by two single quote characters. e.g., o'brian ==> 'o''brian' */ { size_t len, ii, jj; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (!instr) /* a null input pointer?? */ { strcpy(outstr, "''"); /* a null FITS string */ return(*status); } outstr[0] = '\''; /* start output string with a quote */ len = strlen(instr); if (len > 68) len = 68; /* limit input string to 68 chars */ for (ii=0, jj=1; ii < len && jj < 69; ii++, jj++) { outstr[jj] = instr[ii]; /* copy each char from input to output */ if (instr[ii] == '\'') { jj++; outstr[jj]='\''; /* duplicate any apostrophies in the input */ } } for (; jj < 9; jj++) /* pad string so it is at least 8 chars long */ outstr[jj] = ' '; if (jj == 70) /* only occurs if the last char of string was a quote */ outstr[69] = '\0'; else { outstr[jj] = '\''; /* append closing quote character */ outstr[jj+1] = '\0'; /* terminate the string */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffr2f(float fval, /* I - value to be converted to a string */ int decim, /* I - number of decimal places to display */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert float value to a null-terminated F format string */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; if (decim < 0) { ffpmsg("Error in ffr2f: no. of decimal places < 0"); return(*status = BAD_DECIM); } if (sprintf(cval, "%.*f", decim, fval) < 0) { ffpmsg("Error in ffr2f converting float to string"); *status = BAD_F2C; } /* test if output string is 'NaN', 'INDEF', or 'INF' */ if (strchr(cval, 'N')) { ffpmsg("Error in ffr2f: float value is a NaN or INDEF"); *status = BAD_F2C; } return(*status); } /*--------------------------------------------------------------------------*/ int ffr2e(float fval, /* I - value to be converted to a string */ int decim, /* I - number of decimal places to display */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert float value to a null-terminated exponential format string */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; if (decim < 0) { /* use G format if decim is negative */ if ( sprintf(cval, "%.*G", -decim, fval) < 0) { ffpmsg("Error in ffr2e converting float to string"); *status = BAD_F2C; } else { /* test if E format was used, and there is no displayed decimal */ if ( !strchr(cval, '.') && strchr(cval,'E') ) { /* reformat value with a decimal point and single zero */ if ( sprintf(cval, "%.1E", fval) < 0) { ffpmsg("Error in ffr2e converting float to string"); *status = BAD_F2C; } return(*status); } } } else { if ( sprintf(cval, "%.*E", decim, fval) < 0) { ffpmsg("Error in ffr2e converting float to string"); *status = BAD_F2C; } } if (*status <= 0) { /* test if output string is 'NaN', 'INDEF', or 'INF' */ if (strchr(cval, 'N')) { ffpmsg("Error in ffr2e: float value is a NaN or INDEF"); *status = BAD_F2C; } else if ( !strchr(cval, '.') && !strchr(cval,'E') ) { /* add decimal point if necessary to distinquish from integer */ strcat(cval, "."); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffd2f(double dval, /* I - value to be converted to a string */ int decim, /* I - number of decimal places to display */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert double value to a null-terminated F format string */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; if (decim < 0) { ffpmsg("Error in ffd2f: no. of decimal places < 0"); return(*status = BAD_DECIM); } if (sprintf(cval, "%.*f", decim, dval) < 0) { ffpmsg("Error in ffd2f converting double to string"); *status = BAD_F2C; } /* test if output string is 'NaN', 'INDEF', or 'INF' */ if (strchr(cval, 'N')) { ffpmsg("Error in ffd2f: double value is a NaN or INDEF"); *status = BAD_F2C; } return(*status); } /*--------------------------------------------------------------------------*/ int ffd2e(double dval, /* I - value to be converted to a string */ int decim, /* I - number of decimal places to display */ char *cval, /* O - character string representation of the value */ int *status) /* IO - error status */ /* convert double value to a null-terminated exponential format string. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); cval[0] = '\0'; if (decim < 0) { /* use G format if decim is negative */ if ( sprintf(cval, "%.*G", -decim, dval) < 0) { ffpmsg("Error in ffd2e converting float to string"); *status = BAD_F2C; } else { /* test if E format was used, and there is no displayed decimal */ if ( !strchr(cval, '.') && strchr(cval,'E') ) { /* reformat value with a decimal point and single zero */ if ( sprintf(cval, "%.1E", dval) < 0) { ffpmsg("Error in ffd2e converting float to string"); *status = BAD_F2C; } return(*status); } } } else { if ( sprintf(cval, "%.*E", decim, dval) < 0) { ffpmsg("Error in ffd2e converting float to string"); *status = BAD_F2C; } } if (*status <= 0) { /* test if output string is 'NaN', 'INDEF', or 'INF' */ if (strchr(cval, 'N')) { ffpmsg("Error in ffd2e: double value is a NaN or INDEF"); *status = BAD_F2C; } else if ( !strchr(cval, '.') && !strchr(cval,'E') ) { /* add decimal point if necessary to distinquish from integer */ strcat(cval, "."); } } return(*status); } indi-0.5/src/cfitsio/fits_hdecompress.c0000644000175000017500000014475110610474374016067 0ustar jrjr/* ######################################################################### These routines to apply the H-compress decompression algorithm to a 2-D Fits image were written by R. White at the STScI and were obtained from the STScI at http://www.stsci.edu/software/hcompress.html This source file is a concatination of the following sources files in the original distribution hinv.c hsmooth.c undigitize.c decode.c dodecode.c qtree_decode.c qread.c bit_input.c The following modifications have been made to the original code: - commented out redundant "include" statements - added the nextchar global variable - changed all the 'extern' declarations to 'static', since all the routines are in the same source file - changed the first parameter in decode (and in lower level routines from a file stream to a char array - modified the myread routine, and lower level byte reading routines, to copy the input bytes to a char array, instead of reading them from a file stream - changed the function declarations to the more modern ANSI C style - changed calls to printf and perror to call the CFITSIO ffpmsg routine - replace "exit" statements with "return" statements ############################################################################ */ #include #include #include #include #include "fitsio2.h" /* WDP added test to see if min and max are already defined */ #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) #endif #ifndef max #define max(a,b) (((a)>(b))?(a):(b)) #endif #define input_nybble(infile) input_nbits(infile,4) static long nextchar; static int decode(unsigned char *infile, int *a, int *nx, int *ny, int *scale); static int decode64(unsigned char *infile, LONGLONG *a, int *nx, int *ny, int *scale); static int hinv(int a[], int nx, int ny, int smooth ,int scale); static int hinv64(LONGLONG a[], int nx, int ny, int smooth ,int scale); static void undigitize(int a[], int nx, int ny, int scale); static void undigitize64(LONGLONG a[], int nx, int ny, int scale); static void unshuffle(int a[], int n, int n2, int tmp[]); static void unshuffle64(LONGLONG a[], int n, int n2, LONGLONG tmp[]); static void hsmooth(int a[], int nxtop, int nytop, int ny, int scale); static void hsmooth64(LONGLONG a[], int nxtop, int nytop, int ny, int scale); static void qread(unsigned char *infile,char *a, int n); static int readint(unsigned char *infile); static LONGLONG readlonglong(unsigned char *infile); static int dodecode(unsigned char *infile, int a[], int nx, int ny, unsigned char nbitplanes[3]); static int dodecode64(unsigned char *infile, LONGLONG a[], int nx, int ny, unsigned char nbitplanes[3]); static int qtree_decode(unsigned char *infile, int a[], int n, int nqx, int nqy, int nbitplanes); static int qtree_decode64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes); static void start_inputing_bits(); static int input_bit(unsigned char *infile); static int input_nbits(unsigned char *infile, int n); static void qtree_expand(unsigned char *infile, unsigned char a[], int nx, int ny, unsigned char b[]); static void qtree_bitins(unsigned char a[], int nx, int ny, int b[], int n, int bit); static void qtree_bitins64(unsigned char a[], int nx, int ny, LONGLONG b[], int n, int bit); static void qtree_copy(unsigned char a[], int nx, int ny, unsigned char b[], int n); static void read_bdirect(unsigned char *infile, int a[], int n, int nqx, int nqy, unsigned char scratch[], int bit); static void read_bdirect64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, unsigned char scratch[], int bit); static int input_huffman(unsigned char *infile); static int myread(unsigned char *file, char buffer[], int n); /* ---------------------------------------------------------------------- */ int fits_hdecompress(unsigned char *input, int smooth, int *a, int *ny, int *nx, int *scale, int *status) { /* decompress the input byte stream using the H-compress algorithm input - input array of compressed bytes a - pre-allocated array to hold the output uncompressed image nx - returned X axis size ny - returned Y axis size NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat; if (*status > 0) return(*status); /* decode the input array */ stat = decode(input, a, nx, ny, scale); *status = stat; if (stat) return(*status); /* * Un-Digitize */ undigitize(a, *nx, *ny, *scale); /* * Inverse H-transform */ stat = hinv(a, *nx, *ny, smooth, *scale); *status = stat; return(*status); } /* ---------------------------------------------------------------------- */ int fits_hdecompress64(unsigned char *input, int smooth, LONGLONG *a, int *ny, int *nx, int *scale, int *status) { /* decompress the input byte stream using the H-compress algorithm input - input array of compressed bytes a - pre-allocated array to hold the output uncompressed image nx - returned X axis size ny - returned Y axis size NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat, *iarray, ii, nval; if (*status > 0) return(*status); /* decode the input array */ stat = decode64(input, a, nx, ny, scale); *status = stat; if (stat) return(*status); /* * Un-Digitize */ undigitize64(a, *nx, *ny, *scale); /* * Inverse H-transform */ stat = hinv64(a, *nx, *ny, smooth, *scale); *status = stat; /* pack the I*8 values back into an I*4 array */ iarray = (int *) a; nval = (*nx) * (*ny); for (ii = 0; ii < nval; ii++) iarray[ii] = (int) a[ii]; return(*status); } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* hinv.c Inverse H-transform of NX x NY integer image * * Programmer: R. White Date: 23 July 1993 */ /* ############################################################################ */ static int hinv(int a[], int nx, int ny, int smooth ,int scale) /* int smooth; 0 for no smoothing, else smooth during inversion int scale; used if smoothing is specified */ { int nmax, log2n, i, j, k; int nxtop,nytop,nxf,nyf,c; int oddx,oddy; int shift, bit0, bit1, bit2, mask0, mask1, mask2, prnd0, prnd1, prnd2, nrnd0, nrnd1, nrnd2, lowbit0, lowbit1; int h0, hx, hy, hc; int s10, s00; int *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<> 1; prnd1 = bit1 >> 1; prnd2 = bit2 >> 1; nrnd0 = prnd0 - 1; nrnd1 = prnd1 - 1; nrnd2 = prnd2 - 1; /* * round h0 to multiple of bit2 */ a[0] = (a[0] + ((a[0] >= 0) ? prnd2 : nrnd2)) & mask2; /* * do log2n expansions * * We're indexing a as a 2-D array with dimensions (nx,ny). */ nxtop = 1; nytop = 1; nxf = nx; nyf = ny; c = 1<=0; k--) { /* * this somewhat cryptic code generates the sequence * ntop[k-1] = (ntop[k]+1)/2, where ntop[log2n] = n */ c = c>>1; nxtop = nxtop<<1; nytop = nytop<<1; if (nxf <= c) { nxtop -= 1; } else { nxf -= c; } if (nyf <= c) { nytop -= 1; } else { nyf -= c; } /* * double shift and fix nrnd0 (because prnd0=0) on last pass */ if (k == 0) { nrnd0 = 0; shift = 2; } /* * unshuffle in each dimension to interleave coefficients */ for (i = 0; i= 0) ? prnd1 : nrnd1)) & mask1; hy = (hy + ((hy >= 0) ? prnd1 : nrnd1)) & mask1; hc = (hc + ((hc >= 0) ? prnd0 : nrnd0)) & mask0; /* * propagate bit0 of hc to hx,hy */ lowbit0 = hc & bit0; hx = (hx >= 0) ? (hx - lowbit0) : (hx + lowbit0); hy = (hy >= 0) ? (hy - lowbit0) : (hy + lowbit0); /* * Propagate bits 0 and 1 of hc,hx,hy to h0. * This could be simplified if we assume h0>0, but then * the inversion would not be lossless for images with * negative pixels. */ lowbit1 = (hc ^ hx ^ hy) & bit1; h0 = (h0 >= 0) ? (h0 + lowbit0 - lowbit1) : (h0 + ((lowbit0 == 0) ? lowbit1 : (lowbit0-lowbit1))); /* * Divide sums by 2 (4 last time) */ a[s10+1] = (h0 + hx + hy + hc) >> shift; a[s10 ] = (h0 + hx - hy - hc) >> shift; a[s00+1] = (h0 - hx + hy - hc) >> shift; a[s00 ] = (h0 - hx - hy + hc) >> shift; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = a[s00 ]; hx = a[s10 ]; hx = ((hx >= 0) ? (hx+prnd1) : (hx+nrnd1)) & mask1; lowbit1 = hx & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s10 ] = (h0 + hx) >> shift; a[s00 ] = (h0 - hx) >> shift; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = ny*i; for (j = 0; j= 0) ? (hy+prnd1) : (hy+nrnd1)) & mask1; lowbit1 = hy & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s00+1] = (h0 + hy) >> shift; a[s00 ] = (h0 - hy) >> shift; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00 ]; a[s00 ] = h0 >> shift; } } /* * divide all the masks and rounding values by 2 */ bit2 = bit1; bit1 = bit0; bit0 = bit0 >> 1; mask1 = mask0; mask0 = mask0 >> 1; prnd1 = prnd0; prnd0 = prnd0 >> 1; nrnd1 = nrnd0; nrnd0 = prnd0 - 1; } free(tmp); return(0); } /* ############################################################################ */ static int hinv64(LONGLONG a[], int nx, int ny, int smooth ,int scale) /* int smooth; 0 for no smoothing, else smooth during inversion int scale; used if smoothing is specified */ { int nmax, log2n, i, j, k; int nxtop,nytop,nxf,nyf,c; int oddx,oddy; int shift; LONGLONG mask0, mask1, mask2, prnd0, prnd1, prnd2, bit0, bit1, bit2; LONGLONG nrnd0, nrnd1, nrnd2, lowbit0, lowbit1; LONGLONG h0, hx, hy, hc; int s10, s00; LONGLONG *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<> 1; prnd1 = bit1 >> 1; prnd2 = bit2 >> 1; nrnd0 = prnd0 - 1; nrnd1 = prnd1 - 1; nrnd2 = prnd2 - 1; /* * round h0 to multiple of bit2 */ a[0] = (a[0] + ((a[0] >= 0) ? prnd2 : nrnd2)) & mask2; /* * do log2n expansions * * We're indexing a as a 2-D array with dimensions (nx,ny). */ nxtop = 1; nytop = 1; nxf = nx; nyf = ny; c = 1<=0; k--) { /* * this somewhat cryptic code generates the sequence * ntop[k-1] = (ntop[k]+1)/2, where ntop[log2n] = n */ c = c>>1; nxtop = nxtop<<1; nytop = nytop<<1; if (nxf <= c) { nxtop -= 1; } else { nxf -= c; } if (nyf <= c) { nytop -= 1; } else { nyf -= c; } /* * double shift and fix nrnd0 (because prnd0=0) on last pass */ if (k == 0) { nrnd0 = 0; shift = 2; } /* * unshuffle in each dimension to interleave coefficients */ for (i = 0; i= 0) ? prnd1 : nrnd1)) & mask1; hy = (hy + ((hy >= 0) ? prnd1 : nrnd1)) & mask1; hc = (hc + ((hc >= 0) ? prnd0 : nrnd0)) & mask0; /* * propagate bit0 of hc to hx,hy */ lowbit0 = hc & bit0; hx = (hx >= 0) ? (hx - lowbit0) : (hx + lowbit0); hy = (hy >= 0) ? (hy - lowbit0) : (hy + lowbit0); /* * Propagate bits 0 and 1 of hc,hx,hy to h0. * This could be simplified if we assume h0>0, but then * the inversion would not be lossless for images with * negative pixels. */ lowbit1 = (hc ^ hx ^ hy) & bit1; h0 = (h0 >= 0) ? (h0 + lowbit0 - lowbit1) : (h0 + ((lowbit0 == 0) ? lowbit1 : (lowbit0-lowbit1))); /* * Divide sums by 2 (4 last time) */ a[s10+1] = (h0 + hx + hy + hc) >> shift; a[s10 ] = (h0 + hx - hy - hc) >> shift; a[s00+1] = (h0 - hx + hy - hc) >> shift; a[s00 ] = (h0 - hx - hy + hc) >> shift; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = a[s00 ]; hx = a[s10 ]; hx = ((hx >= 0) ? (hx+prnd1) : (hx+nrnd1)) & mask1; lowbit1 = hx & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s10 ] = (h0 + hx) >> shift; a[s00 ] = (h0 - hx) >> shift; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = ny*i; for (j = 0; j= 0) ? (hy+prnd1) : (hy+nrnd1)) & mask1; lowbit1 = hy & bit1; h0 = (h0 >= 0) ? (h0 - lowbit1) : (h0 + lowbit1); a[s00+1] = (h0 + hy) >> shift; a[s00 ] = (h0 - hy) >> shift; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00 ]; a[s00 ] = h0 >> shift; } } /* * divide all the masks and rounding values by 2 */ bit2 = bit1; bit1 = bit0; bit0 = bit0 >> 1; mask1 = mask0; mask0 = mask0 >> 1; prnd1 = prnd0; prnd0 = prnd0 >> 1; nrnd1 = nrnd0; nrnd0 = prnd0 - 1; } free(tmp); return(0); } /* ############################################################################ */ static void unshuffle(int a[], int n, int n2, int tmp[]) /* int a[]; array to shuffle int n; number of elements to shuffle int n2; second dimension int tmp[]; scratch storage */ { int i; int nhalf; int *p1, *p2, *pt; /* * copy 2nd half of array to tmp */ nhalf = (n+1)>>1; pt = tmp; p1 = &a[n2*nhalf]; /* pointer to a[i] */ for (i=nhalf; i= 0; i--) { *p1 = *p2; p2 -= n2; p1 -= (n2+n2); } /* * now distribute 2nd half of array (in tmp) to odd elements */ pt = tmp; p1 = &a[n2]; /* pointer to a[i] */ for (i=1; i>1; pt = tmp; p1 = &a[n2*nhalf]; /* pointer to a[i] */ for (i=nhalf; i= 0; i--) { *p1 = *p2; p2 -= n2; p1 -= (n2+n2); } /* * now distribute 2nd half of array (in tmp) to odd elements */ pt = tmp; p1 = &a[n2]; /* pointer to a[i] */ for (i=1; i> 1); if (smax <= 0) return; ny2 = ny << 1; /* * We're indexing a as a 2-D array with dimensions (nxtop,ny) of which * only (nxtop,nytop) are used. The coefficients on the edge of the * array are not adjusted (which is why the loops below start at 2 * instead of 0 and end at nxtop-2 instead of nxtop.) */ /* * Adjust x difference hx */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 8. */ s = diff-(a[s10]<<3); s = (s>=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s10] = a[s10]+s; } s00 += 2; s10 += 2; } } /* * Adjust y difference hy */ for (i = 0; i=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s00+1] = a[s00+1]+s; } s00 += 2; s10 += 2; } } /* * Adjust curvature difference hc */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 64. */ s = diff-(a[s10+1]<<6); s = (s>=0) ? (s>>6) : ((s+63)>>6) ; s = max( min(s, smax), -smax); a[s10+1] = a[s10+1]+s; } s00 += 2; s10 += 2; } } } /* ############################################################################ */ static void hsmooth64(LONGLONG a[], int nxtop, int nytop, int ny, int scale) /* LONGLONG a[]; array of H-transform coefficients int nxtop,nytop; size of coefficient block to use int ny; actual 1st dimension of array int scale; truncation scale factor that was used */ { int i, j; int ny2, s10, s00; LONGLONG hm, h0, hp, hmm, hpm, hmp, hpp, hx2, hy2, diff, dmax, dmin, s, smax, m1, m2; /* * Maximum change in coefficients is determined by scale factor. * Since we rounded during division (see digitize.c), the biggest * permitted change is scale/2. */ smax = (scale >> 1); if (smax <= 0) return; ny2 = ny << 1; /* * We're indexing a as a 2-D array with dimensions (nxtop,ny) of which * only (nxtop,nytop) are used. The coefficients on the edge of the * array are not adjusted (which is why the loops below start at 2 * instead of 0 and end at nxtop-2 instead of nxtop.) */ /* * Adjust x difference hx */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 8. */ s = diff-(a[s10]<<3); s = (s>=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s10] = a[s10]+s; } s00 += 2; s10 += 2; } } /* * Adjust y difference hy */ for (i = 0; i=0) ? (s>>3) : ((s+7)>>3) ; s = max( min(s, smax), -smax); a[s00+1] = a[s00+1]+s; } s00 += 2; s10 += 2; } } /* * Adjust curvature difference hc */ for (i = 2; i=0, dmin<=0. */ if (dmin < dmax) { diff = max( min(diff, dmax), dmin); /* * Compute change in slope limited to range +/- smax. * Careful with rounding negative numbers when using * shift for divide by 64. */ s = diff-(a[s10+1]<<6); s = (s>=0) ? (s>>6) : ((s+63)>>6) ; s = max( min(s, smax), -smax); a[s10+1] = a[s10+1]+s; } s00 += 2; s10 += 2; } } } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* undigitize.c undigitize H-transform * * Programmer: R. White Date: 9 May 1991 */ /* ############################################################################ */ static void undigitize(int a[], int nx, int ny, int scale) { int *p; /* * multiply by scale */ if (scale <= 1) return; for (p=a; p <= &a[nx*ny-1]; p++) *p = (*p)*scale; } /* ############################################################################ */ static void undigitize64(LONGLONG a[], int nx, int ny, int scale) { LONGLONG *p, scale64; /* * multiply by scale */ if (scale <= 1) return; scale64 = (LONGLONG) scale; /* use a 64-bit int for efficiency in the big loop */ for (p=a; p <= &a[nx*ny-1]; p++) *p = (*p)*scale64; } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* decode.c read codes from infile and construct array * * Programmer: R. White Date: 2 February 1994 */ static char code_magic[2] = { (char)0xDD, (char)0x99 }; /* ############################################################################ */ static int decode(unsigned char *infile, int *a, int *nx, int *ny, int *scale) /* char *infile; input file int *a; address of output array [nx][ny] int *nx,*ny; size of output array int *scale; scale factor for digitization */ { LONGLONG sumall; int nel, stat; unsigned char nbitplanes[3]; char tmagic[2]; /* initialize the byte read position to the beginning of the array */; nextchar = 0; /* * File starts either with special 2-byte magic code or with * FITS keyword "SIMPLE =" */ qread(infile, tmagic, sizeof(tmagic)); /* * check for correct magic code value */ if (memcmp(tmagic,code_magic,sizeof(code_magic)) != 0) { ffpmsg("bad file format"); return(DATA_DECOMPRESSION_ERR); } *nx =readint(infile); /* x size of image */ *ny =readint(infile); /* y size of image */ *scale=readint(infile); /* scale factor for digitization */ nel = (*nx) * (*ny); /* sum of all pixels */ sumall=readlonglong(infile); /* # bits in quadrants */ qread(infile, (char *) nbitplanes, sizeof(nbitplanes)); stat = dodecode(infile, a, *nx, *ny, nbitplanes); /* * put sum of all pixels back into pixel 0 */ a[0] = (int) sumall; return(stat); } /* ############################################################################ */ static int decode64(unsigned char *infile, LONGLONG *a, int *nx, int *ny, int *scale) /* char *infile; input file LONGLONG *a; address of output array [nx][ny] int *nx,*ny; size of output array int *scale; scale factor for digitization */ { int nel, stat; LONGLONG sumall; unsigned char nbitplanes[3]; char tmagic[2]; /* initialize the byte read position to the beginning of the array */; nextchar = 0; /* * File starts either with special 2-byte magic code or with * FITS keyword "SIMPLE =" */ qread(infile, tmagic, sizeof(tmagic)); /* * check for correct magic code value */ if (memcmp(tmagic,code_magic,sizeof(code_magic)) != 0) { ffpmsg("bad file format"); return(DATA_DECOMPRESSION_ERR); } *nx =readint(infile); /* x size of image */ *ny =readint(infile); /* y size of image */ *scale=readint(infile); /* scale factor for digitization */ nel = (*nx) * (*ny); /* sum of all pixels */ sumall=readlonglong(infile); /* # bits in quadrants */ qread(infile, (char *) nbitplanes, sizeof(nbitplanes)); stat = dodecode64(infile, a, *nx, *ny, nbitplanes); /* * put sum of all pixels back into pixel 0 */ a[0] = sumall; return(stat); } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* dodecode.c Decode stream of characters on infile and return array * * This version encodes the different quadrants separately * * Programmer: R. White Date: 9 May 1991 */ /* ############################################################################ */ static int dodecode(unsigned char *infile, int a[], int nx, int ny, unsigned char nbitplanes[3]) /* int a[]; int nx,ny; Array dimensions are [nx][ny] unsigned char nbitplanes[3]; Number of bit planes in quadrants */ { int i, nel, nx2, ny2, stat; nel = nx*ny; nx2 = (nx+1)/2; ny2 = (ny+1)/2; /* * initialize a to zero */ for (i=0; inqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<= 0; bit--) { /* * Was bitplane was quadtree-coded or written directly? */ b = input_nybble(infile); if(b == 0) { /* * bit map was written directly */ read_bdirect(infile,a,n,nqx,nqy,scratch,bit); } else if (b != 0xf) { ffpmsg("qtree_decode: bad format code"); free(scratch); return(DATA_DECOMPRESSION_ERR); } else { /* * bitmap was quadtree-coded, do log2n expansions * * read first code */ scratch[0] = input_huffman(infile); /* * now do log2n expansions, reading codes from file as necessary */ nx = 1; ny = 1; nfx = nqx; nfy = nqy; c = 1<>1; nx = nx<<1; ny = ny<<1; if (nfx <= c) { nx -= 1; } else { nfx -= c; } if (nfy <= c) { ny -= 1; } else { nfy -= c; } qtree_expand(infile,scratch,nx,ny,scratch); } /* * now copy last set of 4-bit codes to bitplane bit of array a */ qtree_bitins(scratch,nqx,nqy,a,n,bit); } } free(scratch); return(0); } /* ############################################################################ */ static int qtree_decode64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes) /* char *infile; LONGLONG a[]; a is 2-D array with dimensions (n,n) int n; length of full row in a int nqx; partial length of row to decode int nqy; partial length of column (<=n) int nbitplanes; number of bitplanes to decode */ { int log2n, k, bit, b, nqmax; int nx,ny,nfx,nfy,c; int nqx2, nqy2; unsigned char *scratch; /* * log2n is log2 of max(nqx,nqy) rounded up to next power of 2 */ nqmax = (nqx>nqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<= 0; bit--) { /* * Was bitplane was quadtree-coded or written directly? */ b = input_nybble(infile); if(b == 0) { /* * bit map was written directly */ read_bdirect64(infile,a,n,nqx,nqy,scratch,bit); } else if (b != 0xf) { ffpmsg("qtree_decode64: bad format code"); free(scratch); return(DATA_DECOMPRESSION_ERR); } else { /* * bitmap was quadtree-coded, do log2n expansions * * read first code */ scratch[0] = input_huffman(infile); /* * now do log2n expansions, reading codes from file as necessary */ nx = 1; ny = 1; nfx = nqx; nfy = nqy; c = 1<>1; nx = nx<<1; ny = ny<<1; if (nfx <= c) { nx -= 1; } else { nfx -= c; } if (nfy <= c) { ny -= 1; } else { nfy -= c; } qtree_expand(infile,scratch,nx,ny,scratch); } /* * now copy last set of 4-bit codes to bitplane bit of array a */ qtree_bitins64(scratch,nqx,nqy,a,n,bit); } } free(scratch); return(0); } /* ############################################################################ */ /* * do one quadtree expansion step on array a[(nqx+1)/2,(nqy+1)/2] * results put into b[nqx,nqy] (which may be the same as a) */ static void qtree_expand(unsigned char *infile, unsigned char a[], int nx, int ny, unsigned char b[]) { int i; /* * first copy a to b, expanding each 4-bit value */ qtree_copy(a,nx,ny,b,ny); /* * now read new 4-bit values into b for each non-zero element */ for (i = nx*ny-1; i >= 0; i--) { if (b[i] != 0) b[i] = input_huffman(infile); } } /* ############################################################################ */ /* * copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding * each value to 2x2 pixels * a,b may be same array */ static void qtree_copy(unsigned char a[], int nx, int ny, unsigned char b[], int n) /* int n; declared y dimension of b */ { int i, j, k, nx2, ny2; int s00, s10; /* * first copy 4-bit values to b * start at end in case a,b are same array */ nx2 = (nx+1)/2; ny2 = (ny+1)/2; k = ny2*(nx2-1)+ny2-1; /* k is index of a[i,j] */ for (i = nx2-1; i >= 0; i--) { s00 = 2*(n*i+ny2-1); /* s00 is index of b[2*i,2*j] */ for (j = ny2-1; j >= 0; j--) { b[s00] = a[k]; k -= 1; s00 -= 2; } } /* * now expand each 2x2 block */ for (i = 0; i>1) & 1; b[s00+1] = (b[s00]>>2) & 1; b[s00 ] = (b[s00]>>3) & 1; s00 += 2; s10 += 2; } if (j < ny) { /* * row size is odd, do last element in row * s00+1, s10+1 are off edge */ b[s10 ] = (b[s00]>>1) & 1; b[s00 ] = (b[s00]>>3) & 1; } } if (i < nx) { /* * column size is odd, do last row * s10, s10+1 are off edge */ s00 = n*i; for (j = 0; j>2) & 1; b[s00 ] = (b[s00]>>3) & 1; s00 += 2; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[s00 ] = (b[s00]>>3) & 1; } } } /* ############################################################################ */ /* * Copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding * each value to 2x2 pixels and inserting into bitplane BIT of B. * A,B may NOT be same array (it wouldn't make sense to be inserting * bits into the same array anyway.) */ static void qtree_bitins(unsigned char a[], int nx, int ny, int b[], int n, int bit) /* int n; declared y dimension of b */ { int i, j, k; int s00, s10; /* * expand each 2x2 block */ k = 0; /* k is index of a[i/2,j/2] */ for (i = 0; i>1) & 1) << bit; b[s00+1] |= ((a[k]>>2) & 1) << bit; b[s00 ] |= ((a[k]>>3) & 1) << bit; s00 += 2; s10 += 2; k += 1; } if (j < ny) { /* * row size is odd, do last element in row * s00+1, s10+1 are off edge */ b[s10 ] |= ((a[k]>>1) & 1) << bit; b[s00 ] |= ((a[k]>>3) & 1) << bit; k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10, s10+1 are off edge */ s00 = n*i; for (j = 0; j>2) & 1) << bit; b[s00 ] |= ((a[k]>>3) & 1) << bit; s00 += 2; k += 1; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[s00 ] |= ((a[k]>>3) & 1) << bit; k += 1; } } } /* ############################################################################ */ /* * Copy 4-bit values from a[(nx+1)/2,(ny+1)/2] to b[nx,ny], expanding * each value to 2x2 pixels and inserting into bitplane BIT of B. * A,B may NOT be same array (it wouldn't make sense to be inserting * bits into the same array anyway.) */ static void qtree_bitins64(unsigned char a[], int nx, int ny, LONGLONG b[], int n, int bit) /* int n; declared y dimension of b */ { int i, j, k; int s00, s10; /* * expand each 2x2 block */ k = 0; /* k is index of a[i/2,j/2] */ for (i = 0; i>1) & 1) << bit; b[s00+1] |= ((((LONGLONG)a[k])>>2) & 1) << bit; b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; s00 += 2; s10 += 2; k += 1; } if (j < ny) { /* * row size is odd, do last element in row * s00+1, s10+1 are off edge */ b[s10 ] |= ((((LONGLONG)a[k])>>1) & 1) << bit; b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10, s10+1 are off edge */ s00 = n*i; for (j = 0; j>2) & 1) << bit; b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; s00 += 2; k += 1; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[s00 ] |= ((((LONGLONG)a[k])>>3) & 1) << bit; k += 1; } } } /* ############################################################################ */ static void read_bdirect(unsigned char *infile, int a[], int n, int nqx, int nqy, unsigned char scratch[], int bit) { int i; /* * read bit image packed 4 pixels/nybble */ for (i = 0; i < ((nqx+1)/2) * ((nqy+1)/2); i++) { scratch[i] = input_nybble(infile); } /* * insert in bitplane BIT of image A */ qtree_bitins(scratch,nqx,nqy,a,n,bit); } /* ############################################################################ */ static void read_bdirect64(unsigned char *infile, LONGLONG a[], int n, int nqx, int nqy, unsigned char scratch[], int bit) { int i; /* * read bit image packed 4 pixels/nybble */ for (i = 0; i < ((nqx+1)/2) * ((nqy+1)/2); i++) { scratch[i] = input_nybble(infile); } /* * insert in bitplane BIT of image A */ qtree_bitins64(scratch,nqx,nqy,a,n,bit); } /* ############################################################################ */ /* * Huffman decoding for fixed codes * * Coded values range from 0-15 * * Huffman code values (hex): * * 3e, 00, 01, 08, 02, 09, 1a, 1b, * 03, 1c, 0a, 1d, 0b, 1e, 3f, 0c * * and number of bits in each code: * * 6, 3, 3, 4, 3, 4, 5, 5, * 3, 5, 4, 5, 4, 5, 6, 4 */ static int input_huffman(unsigned char *infile) { int c; /* * get first 3 bits to start */ c = input_nbits(infile,3); if (c < 4) { /* * this is all we need * return 1,2,4,8 for c=0,1,2,3 */ return(1< 0) { total += nread; if (total==n) return(total); } */ memcpy(buffer, &file[nextchar], n); nextchar += n; return(n); } /* ############################################################################ */ /* ############################################################################ */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* BIT INPUT ROUTINES */ /* THE BIT BUFFER */ static int buffer2; /* Bits waiting to be input */ static int bits_to_go; /* Number of bits still in buffer */ /* INITIALIZE BIT INPUT */ /* ############################################################################ */ static void start_inputing_bits() { /* * Buffer starts out with no bits in it */ bits_to_go = 0; } /* ############################################################################ */ /* INPUT A BIT */ static int input_bit(unsigned char *infile) { if (bits_to_go == 0) { /* Read the next byte if no */ /* buffer2 = getc(infile); */ /* bits are left in buffer */ buffer2 = infile[nextchar]; nextchar++; /* if (buffer2 == EOF) { */ /* * end of file is an error for this application */ /* fprintf(stderr, "input_bit: unexpected end-of-file\n"); exit(-1); } */ bits_to_go = 8; } /* * Return the next bit */ bits_to_go -= 1; return((buffer2>>bits_to_go) & 1); } /* ############################################################################ */ /* INPUT N BITS (N must be <= 8) */ static int input_nbits(unsigned char *infile, int n) { int c; if (bits_to_go < n) { /* * need another byte's worth of bits */ buffer2 <<= 8; /* c = getc(infile); */ c = infile[nextchar]; nextchar++; /* if (c == EOF) { */ /* * end of file is an error for this application */ /* fprintf(stderr, "input_nbits: unexpected end-of-file\n"); exit(-1); } */ buffer2 |= c; bits_to_go += 8; } /* * now pick off the first n bits */ bits_to_go -= n; return( (buffer2>>bits_to_go) & ((1<= 8640 */ /* it is useful to identify certain specific types of machines */ #define NATIVE 0 /* machine that uses non-byteswapped IEEE formats */ #define OTHERTYPE 1 /* any other type of machine */ #define VAXVMS 3 /* uses an odd floating point format */ #define ALPHAVMS 4 /* uses an odd floating point format */ #define IBMPC 5 /* used in drvrfile.c to work around a bug on PCs */ #define CRAY 6 /* requires a special NaN test algorithm */ #define GFLOAT 1 /* used for VMS */ #define IEEEFLOAT 2 /* used for VMS */ /* ======================================================================= */ /* The following logic is used to determine the type machine, */ /* whether the bytes are swapped, and the number of bits in a long value */ /* ======================================================================= */ /* The following platforms have sizeof(long) == 8 */ /* This block of code should match a similar block in fitsio.h */ /* and the block of code at the beginning of f77_wrap.h */ #if defined(__alpha) && ( defined(__unix__) || defined(__NetBSD__) ) /* old Dec Alpha platforms running OSF */ #define BYTESWAPPED TRUE #define LONGSIZE 64 #elif defined(__sparcv9) /* SUN Solaris7 in 64-bit mode */ #define BYTESWAPPED FALSE #define MACHINE NATIVE #define LONGSIZE 64 #elif defined(__ia64__) || defined(__x86_64__) /* Intel itanium 64-bit PC, or AMD opteron 64-bit PC */ #define BYTESWAPPED TRUE #define LONGSIZE 64 #elif defined(_SX) /* Nec SuperUx */ #define BYTESWAPPED FALSE #define MACHINE NATIVE #define LONGSIZE 64 #elif defined(__powerpc64__) || defined(__64BIT__) /* IBM 64-bit AIX powerpc*/ /* could also test for __ppc64__ or __PPC64 */ #define BYTESWAPPED FALSE #define MACHINE NATIVE #define LONGSIZE 64 #elif defined(_MIPS_SZLONG) # if defined(MIPSEL) # define BYTESWAPPED TRUE # else # define BYTESWAPPED FALSE # define MACHINE NATIVE # endif # if _MIPS_SZLONG == 32 # define LONGSIZE 32 # elif _MIPS_SZLONG == 64 # define LONGSIZE 64 # else # error "can't handle long size given by _MIPS_SZLONG" # endif /* ============================================================== */ /* the following are all 32-bit byteswapped platforms */ #elif defined(vax) && defined(VMS) #define MACHINE VAXVMS #define BYTESWAPPED TRUE #elif defined(__alpha) && defined(__VMS) #if (__D_FLOAT == TRUE) /* this float option is the same as for VAX/VMS machines. */ #define MACHINE VAXVMS #define BYTESWAPPED TRUE #elif (__G_FLOAT == TRUE) /* G_FLOAT is the default for ALPHA VMS systems */ #define MACHINE ALPHAVMS #define BYTESWAPPED TRUE #define FLOATTYPE GFLOAT #elif (__IEEE_FLOAT == TRUE) #define MACHINE ALPHAVMS #define BYTESWAPPED TRUE #define FLOATTYPE IEEEFLOAT #endif /* end of alpha VMS case */ #elif defined(ultrix) && defined(unix) /* old Dec ultrix machines */ #define BYTESWAPPED TRUE #elif defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) \ || defined(_MSC_VER) || defined(__BORLANDC__) || defined(__TURBOC__) \ || defined(_NI_mswin_) || defined(__EMX__) /* generic 32-bit IBM PC */ #define MACHINE IBMPC #define BYTESWAPPED TRUE #elif defined(__arm__) /* This assumes all ARM are little endian. In the future, it might be */ /* necessary to use "if defined(__ARMEL__)" to distinguish little from big. */ /* (__ARMEL__ would be defined on little-endian, but not on big-endian). */ #define BYTESWAPPED TRUE #else /* assume all other machine uses the same IEEE formats as used in FITS files */ /* e.g., Macs fall into this category */ #define MACHINE NATIVE #define BYTESWAPPED FALSE #endif #ifndef MACHINE #define MACHINE OTHERTYPE #endif /* assume longs are 4 bytes long, unless previously set otherwise */ #ifndef LONGSIZE #define LONGSIZE 32 #endif /* end of block that determine long size and byte swapping */ /* ==================================================================== */ #define IGNORE_EOF 1 #define REPORT_EOF 0 #define DATA_UNDEFINED -1 #define NULL_UNDEFINED 1234554321 #define ASCII_NULL_UNDEFINED 1 /* indicate no defined null value */ #define maxvalue(A,B) ((A) > (B) ? (A) : (B)) #define minvalue(A,B) ((A) < (B) ? (A) : (B)) /* faster string comparison macros */ #define FSTRCMP(a,b) ((a)[0]<(b)[0]? -1:(a)[0]>(b)[0]?1:strcmp((a),(b))) #define FSTRNCMP(a,b,n) ((a)[0]<(b)[0]?-1:(a)[0]>(b)[0]?1:strncmp((a),(b),(n))) #if defined(__VMS) || defined(VMS) #define FNANMASK 0xFFFF /* mask all bits */ #define DNANMASK 0xFFFF /* mask all bits */ #else #define FNANMASK 0x7F80 /* mask bits 1 - 8; all set on NaNs */ /* all 0 on underflow or 0. */ #define DNANMASK 0x7FF0 /* mask bits 1 - 11; all set on NaNs */ /* all 0 on underflow or 0. */ #endif #if MACHINE == CRAY /* Cray machines: the large negative integer corresponds to the 3 most sig digits set to 1. If these 3 bits are set in a floating point number (64 bits), then it represents a reserved value (i.e., a NaN) */ #define fnan(L) ( (L) >= 0xE000000000000000 ? 1 : 0) ) #else /* these functions work for both big and little endian machines */ /* that use the IEEE floating point format for internal numbers */ /* These functions tests whether the float value is a reserved IEEE */ /* value such as a Not-a-Number (NaN), or underflow, overflow, or */ /* infinity. The functions returns 1 if the value is a NaN, overflow */ /* or infinity; it returns 2 if the value is an denormalized underflow */ /* value; otherwise it returns 0. fnan tests floats, dnan tests doubles */ #define fnan(L) \ ( (L & FNANMASK) == FNANMASK ? 1 : (L & FNANMASK) == 0 ? 2 : 0) #define dnan(L) \ ( (L & DNANMASK) == DNANMASK ? 1 : (L & DNANMASK) == 0 ? 2 : 0) #endif #define DSCHAR_MAX 127.49 /* max double value that fits in an signed char */ #define DSCHAR_MIN -128.49 /* min double value that fits in an signed char */ #define DUCHAR_MAX 255.49 /* max double value that fits in an unsigned char */ #define DUCHAR_MIN -0.49 /* min double value that fits in an unsigned char */ #define DUSHRT_MAX 65535.49 /* max double value that fits in a unsigned short*/ #define DUSHRT_MIN -0.49 /* min double value that fits in an unsigned short */ #define DSHRT_MAX 32767.49 /* max double value that fits in a short */ #define DSHRT_MIN -32768.49 /* min double value that fits in a short */ #if LONGSIZE == 32 # define DLONG_MAX 2147483647.49 /* max double value that fits in a long */ # define DLONG_MIN -2147483648.49 /* min double value that fits in a long */ # define DULONG_MAX 4294967295.49 /* max double that fits in a unsigned long */ #else # define DLONG_MAX 9.2233720368547752E18 /* max double value long */ # define DLONG_MIN -9.2233720368547752E18 /* min double value long */ # define DULONG_MAX 1.84467440737095504E19 /* max double value ulong */ #endif #define DULONG_MIN -0.49 /* min double value that fits in an unsigned long */ #define DLONGLONG_MAX 9.2233720368547755807E18 /* max double value longlong */ #define DLONGLONG_MIN -9.2233720368547755808E18 /* min double value longlong */ #define DUINT_MAX 4294967295.49 /* max dbl that fits in a unsigned 4-byte int */ #define DUINT_MIN -0.49 /* min dbl that fits in an unsigned 4-byte int */ #define DINT_MAX 2147483647.49 /* max double value that fits in a 4-byte int */ #define DINT_MIN -2147483648.49 /* min double value that fits in a 4-byte int */ #ifndef UINT32_MAX #define UINT32_MAX 4294967295U /* max unsigned 32-bit integer */ #endif #ifndef INT32_MAX #define INT32_MAX 2147483647 /* max 32-bit integer */ #endif #ifndef INT32_MIN #define INT32_MIN (-INT32_MAX -1) /* min 32-bit integer */ #endif #ifndef LONGLONG_MAX #ifdef LLONG_MAX /* Linux and Solaris definition */ #define LONGLONG_MAX LLONG_MAX #define LONGLONG_MIN LLONG_MIN #elif defined(LONG_LONG_MAX) #define LONGLONG_MAX LONG_LONG_MAX #define LONGLONG_MIN LONG_LONG_MIN #elif defined(__LONG_LONG_MAX__) /* Mac OS X & CYGWIN defintion */ #define LONGLONG_MAX __LONG_LONG_MAX__ #define LONGLONG_MIN (-LONGLONG_MAX -1LL) #elif defined(INT64_MAX) /* windows definition */ #define LONGLONG_MAX INT64_MAX #define LONGLONG_MIN INT64_MIN #elif defined(_I64_MAX) /* windows definition */ #define LONGLONG_MAX _I64_MAX #define LONGLONG_MIN _I64_MIN #elif (LONGSIZE == 64) /* sizeof(long) = 64 */ #define LONGLONG_MAX 9223372036854775807L /* max 64-bit integer */ #define LONGLONG_MIN (-LONGLONG_MAX -1L) /* min 64-bit integer */ #else /* define a default value, even if it is never used */ #define LONGLONG_MAX 9223372036854775807LL /* max 64-bit integer */ #define LONGLONG_MIN (-LONGLONG_MAX -1LL) /* min 64-bit integer */ #endif #endif /* end of ndef LONGLONG_MAX section */ #define COMPRESS_NULL_VALUE -2147483647 int ffmkky(char *keyname, char *keyval, char *comm, char *card, int *status); int ffgnky(fitsfile *fptr, char *card, int *status); void ffcfmt(char *tform, char *cform); void ffcdsp(char *tform, char *cform); void ffswap2(short *values, long nvalues); void ffswap4(INT32BIT *values, long nvalues); void ffswap8(double *values, long nvalues); int ffi2c(LONGLONG ival, char *cval, int *status); int ffl2c(int lval, char *cval, int *status); int ffs2c(char *instr, char *outstr, int *status); int ffr2f(float fval, int decim, char *cval, int *status); int ffr2e(float fval, int decim, char *cval, int *status); int ffd2f(double dval, int decim, char *cval, int *status); int ffd2e(double dval, int decim, char *cval, int *status); int ffc2ii(char *cval, long *ival, int *status); int ffc2jj(char *cval, LONGLONG *ival, int *status); int ffc2ll(char *cval, int *lval, int *status); int ffc2rr(char *cval, float *fval, int *status); int ffc2dd(char *cval, double *dval, int *status); int ffc2x(char *cval, char *dtype, long *ival, int *lval, char *sval, double *dval, int *status); int ffc2s(char *instr, char *outstr, int *status); int ffc2i(char *cval, long *ival, int *status); int ffc2j(char *cval, LONGLONG *ival, int *status); int ffc2r(char *cval, float *fval, int *status); int ffc2d(char *cval, double *dval, int *status); int ffc2l(char *cval, int *lval, int *status); void ffxmsg(int action, char *err_message); int ffgcnt(fitsfile *fptr, char *value, int *status); int ffgtkn(fitsfile *fptr, int numkey, char *keyname, long *value, int *status); int ffgtknjj(fitsfile *fptr, int numkey, char *keyname, LONGLONG *value, int *status); int fftkyn(fitsfile *fptr, int numkey, char *keyname, char *value, int *status); int ffgphd(fitsfile *fptr, int maxdim, int *simple, int *bitpix, int *naxis, LONGLONG naxes[], long *pcount, long *gcount, int *extend, double *bscale, double *bzero, LONGLONG *blank, int *nspace, int *status); int ffgttb(fitsfile *fptr, LONGLONG *rowlen, LONGLONG *nrows, LONGLONG *pcount, long *tfield, int *status); int ffmkey(fitsfile *fptr, char *card, int *status); /* ffmbyt has been moved to fitsio.h */ int ffgbyt(fitsfile *fptr, LONGLONG nbytes, void *buffer, int *status); int ffpbyt(fitsfile *fptr, LONGLONG nbytes, void *buffer, int *status); int ffgbytoff(fitsfile *fptr, long gsize, long ngroups, long offset, void *buffer, int *status); int ffpbytoff(fitsfile *fptr, long gsize, long ngroups, long offset, void *buffer, int *status); int ffldrc(fitsfile *fptr, long record, int err_mode, int *status); int ffwhbf(fitsfile *fptr, int *nbuff); int ffbfeof(fitsfile *fptr, int *status); int ffbfwt(int nbuff, int *status); int fits_get_num_files(void); int ffpxsz(int datatype); int ffourl(char *url, char *urltype, char *outfile, char *tmplfile, char *compspec, int *status); int ffparsecompspec(fitsfile *fptr, char *compspec, int *status); int ffoptplt(fitsfile *fptr, const char *tempname, int *status); int fits_is_this_a_copy(char *urltype); int fits_store_Fptr(FITSfile *Fptr, int *status); int fits_clear_Fptr(FITSfile *Fptr, int *status); int fits_already_open(fitsfile **fptr, char *url, char *urltype, char *infile, char *extspec, char *rowfilter, char *binspec, char *colspec, int mode,int *isopen, int *status); int ffedit_columns(fitsfile **fptr, char *outfile, char *expr, int *status); int fits_get_col_minmax(fitsfile *fptr, int colnum, float *datamin, float *datamax, int *status); int ffwritehisto(long totaln, long offset, long firstn, long nvalues, int narrays, iteratorCol *imagepars, void *userPointer); int ffcalchist(long totalrows, long offset, long firstrow, long nrows, int ncols, iteratorCol *colpars, void *userPointer); int ffrhdu(fitsfile *fptr, int *hdutype, int *status); int ffpinit(fitsfile *fptr, int *status); int ffainit(fitsfile *fptr, int *status); int ffbinit(fitsfile *fptr, int *status); int ffchdu(fitsfile *fptr, int *status); int ffwend(fitsfile *fptr, int *status); int ffpdfl(fitsfile *fptr, int *status); int ffuptf(fitsfile *fptr, int *status); int ffdblk(fitsfile *fptr, long nblocks, int *status); int ffgext(fitsfile *fptr, int moveto, int *exttype, int *status); int ffgtbc(fitsfile *fptr, LONGLONG *totalwidth, int *status); int ffgtbp(fitsfile *fptr, char *name, char *value, int *status); int ffiblk(fitsfile *fptr, long nblock, int headdata, int *status); int ffshft(fitsfile *fptr, LONGLONG firstbyte, LONGLONG nbytes, LONGLONG nshift, int *status); int ffgcprll(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int writemode, double *scale, double *zero, char *tform, long *twidth, int *tcode, int *maxelem, LONGLONG *startpos, LONGLONG *elemnum, long *incre, LONGLONG *repeat, LONGLONG *rowlen, int *hdutype, LONGLONG *tnull, char *snull, int *status); int ffflushx(FITSfile *fptr); int ffseek(FITSfile *fptr, LONGLONG position); int ffread(FITSfile *fptr, long nbytes, void *buffer, int *status); int ffwrite(FITSfile *fptr, long nbytes, void *buffer, int *status); int fftrun(fitsfile *fptr, LONGLONG filesize, int *status); int ffpcluc(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *status); int ffgcll(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int nultyp, char nulval, char *array, char *nularray, int *anynul, int *status); int ffgcls(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int nultyp, char *nulval, char **array, char *nularray, int *anynul, int *status); int ffgcls2(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int nultyp, char *nulval, char **array, char *nularray, int *anynul, int *status); int ffgclb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, unsigned char nulval, unsigned char *array, char *nularray, int *anynul, int *status); int ffgclsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, signed char nulval, signed char *array, char *nularray, int *anynul, int *status); int ffgclui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, unsigned short nulval, unsigned short *array, char *nularray, int *anynul, int *status); int ffgcli(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, short nulval, short *array, char *nularray, int *anynul, int *status); int ffgcluj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, unsigned long nulval, unsigned long *array, char *nularray, int *anynul, int *status); int ffgcljj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, LONGLONG nulval, LONGLONG *array, char *nularray, int *anynul, int *status); int ffgclj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, long nulval, long *array, char *nularray, int *anynul, int *status); int ffgcluk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, unsigned int nulval, unsigned int *array, char *nularray, int *anynul, int *status); int ffgclk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, int nulval, int *array, char *nularray, int *anynul, int *status); int ffgcle(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, float nulval, float *array, char *nularray, int *anynul, int *status); int ffgcld(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long elemincre, int nultyp, double nulval, double *array, char *nularray, int *anynul, int *status); int ffpi1b(fitsfile *fptr, long nelem, long incre, unsigned char *buffer, int *status); int ffpi2b(fitsfile *fptr, long nelem, long incre, short *buffer, int *status); int ffpi4b(fitsfile *fptr, long nelem, long incre, INT32BIT *buffer, int *status); int ffpi8b(fitsfile *fptr, long nelem, long incre, long *buffer, int *status); int ffpr4b(fitsfile *fptr, long nelem, long incre, float *buffer, int *status); int ffpr8b(fitsfile *fptr, long nelem, long incre, double *buffer, int *status); int ffgi1b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, unsigned char *buffer, int *status); int ffgi2b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, short *buffer, int *status); int ffgi4b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, INT32BIT *buffer, int *status); int ffgi8b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, long *buffer, int *status); int ffgr4b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, float *buffer, int *status); int ffgr8b(fitsfile *fptr, LONGLONG pos, long nelem, long incre, double *buffer, int *status); int ffcins(fitsfile *fptr, LONGLONG naxis1, LONGLONG naxis2, LONGLONG nbytes, LONGLONG bytepos, int *status); int ffcdel(fitsfile *fptr, LONGLONG naxis1, LONGLONG naxis2, LONGLONG nbytes, LONGLONG bytepos, int *status); int ffkshf(fitsfile *fptr, int firstcol, int tfields, int nshift, int *status); int fffi1i1(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffi2i1(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffi4i1(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffi8i1(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffr4i1(float *input, long ntodo, double scale, double zero, int nullcheck, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffr8i1(double *input, long ntodo, double scale, double zero, int nullcheck, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffstri1(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, unsigned char nullval, char *nullarray, int *anynull, unsigned char *output, int *status); int fffi1s1(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffi2s1(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffi4s1(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffi8s1(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffr4s1(float *input, long ntodo, double scale, double zero, int nullcheck, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffr8s1(double *input, long ntodo, double scale, double zero, int nullcheck, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffstrs1(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, signed char nullval, char *nullarray, int *anynull, signed char *output, int *status); int fffi1u2(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffi2u2(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffi4u2(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffi8u2(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffr4u2(float *input, long ntodo, double scale, double zero, int nullcheck, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffr8u2(double *input, long ntodo, double scale, double zero, int nullcheck, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffstru2(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, unsigned short nullval, char *nullarray, int *anynull, unsigned short *output, int *status); int fffi1i2(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffi2i2(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffi4i2(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffi8i2(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffr4i2(float *input, long ntodo, double scale, double zero, int nullcheck, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffr8i2(double *input, long ntodo, double scale, double zero, int nullcheck, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffstri2(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, short nullval, char *nullarray, int *anynull, short *output, int *status); int fffi1u4(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffi2u4(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffi4u4(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffi8u4(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffr4u4(float *input, long ntodo, double scale, double zero, int nullcheck, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffr8u4(double *input, long ntodo, double scale, double zero, int nullcheck, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffstru4(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, unsigned long nullval, char *nullarray, int *anynull, unsigned long *output, int *status); int fffi1i4(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffi2i4(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffi4i4(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffi8i4(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffr4i4(float *input, long ntodo, double scale, double zero, int nullcheck, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffr8i4(double *input, long ntodo, double scale, double zero, int nullcheck, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffstri4(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, long nullval, char *nullarray, int *anynull, long *output, int *status); int fffi1int(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffi2int(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffi4int(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffi8int(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffr4int(float *input, long ntodo, double scale, double zero, int nullcheck, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffr8int(double *input, long ntodo, double scale, double zero, int nullcheck, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffstrint(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, int nullval, char *nullarray, int *anynull, int *output, int *status); int fffi1uint(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffi2uint(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffi4uint(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffi8uint(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffr4uint(float *input, long ntodo, double scale, double zero, int nullcheck, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffr8uint(double *input, long ntodo, double scale, double zero, int nullcheck, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffstruint(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, unsigned int nullval, char *nullarray, int *anynull, unsigned int *output, int *status); int fffi1i8(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffi2i8(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffi4i8(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffi8i8(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffr4i8(float *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffr8i8(double *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffstri8(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, LONGLONG nullval, char *nullarray, int *anynull, LONGLONG *output, int *status); int fffi1r4(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffi2r4(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffi4r4(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffi8r4(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffr4r4(float *input, long ntodo, double scale, double zero, int nullcheck, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffr8r4(double *input, long ntodo, double scale, double zero, int nullcheck, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffstrr4(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, float nullval, char *nullarray, int *anynull, float *output, int *status); int fffi1r8(unsigned char *input, long ntodo, double scale, double zero, int nullcheck, unsigned char tnull, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffi2r8(short *input, long ntodo, double scale, double zero, int nullcheck, short tnull, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffi4r8(INT32BIT *input, long ntodo, double scale, double zero, int nullcheck, INT32BIT tnull, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffi8r8(LONGLONG *input, long ntodo, double scale, double zero, int nullcheck, LONGLONG tnull, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffr4r8(float *input, long ntodo, double scale, double zero, int nullcheck, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffr8r8(double *input, long ntodo, double scale, double zero, int nullcheck, double nullval, char *nullarray, int *anynull, double *output, int *status); int fffstrr8(char *input, long ntodo, double scale, double zero, long twidth, double power, int nullcheck, char *snull, double nullval, char *nullarray, int *anynull, double *output, int *status); int ffi1fi1(unsigned char *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffs1fi1(signed char *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffu2fi1(unsigned short *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffi2fi1(short *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffu4fi1(unsigned long *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffi4fi1(long *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffi8fi1(LONGLONG *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffuintfi1(unsigned int *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffintfi1(int *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffr4fi1(float *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffr8fi1(double *array, long ntodo, double scale, double zero, unsigned char *buffer, int *status); int ffi1fi2(unsigned char *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffs1fi2(signed char *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffu2fi2(unsigned short *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffi2fi2(short *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffu4fi2(unsigned long *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffi4fi2(long *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffi8fi2(LONGLONG *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffuintfi2(unsigned int *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffintfi2(int *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffr4fi2(float *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffr8fi2(double *array, long ntodo, double scale, double zero, short *buffer, int *status); int ffi1fi4(unsigned char *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffs1fi4(signed char *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffu2fi4(unsigned short *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffi2fi4(short *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffu4fi4(unsigned long *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffi4fi4(long *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffi8fi4(LONGLONG *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffuintfi4(unsigned int *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffintfi4(int *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffr4fi4(float *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int ffr8fi4(double *array, long ntodo, double scale, double zero, INT32BIT *buffer, int *status); int fflongfi8(long *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffi8fi8(LONGLONG *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffi2fi8(short *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffi1fi8(unsigned char *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffs1fi8(signed char *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffr4fi8(float *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffr8fi8(double *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffintfi8(int *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffu2fi8(unsigned short *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffu4fi8(unsigned long *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffuintfi8(unsigned int *array, long ntodo, double scale, double zero, LONGLONG *buffer, int *status); int ffi1fr4(unsigned char *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffs1fr4(signed char *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffu2fr4(unsigned short *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffi2fr4(short *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffu4fr4(unsigned long *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffi4fr4(long *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffi8fr4(LONGLONG *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffuintfr4(unsigned int *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffintfr4(int *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffr4fr4(float *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffr8fr4(double *array, long ntodo, double scale, double zero, float *buffer, int *status); int ffi1fr8(unsigned char *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffs1fr8(signed char *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffu2fr8(unsigned short *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffi2fr8(short *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffu4fr8(unsigned long *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffi4fr8(long *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffi8fr8(LONGLONG *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffuintfr8(unsigned int *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffintfr8(int *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffr4fr8(float *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffr8fr8(double *array, long ntodo, double scale, double zero, double *buffer, int *status); int ffi1fstr(unsigned char *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffs1fstr(signed char *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffu2fstr(unsigned short *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffi2fstr(short *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffu4fstr(unsigned long *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffi4fstr(long *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffi8fstr(LONGLONG *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffintfstr(int *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffuintfstr(unsigned int *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffr4fstr(float *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); int ffr8fstr(double *input, long ntodo, double scale, double zero, char *cform, long twidth, char *output, int *status); /* the following 4 routines are VMS macros used on VAX or Alpha VMS */ void ieevpd(double *inarray, double *outarray, long *nvals); void ieevud(double *inarray, double *outarray, long *nvals); void ieevpr(float *inarray, float *outarray, long *nvals); void ieevur(float *inarray, float *outarray, long *nvals); /* routines related to the lexical parser */ int ffselect_table(fitsfile **fptr, char *outfile, char *expr, int *status); int ffiprs( fitsfile *fptr, int compressed, char *expr, int maxdim, int *datatype, long *nelem, int *naxis, long *naxes, int *status ); void ffcprs( void ); int ffcvtn( int inputType, void *input, char *undef, long ntodo, int outputType, void *nulval, void *output, int *anynull, int *status ); int parse_data( long totalrows, long offset, long firstrow, long nrows, int nCols, iteratorCol *colData, void *userPtr ); int uncompress_hkdata( fitsfile *fptr, long ntimes, double *times, int *status ); int ffffrw_work( long totalrows, long offset, long firstrow, long nrows, int nCols, iteratorCol *colData, void *userPtr ); /* image compression routines */ int fits_write_compressed_img(fitsfile *fptr, int datatype, long *fpixel, long *lpixel, int nullcheck, void *array, void *nulval, int *status); int fits_write_compressed_pixels(fitsfile *fptr, int datatype, LONGLONG fpixel, LONGLONG npixels, int nullcheck, void *array, void *nulval, int *status); int fits_write_compressed_img_plane(fitsfile *fptr, int datatype, int bytesperpixel, long nplane, long *firstcoord, long *lastcoord, long *naxes, int nullcheck, void *array, void *nullval, long *nread, int *status); int imcomp_init_table(fitsfile *outfptr, int bitpix, int naxis,long *naxes, int writebitpix, int *status); int imcomp_calc_max_elem (int comptype, int nx, int zbitpix, int blocksize); int imcomp_copy_imheader(fitsfile *infptr, fitsfile *outfptr, int *status); int imcomp_copy_img2comp(fitsfile *infptr, fitsfile *outfptr, int *status); int imcomp_copy_comp2img(fitsfile *infptr, fitsfile *outfptr, int norec, int *status); int imcomp_compress_image (fitsfile *infptr, fitsfile *outfptr, int *status); int imcomp_compress_tile (fitsfile *outfptr, long row, int datatype, void *tiledata, long tilelen, long nx, long ny, int *status); /* image decompression routines */ int fits_read_compressed_img(fitsfile *fptr, int datatype, LONGLONG *fpixel,LONGLONG *lpixel,long *inc, int nullcheck, void *nulval, void *array, char *nullarray, int *anynul, int *status); int fits_read_compressed_pixels(fitsfile *fptr, int datatype, LONGLONG fpixel, LONGLONG npixels, int nullcheck, void *nulval, void *array, char *nullarray, int *anynul, int *status); int fits_read_compressed_img_plane(fitsfile *fptr, int datatype, int bytesperpixel, long nplane, LONGLONG *firstcoord, LONGLONG *lastcoord, long *inc, long *naxes, int nullcheck, void *nullval, void *array, char *nullarray, int *anynul, long *nread, int *status); int imcomp_get_compressed_image_par(fitsfile *infptr, int *status); int imcomp_decompress_tile (fitsfile *infptr, int nrow, int tilesize, int datatype, int nullcheck, void *nulval, void *buffer, char *bnullarray, int *anynul, int *status); int imcomp_copy_overlap (char *tile, int pixlen, int ndim, long *tfpixel, long *tlpixel, char *bnullarray, char *image, long *fpixel, long *lpixel, long *inc, int nullcheck, char *nullarray, int *status); int imcomp_merge_overlap (char *tile, int pixlen, int ndim, long *tfpixel, long *tlpixel, char *bnullarray, char *image, long *fpixel, long *lpixel, int nullcheck, int *status); int fits_quantize_float (float fdata[], int nx, float in_null_value, int noise_bits, int idata[], double *bscale, double *bzero, int *iminval, int *imaxval); int fits_quantize_double (double fdata[], int nx, double in_null_value, int noise_bits, int idata[], double *bscale, double *bzero, int *iminval, int *imaxval); int fits_rcomp(int a[], int nx, unsigned char *c, int clen,int nblock); int fits_rdecomp (unsigned char *c, int clen, unsigned int array[], int nx, int nblock); int pl_p2li (int *pxsrc, int xs, short *lldst, int npix); int pl_l2pi (short *ll_src, int xs, int *px_dst, int npix); /* general driver routines */ int urltype2driver(char *urltype, int *driver); int fits_init_cfitsio(void); int fits_register_driver( char *prefix, int (*init)(void), int (*fitsshutdown)(void), int (*setoptions)(int option), int (*getoptions)(int *options), int (*getversion)(int *version), int (*checkfile) (char *urltype, char *infile, char *outfile), int (*fitsopen)(char *filename, int rwmode, int *driverhandle), int (*fitscreate)(char *filename, int *driverhandle), int (*fitstruncate)(int driverhandle, LONGLONG filesize), int (*fitsclose)(int driverhandle), int (*fremove)(char *filename), int (*size)(int driverhandle, LONGLONG *size), int (*flush)(int driverhandle), int (*seek)(int driverhandle, LONGLONG offset), int (*fitsread) (int driverhandle, void *buffer, long nbytes), int (*fitswrite)(int driverhandle, void *buffer, long nbytes)); /* file driver I/O routines */ int file_init(void); int file_setoptions(int options); int file_getoptions(int *options); int file_getversion(int *version); int file_shutdown(void); int file_checkfile(char *urltype, char *infile, char *outfile); int file_open(char *filename, int rwmode, int *driverhandle); int file_compress_open(char *filename, int rwmode, int *hdl); int file_openfile(char *filename, int rwmode, FILE **diskfile); int file_create(char *filename, int *driverhandle); int file_truncate(int driverhandle, LONGLONG filesize); int file_size(int driverhandle, LONGLONG *filesize); int file_close(int driverhandle); int file_remove(char *filename); int file_flush(int driverhandle); int file_seek(int driverhandle, LONGLONG offset); int file_read (int driverhandle, void *buffer, long nbytes); int file_write(int driverhandle, void *buffer, long nbytes); int file_is_compressed(char *filename); /* memory driver I/O routines */ int mem_init(void); int mem_setoptions(int options); int mem_getoptions(int *options); int mem_getversion(int *version); int mem_shutdown(void); int mem_create(char *filename, int *handle); int mem_create_comp(char *filename, int *handle); int mem_openmem(void **buffptr, size_t *buffsize, size_t deltasize, void *(*memrealloc)(void *p, size_t newsize), int *handle); int mem_createmem(size_t memsize, int *handle); int stdin_checkfile(char *urltype, char *infile, char *outfile); int stdin_open(char *filename, int rwmode, int *handle); int stdin2mem(int hd); int stdin2file(int hd); int stdout_close(int handle); int mem_compress_openrw(char *filename, int rwmode, int *hdl); int mem_compress_open(char *filename, int rwmode, int *hdl); int mem_compress_stdin_open(char *filename, int rwmode, int *hdl); int mem_iraf_open(char *filename, int rwmode, int *hdl); int mem_rawfile_open(char *filename, int rwmode, int *hdl); int mem_size(int handle, LONGLONG *filesize); int mem_truncate(int handle, LONGLONG filesize); int mem_close_free(int handle); int mem_close_keep(int handle); int mem_close_comp(int handle); int mem_seek(int handle, LONGLONG offset); int mem_read(int hdl, void *buffer, long nbytes); int mem_write(int hdl, void *buffer, long nbytes); int mem_uncompress2mem(char *filename, FILE *diskfile, int hdl); int iraf2mem(char *filename, char **buffptr, size_t *buffsize, size_t *filesize, int *status); /* root driver I/O routines */ int root_init(void); int root_setoptions(int options); int root_getoptions(int *options); int root_getversion(int *version); int root_shutdown(void); int root_open(char *filename, int rwmode, int *driverhandle); int root_create(char *filename, int *driverhandle); int root_close(int driverhandle); int root_flush(int driverhandle); int root_seek(int driverhandle, LONGLONG offset); int root_read (int driverhandle, void *buffer, long nbytes); int root_write(int driverhandle, void *buffer, long nbytes); int root_size(int handle, LONGLONG *filesize); /* http driver I/O routines */ int http_checkfile(char *urltype, char *infile, char *outfile); int http_open(char *filename, int rwmode, int *driverhandle); int http_file_open(char *filename, int rwmode, int *driverhandle); int http_compress_open(char *filename, int rwmode, int *driverhandle); /* ftp driver I/O routines */ int ftp_checkfile(char *urltype, char *infile, char *outfile); int ftp_open(char *filename, int rwmode, int *driverhandle); int ftp_file_open(char *filename, int rwmode, int *driverhandle); int ftp_compress_open(char *filename, int rwmode, int *driverhandle); int uncompress2mem(char *filename, FILE *diskfile, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int uncompress2mem_from_mem( char *inmemptr, size_t inmemsize, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int uncompress2file(char *filename, FILE *indiskfile, FILE *outdiskfile, int *status); int compress2mem_from_mem( char *inmemptr, size_t inmemsize, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int compress2file_from_mem( char *inmemptr, size_t inmemsize, FILE *outdiskfile, size_t *filesize, /* O - size of file, in bytes */ int *status); #ifdef HAVE_GSIFTP /* prototypes for gsiftp driver I/O routines */ #include "drvrgsiftp.h" #endif #ifdef HAVE_SHMEM_SERVICES /* prototypes for shared memory driver I/O routines */ #include "drvrsmem.h" #endif #if defined(vms) || defined(__vms) || defined(WIN32) || defined(__WIN32__) || (defined(macintosh) && !defined(TARGET_API_MAC_CARBON)) /* A hack for nonunix machines, which lack strcasecmp and strncasecmp */ int strcasecmp (const char *s1, const char *s2 ); int strncasecmp(const char *s1, const char *s2, size_t n); #endif /* end of the entire "ifndef _FITSIO2_H" block */ #endif indi-0.5/src/cfitsio/edithdu.c0000644000175000017500000007322310610474374014147 0ustar jrjr/* This file, edithdu.c, contains the FITSIO routines related to */ /* copying, inserting, or deleting HDUs in a FITS file */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffcopy(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int morekeys, /* I - reserve space in output header */ int *status) /* IO - error status */ /* copy the CHDU from infptr to the CHDU of outfptr. This will also allocate space in the output header for MOREKY keywords */ { if (*status > 0) return(*status); if (infptr == outfptr) return(*status = SAME_FILE); if (ffcphd(infptr, outfptr, status) ) /* copy the header keywords */ return(*status); if (morekeys > 0) ffhdef(outfptr, morekeys, status); /* reserve space for more keywords */ ffcpdt(infptr, outfptr, status); /* now copy the data unit */ return(*status); } /*--------------------------------------------------------------------------*/ int ffcpfl(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int previous, /* I - copy any previous HDUs? */ int current, /* I - copy the current HDU? */ int following, /* I - copy any following HDUs? */ int *status) /* IO - error status */ /* copy all or part of the input file to the output file. */ { int hdunum, ii; if (*status > 0) return(*status); if (infptr == outfptr) return(*status = SAME_FILE); ffghdn(infptr, &hdunum); if (previous) { /* copy any previous HDUs */ for (ii=1; ii < hdunum; ii++) { ffmahd(infptr, ii, NULL, status); ffcopy(infptr, outfptr, 0, status); } } if (current && (*status <= 0) ) { /* copy current HDU */ ffmahd(infptr, hdunum, NULL, status); ffcopy(infptr, outfptr, 0, status); } if (following && (*status <= 0) ) { /* copy any remaining HDUs */ ii = hdunum + 1; while (1) { if (ffmahd(infptr, ii, NULL, status) ) { /* reset expected end of file status */ if (*status == END_OF_FILE) *status = 0; break; } if (ffcopy(infptr, outfptr, 0, status)) break; /* quit on unexpected error */ ii++; } } ffmahd(infptr, hdunum, NULL, status); /* restore initial position */ return(*status); } /*--------------------------------------------------------------------------*/ int ffcphd(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int *status) /* IO - error status */ /* copy the header keywords from infptr to outfptr. */ { int nkeys, ii, inPrim = 0, outPrim = 0; long naxis, naxes[1]; char *card, comm[FLEN_COMMENT]; char *tmpbuff = NULL; if (*status > 0) return(*status); if (infptr == outfptr) return(*status = SAME_FILE); /* set the input pointer to the correct HDU */ if (infptr->HDUposition != (infptr->Fptr)->curhdu) ffmahd(infptr, (infptr->HDUposition) + 1, NULL, status); if (ffghsp(infptr, &nkeys, NULL, status) > 0) /* get no. of keywords */ return(*status); /* create a memory buffer to hold the header records */ tmpbuff = (char*) malloc(nkeys*FLEN_CARD*sizeof(char)); if (!tmpbuff) return(*status = MEMORY_ALLOCATION); /* read all of the header records in the input HDU */ for (ii = 0; ii < nkeys; ii++) ffgrec(infptr, ii+1, tmpbuff + (ii * FLEN_CARD), status); if (infptr->HDUposition == 0) /* set flag if this is the Primary HDU */ inPrim = 1; /* if input is an image hdu, get the number of axes */ naxis = -1; /* negative if HDU is a table */ if ((infptr->Fptr)->hdutype == IMAGE_HDU) ffgkyj(infptr, "NAXIS", &naxis, NULL, status); /* set the output pointer to the correct HDU */ if (outfptr->HDUposition != (outfptr->Fptr)->curhdu) ffmahd(outfptr, (outfptr->HDUposition) + 1, NULL, status); /* check if output header is empty; if not create new empty HDU */ if ((outfptr->Fptr)->headend != (outfptr->Fptr)->headstart[(outfptr->Fptr)->curhdu] ) ffcrhd(outfptr, status); if (outfptr->HDUposition == 0) { if (naxis < 0) { /* the input HDU is a table, so we have to create */ /* a dummy Primary array before copying it to the output */ ffcrim(outfptr, 8, 0, naxes, status); ffcrhd(outfptr, status); /* create new empty HDU */ } else { /* set flag that this is the Primary HDU */ outPrim = 1; } } if (*status > 0) /* check for errors before proceeding */ { free(tmpbuff); return(*status); } if ( inPrim == 1 && outPrim == 0 ) { /* copying from primary array to image extension */ strcpy(comm, "IMAGE extension"); ffpkys(outfptr, "XTENSION", "IMAGE", comm, status); /* copy BITPIX through NAXISn keywords */ for (ii = 1; ii < 3 + naxis; ii++) { card = tmpbuff + (ii * FLEN_CARD); ffprec(outfptr, card, status); } strcpy(comm, "number of random group parameters"); ffpkyj(outfptr, "PCOUNT", 0, comm, status); strcpy(comm, "number of random groups"); ffpkyj(outfptr, "GCOUNT", 1, comm, status); /* copy remaining keywords, excluding EXTEND, and reference COMMENT keywords */ for (ii = 3 + naxis ; ii < nkeys; ii++) { card = tmpbuff+(ii * FLEN_CARD); if (FSTRNCMP(card, "EXTEND ", 8) && FSTRNCMP(card, "COMMENT FITS (Flexible Image Transport System) format is", 58) && FSTRNCMP(card, "COMMENT and Astrophysics', volume 376, page 3", 47) ) { ffprec(outfptr, card, status); } } } else if ( inPrim == 0 && outPrim == 1 ) { /* copying between image extension and primary array */ strcpy(comm, "file does conform to FITS standard"); ffpkyl(outfptr, "SIMPLE", TRUE, comm, status); /* copy BITPIX through NAXISn keywords */ for (ii = 1; ii < 3 + naxis; ii++) { card = tmpbuff + (ii * FLEN_CARD); ffprec(outfptr, card, status); } /* add the EXTEND keyword */ strcpy(comm, "FITS dataset may contain extensions"); ffpkyl(outfptr, "EXTEND", TRUE, comm, status); /* write standard block of self-documentating comments */ ffprec(outfptr, "COMMENT FITS (Flexible Image Transport System) format is defined in 'Astronomy", status); ffprec(outfptr, "COMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H", status); /* copy remaining keywords, excluding pcount, gcount */ for (ii = 3 + naxis; ii < nkeys; ii++) { card = tmpbuff+(ii * FLEN_CARD); if (FSTRNCMP(card, "PCOUNT ", 8) && FSTRNCMP(card, "GCOUNT ", 8)) { ffprec(outfptr, card, status); } } } else { /* input and output HDUs are same type; simply copy all keywords */ for (ii = 0; ii < nkeys; ii++) { card = tmpbuff+(ii * FLEN_CARD); ffprec(outfptr, card, status); } } free(tmpbuff); return(*status); } /*--------------------------------------------------------------------------*/ int ffcpdt(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int *status) /* IO - error status */ { /* copy the data unit from the CHDU of infptr to the CHDU of outfptr. This will overwrite any data already in the outfptr CHDU. */ long nb, ii; LONGLONG indatastart, indataend, outdatastart; char buffer[2880]; if (*status > 0) return(*status); if (infptr == outfptr) return(*status = SAME_FILE); ffghadll(infptr, NULL, &indatastart, &indataend, status); ffghadll(outfptr, NULL, &outdatastart, NULL, status); /* Calculate the number of blocks to be copied */ nb = (long) ((indataend - indatastart) / 2880); if (nb > 0) { if (infptr->Fptr == outfptr->Fptr) { /* copying between 2 HDUs in the SAME file */ for (ii = 0; ii < nb; ii++) { ffmbyt(infptr, indatastart, REPORT_EOF, status); ffgbyt(infptr, 2880L, buffer, status); /* read input block */ ffmbyt(outfptr, outdatastart, IGNORE_EOF, status); ffpbyt(outfptr, 2880L, buffer, status); /* write output block */ indatastart += 2880; /* move address */ outdatastart += 2880; /* move address */ } } else { /* copying between HDUs in separate files */ /* move to the initial copy position in each of the files */ ffmbyt(infptr, indatastart, REPORT_EOF, status); ffmbyt(outfptr, outdatastart, IGNORE_EOF, status); for (ii = 0; ii < nb; ii++) { ffgbyt(infptr, 2880L, buffer, status); /* read input block */ ffpbyt(outfptr, 2880L, buffer, status); /* write output block */ } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffwrhdu(fitsfile *infptr, /* I - FITS file pointer to input file */ FILE *outstream, /* I - stream to write HDU to */ int *status) /* IO - error status */ { /* write the data unit from the CHDU of infptr to the output file stream */ long nb, ii; LONGLONG hdustart, hduend; char buffer[2880]; if (*status > 0) return(*status); ffghadll(infptr, &hdustart, NULL, &hduend, status); nb = (long) ((hduend - hdustart) / 2880); /* number of blocks to copy */ if (nb > 0) { /* move to the start of the HDU */ ffmbyt(infptr, hdustart, REPORT_EOF, status); for (ii = 0; ii < nb; ii++) { ffgbyt(infptr, 2880L, buffer, status); /* read input block */ fwrite(buffer, 1, 2880, outstream ); /* write to output stream */ } } return(*status); } /*--------------------------------------------------------------------------*/ int ffiimg(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ long *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* insert an IMAGE extension following the current HDU */ { LONGLONG tnaxes[99]; int ii; if (*status > 0) return(*status); if (naxis > 99) { ffpmsg("NAXIS value is too large (>99) (ffiimg)"); return(*status = 212); } for (ii = 0; (ii < naxis); ii++) tnaxes[ii] = naxes[ii]; ffiimgll(fptr, bitpix, naxis, tnaxes, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffiimgll(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ LONGLONG *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* insert an IMAGE extension following the current HDU */ { int bytlen, nexthdu, maxhdu, ii, onaxis; long nblocks; LONGLONG npixels, newstart, datasize; char errmsg[FLEN_ERRMSG], card[FLEN_CARD], naxiskey[FLEN_KEYWORD]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); maxhdu = (fptr->Fptr)->maxhdu; if (*status != PREPEND_PRIMARY) { /* if the current header is completely empty ... */ if (( (fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) /* or, if we are at the end of the file, ... */ || ( (((fptr->Fptr)->curhdu) == maxhdu ) && ((fptr->Fptr)->headstart[maxhdu + 1] >= (fptr->Fptr)->logfilesize ) ) ) { /* then simply append new image extension */ ffcrimll(fptr, bitpix, naxis, naxes, status); return(*status); } } if (bitpix == 8) bytlen = 1; else if (bitpix == 16) bytlen = 2; else if (bitpix == 32 || bitpix == -32) bytlen = 4; else if (bitpix == 64 || bitpix == -64) bytlen = 8; else { sprintf(errmsg, "Illegal value for BITPIX keyword: %d", bitpix); ffpmsg(errmsg); return(*status = BAD_BITPIX); /* illegal bitpix value */ } if (naxis < 0 || naxis > 999) { sprintf(errmsg, "Illegal value for NAXIS keyword: %d", naxis); ffpmsg(errmsg); return(*status = BAD_NAXIS); } for (ii = 0; ii < naxis; ii++) { if (naxes[ii] < 0) { sprintf(errmsg, "Illegal value for NAXIS%d keyword: %ld", ii + 1, (long) naxes[ii]); ffpmsg(errmsg); return(*status = BAD_NAXES); } } /* calculate number of pixels in the image */ if (naxis == 0) npixels = 0; else npixels = naxes[0]; for (ii = 1; ii < naxis; ii++) npixels = npixels * naxes[ii]; datasize = npixels * bytlen; /* size of image in bytes */ nblocks = (long) (((datasize + 2879) / 2880) + 1); /* +1 for the header */ if ((fptr->Fptr)->writemode == READWRITE) /* must have write access */ { /* close the CHDU */ ffrdef(fptr, status); /* scan header to redefine structure */ ffpdfl(fptr, status); /* insure correct data file values */ } else return(*status = READONLY_FILE); if (*status == PREPEND_PRIMARY) { /* inserting a new primary array; the current primary */ /* array must be transformed into an image extension. */ *status = 0; ffmahd(fptr, 1, NULL, status); /* move to the primary array */ ffgidm(fptr, &onaxis, status); if (onaxis > 0) ffkeyn("NAXIS",onaxis, naxiskey, status); else strcpy(naxiskey, "NAXIS"); ffgcrd(fptr, naxiskey, card, status); /* read last NAXIS keyword */ ffikyj(fptr, "PCOUNT", 0, "required keyword", status); /* add PCOUNT and */ ffikyj(fptr, "GCOUNT", 1, "required keyword", status); /* GCOUNT keywords */ if (*status > 0) return(*status); if (ffdkey(fptr, "EXTEND", status) ) /* delete the EXTEND keyword */ *status = 0; /* redefine internal structure for this HDU */ ffrdef(fptr, status); /* insert space for the primary array */ if (ffiblk(fptr, nblocks, -1, status) > 0) /* insert the blocks */ return(*status); nexthdu = 0; /* number of the new hdu */ newstart = 0; /* starting addr of HDU */ } else { nexthdu = ((fptr->Fptr)->curhdu) + 1; /* number of the next (new) hdu */ newstart = (fptr->Fptr)->headstart[nexthdu]; /* save starting addr of HDU */ (fptr->Fptr)->hdutype = IMAGE_HDU; /* so that correct fill value is used */ /* ffiblk also increments headstart for all following HDUs */ if (ffiblk(fptr, nblocks, 1, status) > 0) /* insert the blocks */ return(*status); } ((fptr->Fptr)->maxhdu)++; /* increment known number of HDUs in the file */ for (ii = (fptr->Fptr)->maxhdu; ii > (fptr->Fptr)->curhdu; ii--) (fptr->Fptr)->headstart[ii + 1] = (fptr->Fptr)->headstart[ii]; /* incre start addr */ if (nexthdu == 0) (fptr->Fptr)->headstart[1] = nblocks * 2880; /* start of the old Primary array */ (fptr->Fptr)->headstart[nexthdu] = newstart; /* set starting addr of HDU */ /* set default parameters for this new empty HDU */ (fptr->Fptr)->curhdu = nexthdu; /* we are now located at the next HDU */ fptr->HDUposition = nexthdu; /* we are now located at the next HDU */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->headend = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->datastart = ((fptr->Fptr)->headstart[nexthdu]) + 2880; (fptr->Fptr)->hdutype = IMAGE_HDU; /* might need to be reset... */ /* write the required header keywords */ ffphprll(fptr, TRUE, bitpix, naxis, naxes, 0, 1, TRUE, status); /* redefine internal structure for this HDU */ ffrdef(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffitab(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis1, /* I - width of row in the table */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ long *tbcol, /* I - byte offset in row to each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ char *extnm, /* I - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* insert an ASCII table extension following the current HDU */ { int nexthdu, maxhdu, ii, nunit, nhead, ncols, gotmem = 0; long nblocks, rowlen; LONGLONG datasize, newstart; char errmsg[81]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); maxhdu = (fptr->Fptr)->maxhdu; /* if the current header is completely empty ... */ if (( (fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) /* or, if we are at the end of the file, ... */ || ( (((fptr->Fptr)->curhdu) == maxhdu ) && ((fptr->Fptr)->headstart[maxhdu + 1] >= (fptr->Fptr)->logfilesize ) ) ) { /* then simply append new image extension */ ffcrtb(fptr, ASCII_TBL, naxis2, tfields, ttype, tform, tunit, extnm, status); return(*status); } if (naxis1 < 0) return(*status = NEG_WIDTH); else if (naxis2 < 0) return(*status = NEG_ROWS); else if (tfields < 0 || tfields > 999) { sprintf(errmsg, "Illegal value for TFIELDS keyword: %d", tfields); ffpmsg(errmsg); return(*status = BAD_TFIELDS); } /* count number of optional TUNIT keywords to be written */ nunit = 0; for (ii = 0; ii < tfields; ii++) { if (tunit && *tunit && *tunit[ii]) nunit++; } if (extnm && *extnm) nunit++; /* add one for the EXTNAME keyword */ rowlen = (long) naxis1; if (!tbcol || !tbcol[0] || (!naxis1 && tfields)) /* spacing not defined? */ { /* allocate mem for tbcol; malloc may have problems allocating small */ /* arrays, so allocate at least 20 bytes */ ncols = maxvalue(5, tfields); tbcol = (long *) calloc(ncols, sizeof(long)); if (tbcol) { gotmem = 1; /* calculate width of a row and starting position of each column. */ /* Each column will be separated by 1 blank space */ ffgabc(tfields, tform, 1, &rowlen, tbcol, status); } } nhead = (9 + (3 * tfields) + nunit + 35) / 36; /* no. of header blocks */ datasize = (LONGLONG)rowlen * naxis2; /* size of table in bytes */ nblocks = (long) (((datasize + 2879) / 2880) + nhead); /* size of HDU */ if ((fptr->Fptr)->writemode == READWRITE) /* must have write access */ { /* close the CHDU */ ffrdef(fptr, status); /* scan header to redefine structure */ ffpdfl(fptr, status); /* insure correct data file values */ } else { if (gotmem) free(tbcol); return(*status = READONLY_FILE); } nexthdu = ((fptr->Fptr)->curhdu) + 1; /* number of the next (new) hdu */ newstart = (fptr->Fptr)->headstart[nexthdu]; /* save starting addr of HDU */ (fptr->Fptr)->hdutype = ASCII_TBL; /* so that correct fill value is used */ /* ffiblk also increments headstart for all following HDUs */ if (ffiblk(fptr, nblocks, 1, status) > 0) /* insert the blocks */ { if (gotmem) free(tbcol); return(*status); } ((fptr->Fptr)->maxhdu)++; /* increment known number of HDUs in the file */ for (ii = (fptr->Fptr)->maxhdu; ii > (fptr->Fptr)->curhdu; ii--) (fptr->Fptr)->headstart[ii + 1] = (fptr->Fptr)->headstart[ii]; /* incre start addr */ (fptr->Fptr)->headstart[nexthdu] = newstart; /* set starting addr of HDU */ /* set default parameters for this new empty HDU */ (fptr->Fptr)->curhdu = nexthdu; /* we are now located at the next HDU */ fptr->HDUposition = nexthdu; /* we are now located at the next HDU */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->headend = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->datastart = ((fptr->Fptr)->headstart[nexthdu]) + (nhead * 2880); (fptr->Fptr)->hdutype = ASCII_TBL; /* might need to be reset... */ /* write the required header keywords */ ffphtb(fptr, rowlen, naxis2, tfields, ttype, tbcol, tform, tunit, extnm, status); if (gotmem) free(tbcol); /* redefine internal structure for this HDU */ ffrdef(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffibin(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis2, /* I - number of rows in the table */ int tfields, /* I - number of columns in the table */ char **ttype, /* I - name of each column */ char **tform, /* I - value of TFORMn keyword for each column */ char **tunit, /* I - value of TUNITn keyword for each column */ char *extnm, /* I - value of EXTNAME keyword, if any */ LONGLONG pcount, /* I - size of special data area (heap) */ int *status) /* IO - error status */ /* insert a Binary table extension following the current HDU */ { int nexthdu, maxhdu, ii, nunit, nhead, datacode; LONGLONG naxis1; long nblocks, repeat, width; LONGLONG datasize, newstart; char errmsg[81]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); maxhdu = (fptr->Fptr)->maxhdu; /* if the current header is completely empty ... */ if (( (fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) /* or, if we are at the end of the file, ... */ || ( (((fptr->Fptr)->curhdu) == maxhdu ) && ((fptr->Fptr)->headstart[maxhdu + 1] >= (fptr->Fptr)->logfilesize ) ) ) { /* then simply append new image extension */ ffcrtb(fptr, BINARY_TBL, naxis2, tfields, ttype, tform, tunit, extnm, status); return(*status); } if (naxis2 < 0) return(*status = NEG_ROWS); else if (tfields < 0 || tfields > 999) { sprintf(errmsg, "Illegal value for TFIELDS keyword: %d", tfields); ffpmsg(errmsg); return(*status = BAD_TFIELDS); } /* count number of optional TUNIT keywords to be written */ nunit = 0; for (ii = 0; ii < tfields; ii++) { if (tunit && *tunit && *tunit[ii]) nunit++; } if (extnm && *extnm) nunit++; /* add one for the EXTNAME keyword */ nhead = (9 + (2 * tfields) + nunit + 35) / 36; /* no. of header blocks */ /* calculate total width of the table */ naxis1 = 0; for (ii = 0; ii < tfields; ii++) { ffbnfm(tform[ii], &datacode, &repeat, &width, status); if (datacode == TBIT) naxis1 = naxis1 + ((repeat + 7) / 8); else if (datacode == TSTRING) naxis1 += repeat; else naxis1 = naxis1 + (repeat * width); } datasize = ((LONGLONG)naxis1 * naxis2) + pcount; /* size of table in bytes */ nblocks = (long) ((datasize + 2879) / 2880) + nhead; /* size of HDU */ if ((fptr->Fptr)->writemode == READWRITE) /* must have write access */ { /* close the CHDU */ ffrdef(fptr, status); /* scan header to redefine structure */ ffpdfl(fptr, status); /* insure correct data file values */ } else return(*status = READONLY_FILE); nexthdu = ((fptr->Fptr)->curhdu) + 1; /* number of the next (new) hdu */ newstart = (fptr->Fptr)->headstart[nexthdu]; /* save starting addr of HDU */ (fptr->Fptr)->hdutype = BINARY_TBL; /* so that correct fill value is used */ /* ffiblk also increments headstart for all following HDUs */ if (ffiblk(fptr, nblocks, 1, status) > 0) /* insert the blocks */ return(*status); ((fptr->Fptr)->maxhdu)++; /* increment known number of HDUs in the file */ for (ii = (fptr->Fptr)->maxhdu; ii > (fptr->Fptr)->curhdu; ii--) (fptr->Fptr)->headstart[ii + 1] = (fptr->Fptr)->headstart[ii]; /* incre start addr */ (fptr->Fptr)->headstart[nexthdu] = newstart; /* set starting addr of HDU */ /* set default parameters for this new empty HDU */ (fptr->Fptr)->curhdu = nexthdu; /* we are now located at the next HDU */ fptr->HDUposition = nexthdu; /* we are now located at the next HDU */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->headend = (fptr->Fptr)->headstart[nexthdu]; (fptr->Fptr)->datastart = ((fptr->Fptr)->headstart[nexthdu]) + (nhead * 2880); (fptr->Fptr)->hdutype = BINARY_TBL; /* might need to be reset... */ /* write the required header keywords. This will write PCOUNT = 0 */ /* so that the variable length data will be written at the right place */ ffphbn(fptr, naxis2, tfields, ttype, tform, tunit, extnm, pcount, status); /* redefine internal structure for this HDU (with PCOUNT = 0) */ ffrdef(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffdhdu(fitsfile *fptr, /* I - FITS file pointer */ int *hdutype, /* O - type of the new CHDU after deletion */ int *status) /* IO - error status */ /* Delete the CHDU. If the CHDU is the primary array, then replace the HDU with an empty primary array with no data. Return the type of the new CHDU after the old CHDU is deleted. */ { int tmptype = 0; long nblocks, ii, naxes[1]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->curhdu == 0) /* replace primary array with null image */ { /* ignore any existing keywords */ (fptr->Fptr)->headend = 0; (fptr->Fptr)->nextkey = 0; /* write default primary array header */ ffphpr(fptr,1,8,0,naxes,0,1,1,status); /* calc number of blocks to delete (leave just 1 block) */ nblocks = (long) (( (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu + 1] - 2880 ) / 2880); /* ffdblk also updates the starting address of all following HDUs */ if (nblocks > 0) { if (ffdblk(fptr, nblocks, status) > 0) /* delete the HDU */ return(*status); } /* this might not be necessary, but is doesn't hurt */ (fptr->Fptr)->datastart = DATA_UNDEFINED; ffrdef(fptr, status); /* reinitialize the primary array */ } else { /* calc number of blocks to delete */ nblocks = (long) (( (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu + 1] - (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) / 2880); /* ffdblk also updates the starting address of all following HDUs */ if (ffdblk(fptr, nblocks, status) > 0) /* delete the HDU */ return(*status); /* delete the CHDU from the list of HDUs */ for (ii = (fptr->Fptr)->curhdu + 1; ii <= (fptr->Fptr)->maxhdu; ii++) (fptr->Fptr)->headstart[ii] = (fptr->Fptr)->headstart[ii + 1]; (fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1] = 0; ((fptr->Fptr)->maxhdu)--; /* decrement the known number of HDUs */ if (ffrhdu(fptr, &tmptype, status) > 0) /* initialize next HDU */ { /* failed (end of file?), so move back one HDU */ *status = 0; ffcmsg(); /* clear extraneous error messages */ ffgext(fptr, ((fptr->Fptr)->curhdu) - 1, &tmptype, status); } } if (hdutype) *hdutype = tmptype; return(*status); } indi-0.5/src/cfitsio/putcoli.c0000644000175000017500000010341010610474375014171 0ustar jrjr/* This file, putcoli.c, contains routines that write data elements to */ /* a FITS image or table, with short datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppri( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ short *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; short nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TSHORT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcli(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppni( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ short *array, /* I - array of values that are written */ short nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; short nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TSHORT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcni(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2di(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3di(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3di(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TSHORT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcli(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcli(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssi(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TSHORT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcli(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpi( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ short *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcli(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcli( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ short *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped, then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise, we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TSHORT) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TSHORT): if (writeraw) { /* write raw input bytes without conversion */ ffpi2b(fptr, ntodo, incre, &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffi2fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); } break; case (TLONGLONG): ffi2fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffi2fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TLONG): ffi2fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffi2fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffi2fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffi2fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpcli).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcni( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ short *array, /* I - array of values to write */ short nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcli(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcli(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcli(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fi1(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fi2(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo * sizeof(short) ); } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fi4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; /* just copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fi8(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fr4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fr8(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffi2fstr(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } indi-0.5/src/cfitsio/group.h0000644000175000017500000000360610610474402013650 0ustar jrjr#define MAX_HDU_TRACKER 1000 typedef struct _HDUtracker HDUtracker; struct _HDUtracker { int nHDU; char *filename[MAX_HDU_TRACKER]; int position[MAX_HDU_TRACKER]; char *newFilename[MAX_HDU_TRACKER]; int newPosition[MAX_HDU_TRACKER]; }; /* functions used internally in the grouping convention module */ int ffgtdc(int grouptype, int xtensioncol, int extnamecol, int extvercol, int positioncol, int locationcol, int uricol, char *ttype[], char *tform[], int *ncols, int *status); int ffgtgc(fitsfile *gfptr, int *xtensionCol, int *extnameCol, int *extverCol, int *positionCol, int *locationCol, int *uriCol, int *grptype, int *status); int ffgmul(fitsfile *mfptr, int rmopt, int *status); int ffgmf(fitsfile *gfptr, char *xtension, char *extname, int extver, int position, char *location, long *member, int *status); int ffgtrmr(fitsfile *gfptr, HDUtracker *HDU, int *status); int ffgtcpr(fitsfile *infptr, fitsfile *outfptr, int cpopt, HDUtracker *HDU, int *status); int fftsad(fitsfile *mfptr, HDUtracker *HDU, int *newPosition, char *newFileName); int fftsud(fitsfile *mfptr, HDUtracker *HDU, int newPosition, char *newFileName); void prepare_keyvalue(char *keyvalue); int fits_path2url(char *inpath, char *outpath, int *status); int fits_url2path(char *inpath, char *outpath, int *status); int fits_get_cwd(char *cwd, int *status); int fits_get_url(fitsfile *fptr, char *realURL, char *startURL, char *realAccess, char *startAccess, int *iostate, int *status); int fits_clean_url(char *inURL, char *outURL, int *status); int fits_relurl2url(char *refURL, char *relURL, char *absURL, int *status); int fits_url2relurl(char *refURL, char *absURL, char *relURL, int *status); int fits_encode_url(char *inpath, char *outpath, int *status); int fits_unencode_url(char *inpath, char *outpath, int *status); int fits_is_url_absolute(char *url); indi-0.5/src/cfitsio/wcsutil.c0000644000175000017500000004555610610474375014224 0ustar jrjr#include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffwldp(double xpix, double ypix, double xref, double yref, double xrefpix, double yrefpix, double xinc, double yinc, double rot, char *type, double *xpos, double *ypos, int *status) /* WDP 1/97: change the name of the routine from 'worldpos' to 'ffwldp' */ /* worldpos.c -- WCS Algorithms from Classic AIPS. Copyright (C) 1994 Associated Universities, Inc. Washington DC, USA. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence concerning AIPS should be addressed as follows: Internet email: aipsmail@nrao.edu Postal address: AIPS Group National Radio Astronomy Observatory 520 Edgemont Road Charlottesville, VA 22903-2475 USA -=-=-=-=-=-=- These two ANSI C functions, worldpos() and xypix(), perform forward and reverse WCS computations for 8 types of projective geometries ("-SIN", "-TAN", "-ARC", "-NCP", "-GLS", "-MER", "-AIT" and "-STG"): worldpos() converts from pixel location to RA,Dec xypix() converts from RA,Dec to pixel location where "(RA,Dec)" are more generically (long,lat). These functions are based on the WCS implementation of Classic AIPS, an implementation which has been in production use for more than ten years. See the two memos by Eric Greisen ftp://fits.cv.nrao.edu/fits/documents/wcs/aips27.ps.Z ftp://fits.cv.nrao.edu/fits/documents/wcs/aips46.ps.Z for descriptions of the 8 projective geometries and the algorithms. Footnotes in these two documents describe the differences between these algorithms and the 1993-94 WCS draft proposal (see URL below). In particular, these algorithms support ordinary field rotation, but not skew geometries (CD or PC matrix cases). Also, the MER and AIT algorithms work correctly only for CRVALi=(0,0). Users should note that GLS projections with yref!=0 will behave differently in this code than in the draft WCS proposal. The NCP projection is now obsolete (it is a special case of SIN). WCS syntax and semantics for various advanced features is discussed in the draft WCS proposal by Greisen and Calabretta at: ftp://fits.cv.nrao.edu/fits/documents/wcs/wcs.all.ps.Z -=-=-=- The original version of this code was Emailed to D.Wells on Friday, 23 September by Bill Cotton , who described it as a "..more or less.. exact translation from the AIPSish..". Changes were made by Don Wells during the period October 11-13, 1994: 1) added GNU license and header comments 2) added testpos.c program to perform extensive circularity tests 3) changed float-->double to get more than 7 significant figures 4) testpos.c circularity test failed on MER and AIT. B.Cotton found that "..there were a couple of lines of code [in] the wrong place as a result of merging several Fortran routines." 5) testpos.c found 0h wraparound in xypix() and worldpos(). 6) E.Greisen recommended removal of various redundant if-statements, and addition of a 360d difference test to MER case of worldpos(). */ /*-----------------------------------------------------------------------*/ /* routine to determine accurate position for pixel coordinates */ /* returns 0 if successful otherwise: */ /* 1 = angle too large for projection; */ /* (WDP 1/97: changed the return value to 501 instead of 1) */ /* does: -SIN, -TAN, -ARC, -NCP, -GLS, -MER, -AIT projections */ /* anything else is linear (== -CAR) */ /* Input: */ /* f xpix x pixel number (RA or long without rotation) */ /* f ypiy y pixel number (dec or lat without rotation) */ /* d xref x reference coordinate value (deg) */ /* d yref y reference coordinate value (deg) */ /* f xrefpix x reference pixel */ /* f yrefpix y reference pixel */ /* f xinc x coordinate increment (deg) */ /* f yinc y coordinate increment (deg) */ /* f rot rotation (deg) (from N through E) */ /* c *type projection type code e.g. "-SIN"; */ /* Output: */ /* d *xpos x (RA) coordinate (deg) */ /* d *ypos y (dec) coordinate (deg) */ /*-----------------------------------------------------------------------*/ {double cosr, sinr, dx, dy, dz, temp, x, y, z; double sins, coss, dect, rat, dt, l, m, mg, da, dd, cos0, sin0; double dec0, ra0, decout, raout; double geo1, geo2, geo3; double cond2r=1.745329252e-2; double twopi = 6.28318530717959, deps = 1.0e-5; int i, itype; char ctypes[9][5] ={"-CAR","-SIN","-TAN","-ARC","-NCP", "-GLS", "-MER", "-AIT", "-STG"}; if (*status > 0) return(*status); /* Offset from ref pixel */ dx = (xpix-xrefpix) * xinc; dy = (ypix-yrefpix) * yinc; /* Take out rotation */ cosr = cos(rot*cond2r); sinr = sin(rot*cond2r); if (rot!=0.0) {temp = dx * cosr - dy * sinr; dy = dy * cosr + dx * sinr; dx = temp;} /* find type */ /* WDP 1/97: removed support for default type for better error checking */ /* itype = 0; default type is linear */ itype = -1; /* no default type */ for (i=0;i<9;i++) if (!strncmp(type, ctypes[i], 4)) itype = i; /* default, linear result for error return */ *xpos = xref + dx; *ypos = yref + dy; /* convert to radians */ ra0 = xref * cond2r; dec0 = yref * cond2r; l = dx * cond2r; m = dy * cond2r; sins = l*l + m*m; cos0 = cos(dec0); sin0 = sin(dec0); /* process by case */ switch (itype) { case 0: /* linear -CAR */ rat = ra0 + l; dect = dec0 + m; break; case 1: /* -SIN sin*/ if (sins>1.0) return(*status = 501); coss = sqrt (1.0 - sins); dt = sin0 * coss + cos0 * m; if ((dt>1.0) || (dt<-1.0)) return(*status = 501); dect = asin (dt); rat = cos0 * coss - sin0 * m; if ((rat==0.0) && (l==0.0)) return(*status = 501); rat = atan2 (l, rat) + ra0; break; case 2: /* -TAN tan */ x = cos0*cos(ra0) - l*sin(ra0) - m*cos(ra0)*sin0; y = cos0*sin(ra0) + l*cos(ra0) - m*sin(ra0)*sin0; z = sin0 + m* cos0; rat = atan2( y, x ); dect = atan ( z / sqrt(x*x+y*y) ); break; case 3: /* -ARC Arc*/ if (sins>=twopi*twopi/4.0) return(*status = 501); sins = sqrt(sins); coss = cos (sins); if (sins!=0.0) sins = sin (sins) / sins; else sins = 1.0; dt = m * cos0 * sins + sin0 * coss; if ((dt>1.0) || (dt<-1.0)) return(*status = 501); dect = asin (dt); da = coss - dt * sin0; dt = l * sins * cos0; if ((da==0.0) && (dt==0.0)) return(*status = 501); rat = ra0 + atan2 (dt, da); break; case 4: /* -NCP North celestial pole*/ dect = cos0 - m * sin0; if (dect==0.0) return(*status = 501); rat = ra0 + atan2 (l, dect); dt = cos (rat-ra0); if (dt==0.0) return(*status = 501); dect = dect / dt; if ((dect>1.0) || (dect<-1.0)) return(*status = 501); dect = acos (dect); if (dec0<0.0) dect = -dect; break; case 5: /* -GLS global sinusoid */ dect = dec0 + m; if (fabs(dect)>twopi/4.0) return(*status = 501); coss = cos (dect); if (fabs(l)>twopi*coss/2.0) return(*status = 501); rat = ra0; if (coss>deps) rat = rat + l / coss; break; case 6: /* -MER mercator*/ dt = yinc * cosr + xinc * sinr; if (dt==0.0) dt = 1.0; dy = (yref/2.0 + 45.0) * cond2r; dx = dy + dt / 2.0 * cond2r; dy = log (tan (dy)); dx = log (tan (dx)); geo2 = dt * cond2r / (dx - dy); geo3 = geo2 * dy; geo1 = cos (yref*cond2r); if (geo1<=0.0) geo1 = 1.0; rat = l / geo1 + ra0; if (fabs(rat - ra0) > twopi) return(*status = 501); /* added 10/13/94 DCW/EWG */ dt = 0.0; if (geo2!=0.0) dt = (m + geo3) / geo2; dt = exp (dt); dect = 2.0 * atan (dt) - twopi / 4.0; break; case 7: /* -AIT Aitoff*/ dt = yinc*cosr + xinc*sinr; if (dt==0.0) dt = 1.0; dt = dt * cond2r; dy = yref * cond2r; dx = sin(dy+dt)/sqrt((1.0+cos(dy+dt))/2.0) - sin(dy)/sqrt((1.0+cos(dy))/2.0); if (dx==0.0) dx = 1.0; geo2 = dt / dx; dt = xinc*cosr - yinc* sinr; if (dt==0.0) dt = 1.0; dt = dt * cond2r; dx = 2.0 * cos(dy) * sin(dt/2.0); if (dx==0.0) dx = 1.0; geo1 = dt * sqrt((1.0+cos(dy)*cos(dt/2.0))/2.0) / dx; geo3 = geo2 * sin(dy) / sqrt((1.0+cos(dy))/2.0); rat = ra0; dect = dec0; if ((l==0.0) && (m==0.0)) break; dz = 4.0 - l*l/(4.0*geo1*geo1) - ((m+geo3)/geo2)*((m+geo3)/geo2) ; if ((dz>4.0) || (dz<2.0)) return(*status = 501);; dz = 0.5 * sqrt (dz); dd = (m+geo3) * dz / geo2; if (fabs(dd)>1.0) return(*status = 501);; dd = asin (dd); if (fabs(cos(dd))1.0) return(*status = 501);; da = asin (da); rat = ra0 + 2.0 * da; dect = dd; break; case 8: /* -STG Sterographic*/ dz = (4.0 - sins) / (4.0 + sins); if (fabs(dz)>1.0) return(*status = 501); dect = dz * sin0 + m * cos0 * (1.0+dz) / 2.0; if (fabs(dect)>1.0) return(*status = 501); dect = asin (dect); rat = cos(dect); if (fabs(rat)1.0) return(*status = 501); rat = asin (rat); mg = 1.0 + sin(dect) * sin0 + cos(dect) * cos0 * cos(rat); if (fabs(mg)deps) rat = twopi/2.0 - rat; rat = ra0 + rat; break; default: /* fall through to here on error */ return(*status = 504); } /* return ra in range */ raout = rat; decout = dect; if (raout-ra0>twopi/2.0) raout = raout - twopi; if (raout-ra0<-twopi/2.0) raout = raout + twopi; if (raout < 0.0) raout += twopi; /* added by DCW 10/12/94 */ /* correct units back to degrees */ *xpos = raout / cond2r; *ypos = decout / cond2r; return(*status); } /* End of worldpos */ /*--------------------------------------------------------------------------*/ int ffxypx(double xpos, double ypos, double xref, double yref, double xrefpix, double yrefpix, double xinc, double yinc, double rot, char *type, double *xpix, double *ypix, int *status) /* WDP 1/97: changed name of routine from xypix to ffxypx */ /*-----------------------------------------------------------------------*/ /* routine to determine accurate pixel coordinates for an RA and Dec */ /* returns 0 if successful otherwise: */ /* 1 = angle too large for projection; */ /* 2 = bad values */ /* WDP 1/97: changed the return values to 501 and 502 instead of 1 and 2 */ /* does: -SIN, -TAN, -ARC, -NCP, -GLS, -MER, -AIT projections */ /* anything else is linear */ /* Input: */ /* d xpos x (RA) coordinate (deg) */ /* d ypos y (dec) coordinate (deg) */ /* d xref x reference coordinate value (deg) */ /* d yref y reference coordinate value (deg) */ /* f xrefpix x reference pixel */ /* f yrefpix y reference pixel */ /* f xinc x coordinate increment (deg) */ /* f yinc y coordinate increment (deg) */ /* f rot rotation (deg) (from N through E) */ /* c *type projection type code e.g. "-SIN"; */ /* Output: */ /* f *xpix x pixel number (RA or long without rotation) */ /* f *ypiy y pixel number (dec or lat without rotation) */ /*-----------------------------------------------------------------------*/ {double dx, dy, dz, r, ra0, dec0, ra, dec, coss, sins, dt, da, dd, sint; double l, m, geo1, geo2, geo3, sinr, cosr, cos0, sin0; double cond2r=1.745329252e-2, deps=1.0e-5, twopi=6.28318530717959; int i, itype; char ctypes[9][5] ={"-CAR","-SIN","-TAN","-ARC","-NCP", "-GLS", "-MER", "-AIT", "-STG"}; /* 0h wrap-around tests added by D.Wells 10/12/94: */ dt = (xpos - xref); if (dt > 180) xpos -= 360; if (dt < -180) xpos += 360; /* NOTE: changing input argument xpos is OK (call-by-value in C!) */ /* default values - linear */ dx = xpos - xref; dy = ypos - yref; /* dz = 0.0; */ /* Correct for rotation */ r = rot * cond2r; cosr = cos (r); sinr = sin (r); dz = dx*cosr + dy*sinr; dy = dy*cosr - dx*sinr; dx = dz; /* check axis increments - bail out if either 0 */ if ((xinc==0.0) || (yinc==0.0)) {*xpix=0.0; *ypix=0.0; return(*status = 502);} /* convert to pixels */ *xpix = dx / xinc + xrefpix; *ypix = dy / yinc + yrefpix; /* find type */ /* WDP 1/97: removed support for default type for better error checking */ /* itype = 0; default type is linear */ itype = -1; /* no default type */ for (i=0;i<9;i++) if (!strncmp(type, ctypes[i], 4)) itype = i; if (itype==0) return(*status); /* done if linear */ /* Non linear position */ ra0 = xref * cond2r; dec0 = yref * cond2r; ra = xpos * cond2r; dec = ypos * cond2r; /* compute direction cosine */ coss = cos (dec); sins = sin (dec); cos0 = cos (dec0); sin0 = sin (dec0); l = sin(ra-ra0) * coss; sint = sins * sin0 + coss * cos0 * cos(ra-ra0); /* process by case */ switch (itype) { case 1: /* -SIN sin*/ if (sint<0.0) return(*status = 501); m = sins * cos(dec0) - coss * sin(dec0) * cos(ra-ra0); break; case 2: /* -TAN tan */ if (sint<=0.0) return(*status = 501); if( cos0<0.001 ) { /* Do a first order expansion around pole */ m = (coss * cos(ra-ra0)) / (sins * sin0); m = (-m + cos0 * (1.0 + m*m)) / sin0; } else { m = ( sins/sint - sin0 ) / cos0; } if( fabs(sin(ra0)) < 0.3 ) { l = coss*sin(ra)/sint - cos0*sin(ra0) + m*sin(ra0)*sin0; l /= cos(ra0); } else { l = coss*cos(ra)/sint - cos0*cos(ra0) + m*cos(ra0)*sin0; l /= -sin(ra0); } break; case 3: /* -ARC Arc*/ m = sins * sin(dec0) + coss * cos(dec0) * cos(ra-ra0); if (m<-1.0) m = -1.0; if (m>1.0) m = 1.0; m = acos (m); if (m!=0) m = m / sin(m); else m = 1.0; l = l * m; m = (sins * cos(dec0) - coss * sin(dec0) * cos(ra-ra0)) * m; break; case 4: /* -NCP North celestial pole*/ if (dec0==0.0) return(*status = 501); /* can't stand the equator */ else m = (cos(dec0) - coss * cos(ra-ra0)) / sin(dec0); break; case 5: /* -GLS global sinusoid */ dt = ra - ra0; if (fabs(dec)>twopi/4.0) return(*status = 501); if (fabs(dec0)>twopi/4.0) return(*status = 501); m = dec - dec0; l = dt * coss; break; case 6: /* -MER mercator*/ dt = yinc * cosr + xinc * sinr; if (dt==0.0) dt = 1.0; dy = (yref/2.0 + 45.0) * cond2r; dx = dy + dt / 2.0 * cond2r; dy = log (tan (dy)); dx = log (tan (dx)); geo2 = dt * cond2r / (dx - dy); geo3 = geo2 * dy; geo1 = cos (yref*cond2r); if (geo1<=0.0) geo1 = 1.0; dt = ra - ra0; l = geo1 * dt; dt = dec / 2.0 + twopi / 8.0; dt = tan (dt); if (dttwopi/4.0) return(*status = 501); dt = yinc*cosr + xinc*sinr; if (dt==0.0) dt = 1.0; dt = dt * cond2r; dy = yref * cond2r; dx = sin(dy+dt)/sqrt((1.0+cos(dy+dt))/2.0) - sin(dy)/sqrt((1.0+cos(dy))/2.0); if (dx==0.0) dx = 1.0; geo2 = dt / dx; dt = xinc*cosr - yinc* sinr; if (dt==0.0) dt = 1.0; dt = dt * cond2r; dx = 2.0 * cos(dy) * sin(dt/2.0); if (dx==0.0) dx = 1.0; geo1 = dt * sqrt((1.0+cos(dy)*cos(dt/2.0))/2.0) / dx; geo3 = geo2 * sin(dy) / sqrt((1.0+cos(dy))/2.0); dt = sqrt ((1.0 + cos(dec) * cos(da))/2.0); if (fabs(dt)twopi/4.0) return(*status = 501); dd = 1.0 + sins * sin(dec0) + coss * cos(dec0) * cos(da); if (fabs(dd) #include #include "fitsio2.h" #if defined(unix) || defined(__unix__) || defined(__unix) #include /* needed in file_openfile */ #ifdef REPLACE_LINKS #include #include #endif #endif #ifdef HAVE_FTRUNCATE #if defined(unix) || defined(__unix__) || defined(__unix) #include /* needed for getcwd prototype on unix machines */ #endif #endif #define IO_SEEK 0 /* last file I/O operation was a seek */ #define IO_READ 1 /* last file I/O operation was a read */ #define IO_WRITE 2 /* last file I/O operation was a write */ static char file_outfile[FLEN_FILENAME]; typedef struct /* structure containing disk file structure */ { FILE *fileptr; LONGLONG currentpos; int last_io_op; } diskdriver; static diskdriver handleTable[NMAXFILES]; /* allocate diskfile handle tables */ /*--------------------------------------------------------------------------*/ int file_init(void) { int ii; for (ii = 0; ii < NMAXFILES; ii++) /* initialize all empty slots in table */ { handleTable[ii].fileptr = 0; } return(0); } /*--------------------------------------------------------------------------*/ int file_setoptions(int options) { /* do something with the options argument, to stop compiler warning */ options = 0; return(options); } /*--------------------------------------------------------------------------*/ int file_getoptions(int *options) { *options = 0; return(0); } /*--------------------------------------------------------------------------*/ int file_getversion(int *version) { *version = 10; return(0); } /*--------------------------------------------------------------------------*/ int file_shutdown(void) { return(0); } /*--------------------------------------------------------------------------*/ int file_open(char *filename, int rwmode, int *handle) { FILE *diskfile; int copyhandle, ii, status; char recbuf[2880]; size_t nread; /* if an output filename has been specified as part of the input file, as in "inputfile.fits(outputfile.fit)" then we have to create the output file, copy the input to it, then reopen the the new copy. */ if (*file_outfile) { /* open the original file, with readonly access */ status = file_openfile(filename, READONLY, &diskfile); if (status) { file_outfile[0] = '\0'; return(status); } /* create the output file */ status = file_create(file_outfile,handle); if (status) { ffpmsg("Unable to create output file for copy of input file:"); ffpmsg(file_outfile); file_outfile[0] = '\0'; return(status); } /* copy the file from input to output */ while(0 != (nread = fread(recbuf,1,2880, diskfile))) { status = file_write(*handle, recbuf, nread); if (status) { file_outfile[0] = '\0'; return(status); } } /* close both files */ fclose(diskfile); copyhandle = *handle; file_close(*handle); *handle = copyhandle; /* reuse the old file handle */ /* reopen the new copy, with correct rwmode */ status = file_openfile(file_outfile, rwmode, &diskfile); file_outfile[0] = '\0'; } else { *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in table */ { if (handleTable[ii].fileptr == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ /*open the file */ status = file_openfile(filename, rwmode, &diskfile); } handleTable[*handle].fileptr = diskfile; handleTable[*handle].currentpos = 0; handleTable[*handle].last_io_op = IO_SEEK; return(status); } /*--------------------------------------------------------------------------*/ int file_openfile(char *filename, int rwmode, FILE **diskfile) /* lowest level routine to physically open a disk file */ { char mode[4]; #if defined(unix) || defined(__unix__) || defined(__unix) char tempname[512], *cptr, user[80]; struct passwd *pwd; int ii = 0; #if defined(REPLACE_LINKS) struct stat stbuf; int success = 0; size_t n; FILE *f1, *f2; char buf[BUFSIZ]; #endif #endif if (rwmode == READWRITE) { strcpy(mode, "r+b"); /* open existing file with read-write */ } else { strcpy(mode, "rb"); /* open existing file readonly */ } #if MACHINE == ALPHAVMS || MACHINE == VAXVMS /* specify VMS record structure: fixed format, 2880 byte records */ /* but force stream mode access to enable random I/O access */ *diskfile = fopen(filename, mode, "rfm=fix", "mrs=2880", "ctx=stm"); #elif defined(unix) || defined(__unix__) || defined(__unix) /* support the ~user/file.fits or ~/file.fits filenames in UNIX */ if (*filename == '~') { if (filename[1] == '/') { cptr = getenv("HOME"); if (cptr) { strcpy(tempname, cptr); strcat(tempname, filename+1); } else { strcpy(tempname, filename); } } else { /* copy user name */ cptr = filename+1; while (*cptr && (*cptr != '/')) { user[ii] = *cptr; cptr++; ii++; } user[ii] = '\0'; /* get structure that includes name of user's home directory */ pwd = getpwnam(user); /* copy user's home directory */ strcpy(tempname, pwd->pw_dir); strcat(tempname, cptr); } *diskfile = fopen(tempname, mode); } else { /* don't need to expand the input file name */ *diskfile = fopen(filename, mode); #if defined(REPLACE_LINKS) if (!(*diskfile) && (rwmode == READWRITE)) { /* failed to open file with READWRITE privilege. Test if */ /* the file we are trying to open is a soft link to a file that */ /* doesn't have write privilege. */ lstat(filename, &stbuf); if ((stbuf.st_mode & S_IFMT) == S_IFLNK) /* is this a soft link? */ { if ((f1 = fopen(filename, "rb")) != 0) /* try opening READONLY */ { strcpy(tempname, filename); strcat(tempname, ".TmxFil"); if ((f2 = fopen(tempname, "wb")) != 0) /* create temp file */ { success = 1; while ((n = fread(buf, 1, BUFSIZ, f1)) > 0) { /* copy linked file to local temporary file */ if (fwrite(buf, 1, n, f2) != n) { success = 0; break; } } fclose(f2); } fclose(f1); if (success) { /* delete link and rename temp file to previous link name */ remove(filename); rename(tempname, filename); /* try once again to open the file with write access */ *diskfile = fopen(filename, mode); } else remove(tempname); /* clean up the failed copy */ } } } #endif } #else /* other non-UNIX machines */ *diskfile = fopen(filename, mode); #endif if (!(*diskfile)) /* couldn't open file */ { return(FILE_NOT_OPENED); } return(0); } /*--------------------------------------------------------------------------*/ int file_create(char *filename, int *handle) { FILE *diskfile; int ii; char mode[4]; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in table */ { if (handleTable[ii].fileptr == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ strcpy(mode, "w+b"); /* create new file with read-write */ diskfile = fopen(filename, "r"); /* does file already exist? */ if (diskfile) { fclose(diskfile); /* close file and exit with error */ return(FILE_NOT_CREATED); } #if MACHINE == ALPHAVMS || MACHINE == VAXVMS /* specify VMS record structure: fixed format, 2880 byte records */ /* but force stream mode access to enable random I/O access */ diskfile = fopen(filename, mode, "rfm=fix", "mrs=2880", "ctx=stm"); #else diskfile = fopen(filename, mode); #endif if (!(diskfile)) /* couldn't create file */ { return(FILE_NOT_CREATED); } handleTable[ii].fileptr = diskfile; handleTable[ii].currentpos = 0; handleTable[ii].last_io_op = IO_SEEK; return(0); } /*--------------------------------------------------------------------------*/ int file_truncate(int handle, LONGLONG filesize) /* truncate the diskfile to a new smaller size */ { #ifdef HAVE_FTRUNCATE int fdesc; fdesc = fileno(handleTable[handle].fileptr); ftruncate(fdesc, (OFF_T) filesize); handleTable[handle].currentpos = filesize; handleTable[handle].last_io_op = IO_WRITE; #endif return(0); } /*--------------------------------------------------------------------------*/ int file_size(int handle, LONGLONG *filesize) /* return the size of the file in bytes */ { OFF_T position1,position2; FILE *diskfile; diskfile = handleTable[handle].fileptr; #if _FILE_OFFSET_BITS - 0 == 64 /* call the newer ftello and fseeko routines , which support */ /* Large Files (> 2GB) if they are supported. */ position1 = ftello(diskfile); /* save current postion */ if (position1 < 0) return(SEEK_ERROR); if (fseeko(diskfile, 0, 2) != 0) /* seek to end of file */ return(SEEK_ERROR); position2 = ftello(diskfile); /* get file size */ if (position2 < 0) return(SEEK_ERROR); if (fseeko(diskfile, position1, 0) != 0) /* seek back to original pos */ return(SEEK_ERROR); #else position1 = ftell(diskfile); /* save current postion */ if (position1 < 0) return(SEEK_ERROR); if (fseek(diskfile, 0, 2) != 0) /* seek to end of file */ return(SEEK_ERROR); position2 = ftell(diskfile); /* get file size */ if (position2 < 0) return(SEEK_ERROR); if (fseek(diskfile, position1, 0) != 0) /* seek back to original pos */ return(SEEK_ERROR); #endif *filesize = (LONGLONG) position2; return(0); } /*--------------------------------------------------------------------------*/ int file_close(int handle) /* close the file */ { if (fclose(handleTable[handle].fileptr) ) return(FILE_NOT_CLOSED); handleTable[handle].fileptr = 0; return(0); } /*--------------------------------------------------------------------------*/ int file_remove(char *filename) /* delete the file from disk */ { remove(filename); return(0); } /*--------------------------------------------------------------------------*/ int file_flush(int handle) /* flush the file */ { if (fflush(handleTable[handle].fileptr) ) return(WRITE_ERROR); /* The flush operation is not supposed to move the internal */ /* file pointer, but it does on some Windows-95 compilers and */ /* perhaps others, so seek to original position to be sure. */ /* This seek will do no harm on other systems. */ #if MACHINE == IBMPC if (file_seek(handle, handleTable[handle].currentpos)) return(SEEK_ERROR); #endif return(0); } /*--------------------------------------------------------------------------*/ int file_seek(int handle, LONGLONG offset) /* seek to position relative to start of the file */ { #if _FILE_OFFSET_BITS - 0 == 64 if (fseeko(handleTable[handle].fileptr, (OFF_T) offset, 0) != 0) return(SEEK_ERROR); #else if (fseek(handleTable[handle].fileptr, (OFF_T) offset, 0) != 0) return(SEEK_ERROR); #endif handleTable[handle].currentpos = offset; return(0); } /*--------------------------------------------------------------------------*/ int file_read(int hdl, void *buffer, long nbytes) /* read bytes from the current position in the file */ { long nread; char *cptr; if (handleTable[hdl].last_io_op == IO_WRITE) { if (file_seek(hdl, handleTable[hdl].currentpos)) return(SEEK_ERROR); } nread = (long) fread(buffer, 1, nbytes, handleTable[hdl].fileptr); if (nread == 1) { cptr = (char *) buffer; /* some editors will add a single end-of-file character to a file */ /* Ignore it if the character is a zero, 10, or 32 */ if (*cptr == 0 || *cptr == 10 || *cptr == 32) return(END_OF_FILE); else return(READ_ERROR); } else if (nread != nbytes) { return(READ_ERROR); } handleTable[hdl].currentpos += nbytes; handleTable[hdl].last_io_op = IO_READ; return(0); } /*--------------------------------------------------------------------------*/ int file_write(int hdl, void *buffer, long nbytes) /* write bytes at the current position in the file */ { if (handleTable[hdl].last_io_op == IO_READ) { if (file_seek(hdl, handleTable[hdl].currentpos)) return(SEEK_ERROR); } if((long) fwrite(buffer, 1, nbytes, handleTable[hdl].fileptr) != nbytes) return(WRITE_ERROR); handleTable[hdl].currentpos += nbytes; handleTable[hdl].last_io_op = IO_WRITE; return(0); } /*--------------------------------------------------------------------------*/ int file_compress_open(char *filename, int rwmode, int *hdl) /* This routine opens the compressed diskfile by creating a new uncompressed file then opening it. The input file name (the name of the compressed file) gets replaced with the name of the uncompressed file, which is initially stored in the global file_outfile string. file_outfile then gets set to a null string. */ { FILE *indiskfile, *outdiskfile; int status, clobber = 0; char *cptr; /* open the compressed disk file */ status = file_openfile(filename, READONLY, &indiskfile); if (status) { ffpmsg("failed to open compressed disk file (file_compress_open)"); ffpmsg(filename); return(status); } /* name of the output uncompressed file is stored in the */ /* global variable called 'file_outfile'. */ cptr = file_outfile; if (*cptr == '!') { /* clobber any existing file with the same name */ clobber = 1; cptr++; remove(cptr); } else { outdiskfile = fopen(file_outfile, "r"); /* does file already exist? */ if (outdiskfile) { ffpmsg("uncompressed file already exists: (file_compress_open)"); ffpmsg(file_outfile); fclose(outdiskfile); /* close file and exit with error */ file_outfile[0] = '\0'; return(FILE_NOT_CREATED); } } outdiskfile = fopen(cptr, "w+b"); /* create new file */ if (!outdiskfile) { ffpmsg("could not create uncompressed file: (file_compress_open)"); ffpmsg(file_outfile); file_outfile[0] = '\0'; return(FILE_NOT_CREATED); } /* uncompress file into another file */ uncompress2file(filename, indiskfile, outdiskfile, &status); fclose(indiskfile); fclose(outdiskfile); if (status) { ffpmsg("error in file_compress_open: failed to uncompressed file:"); ffpmsg(filename); ffpmsg(" into new output file:"); ffpmsg(file_outfile); file_outfile[0] = '\0'; return(status); } strcpy(filename, cptr); /* switch the names */ file_outfile[0] = '\0'; status = file_open(filename, rwmode, hdl); return(status); } /*--------------------------------------------------------------------------*/ int file_is_compressed(char *filename) /* I - FITS file name */ /* Test if the disk file is compressed. Returns 1 if compressed, 0 if not. This may modify the filename string by appending a compression suffex. */ { FILE *diskfile; unsigned char buffer[2]; char tmpfilename[FLEN_FILENAME]; /* Open file. Try various suffix combinations */ if (file_openfile(filename, 0, &diskfile)) { strcpy(tmpfilename,filename); strcat(filename,".gz"); if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,".Z"); if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,".z"); /* it's often lower case on CDROMs */ if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,".zip"); if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,"-z"); /* VMS suffix */ if (file_openfile(filename, 0, &diskfile)) { strcpy(filename, tmpfilename); strcat(filename,"-gz"); /* VMS suffix */ if (file_openfile(filename, 0, &diskfile)) { strcpy(filename,tmpfilename); /* restore original name */ return(0); /* file not found */ } } } } } } } if (fread(buffer, 1, 2, diskfile) != 2) /* read 2 bytes */ { fclose(diskfile); /* error reading file so just return */ return(0); } fclose(diskfile); /* see if the 2 bytes have the magic values for a compressed file */ if ( (memcmp(buffer, "\037\213", 2) == 0) || /* GZIP */ (memcmp(buffer, "\120\113", 2) == 0) || /* PKZIP */ (memcmp(buffer, "\037\036", 2) == 0) || /* PACK */ (memcmp(buffer, "\037\235", 2) == 0) || /* LZW */ (memcmp(buffer, "\037\240", 2) == 0) ) /* LZH */ { return(1); /* this is a compressed file */ } else { return(0); /* not a compressed file */ } } /*--------------------------------------------------------------------------*/ int file_checkfile (char *urltype, char *infile, char *outfile) { /* special case: if file:// driver, check if the file is compressed */ if ( file_is_compressed(infile) ) { /* if output file has been specified, save the name for future use: */ /* This is the name of the uncompressed file to be created on disk. */ if (strlen(outfile)) { if (!strncmp(outfile, "mem:", 4) ) { /* uncompress the file in memory, with READ and WRITE access */ strcpy(urltype, "compressmem://"); /* use special driver */ *file_outfile = '\0'; } else { strcpy(urltype, "compressfile://"); /* use special driver */ /* don't copy the "file://" prefix, if present. */ if (!strncmp(outfile, "file://", 7) ) strcpy(file_outfile,outfile+7); else strcpy(file_outfile,outfile); } } else { /* uncompress the file in memory */ strcpy(urltype, "compress://"); /* use special driver */ *file_outfile = '\0'; /* no output file was specified */ } } else /* an ordinary, uncompressed FITS file on disk */ { /* save the output file name for later use when opening the file. */ /* In this case, the file to be opened will be opened READONLY, */ /* and copied to this newly created output file. The original file */ /* will be closed, and the copy will be opened by CFITSIO for */ /* subsequent processing (possibly with READWRITE access). */ if (strlen(outfile)) strcpy(file_outfile,outfile); } return 0; } indi-0.5/src/cfitsio/eval_tab.h0000644000175000017500000000151210610474402014263 0ustar jrjrtypedef union { int Node; /* Index of Node */ double dbl; /* real value */ long lng; /* integer value */ char log; /* logical value */ char str[256]; /* string value */ } FFSTYPE; #define BOOLEAN 258 #define LONG 259 #define DOUBLE 260 #define STRING 261 #define BITSTR 262 #define FUNCTION 263 #define BFUNCTION 264 #define GTIFILTER 265 #define REGFILTER 266 #define COLUMN 267 #define BCOLUMN 268 #define SCOLUMN 269 #define BITCOL 270 #define ROWREF 271 #define NULLREF 272 #define SNULLREF 273 #define OR 274 #define AND 275 #define EQ 276 #define NE 277 #define GT 278 #define LT 279 #define LTE 280 #define GTE 281 #define POWER 282 #define NOT 283 #define INTCAST 284 #define FLTCAST 285 #define UMINUS 286 #define ACCUM 287 #define DIFF 288 extern FFSTYPE fflval; indi-0.5/src/cfitsio/putcole.c0000644000175000017500000011254710610474375014200 0ustar jrjr/* This file, putcole.c, contains routines that write data elements to */ /* a FITS image or table, with float datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppre( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine cannot be called directly by users to write to large arrays with > 2**31 pixels (although CFITSIO can do so by passing the firstelem thru a LONGLONG sized global variable) */ { long row; float nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TFLOAT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcle(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppne( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values that are written */ float nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. This routine cannot be called directly by users to write to large arrays with > 2**31 pixels (although CFITSIO can do so by passing the firstelem thru a LONGLONG sized global variable) */ { long row; float nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TFLOAT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcne(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2de(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ float *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine does not support writing to large images with more than 2**31 pixels. */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3de(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3de(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ float *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine does not support writing to large images with more than 2**31 pixels. */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TFLOAT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcle(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcle(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpsse(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ float *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TFLOAT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcle(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpe( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ float *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcle(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcle( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise, we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TFLOAT) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TFLOAT): if (writeraw) { /* write raw input bytes without conversion */ ffpr4b(fptr, ntodo, incre, &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffr4fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); } break; case (TLONGLONG): ffr4fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffr4fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffr4fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONG): ffr4fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TDOUBLE): ffr4fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffr4fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpcle).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpclc( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of complex values to a column in the current FITS HDU. Each complex number if interpreted as a pair of float values. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column if necessary, but normally complex values should only be written to a binary table with TFORMn = 'rC' where r is an optional repeat count. The TSCALn and TZERO keywords should not be used with complex numbers because mathmatically the scaling should only be applied to the real (first) component of the complex value. */ { /* simply multiply the number of elements by 2, and call ffpcle */ ffpcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcne( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ float *array, /* I - array of values to write */ float nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ if (abs(tcode) >= TCOMPLEX) { /* treat complex columns as pairs of numbers */ repeat *= 2; } /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcle(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ /* call ffpcluc, not ffpclu, in case we are writing to a complex ('C') binary table column */ if (ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcle(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcle(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fi1(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fi2(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fi4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = (INT32BIT) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fi8(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (long) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fr4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo * sizeof(float) ); /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fr8(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffr4fstr(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } indi-0.5/src/cfitsio/cfileio.c0000644000175000017500000063422210610474374014135 0ustar jrjr/* This file, cfileio.c, contains the low-level file access routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include #include /* apparently needed to define size_t */ #include "fitsio2.h" #include "group.h" #define MAX_PREFIX_LEN 20 /* max length of file type prefix (e.g. 'http://') */ #define MAX_DRIVERS 23 /* max number of file I/O drivers */ typedef struct /* structure containing pointers to I/O driver functions */ { char prefix[MAX_PREFIX_LEN]; int (*init)(void); int (*shutdown)(void); int (*setoptions)(int option); int (*getoptions)(int *options); int (*getversion)(int *version); int (*checkfile)(char *urltype, char *infile, char *outfile); int (*open)(char *filename, int rwmode, int *driverhandle); int (*create)(char *filename, int *drivehandle); int (*truncate)(int drivehandle, LONGLONG size); int (*close)(int drivehandle); int (*remove)(char *filename); int (*size)(int drivehandle, LONGLONG *size); int (*flush)(int drivehandle); int (*seek)(int drivehandle, LONGLONG offset); int (*read)(int drivehandle, void *buffer, long nbytes); int (*write)(int drivehandle, void *buffer, long nbytes); } fitsdriver; fitsdriver driverTable[MAX_DRIVERS]; /* allocate driver tables */ FITSfile *FptrTable[NMAXFILES]; /* this table of Fptr pointers is */ /* used by fits_already_open */ int need_to_initialize = 1; /* true if CFITSIO has not been initialized */ int no_of_drivers = 0; /* number of currently defined I/O drivers */ static int pixel_filter_helper(fitsfile **fptr, char *outfile, char *expr, int *status); /*--------------------------------------------------------------------------*/ int ffomem(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ void **buffptr, /* I - address of memory pointer */ size_t *buffsize, /* I - size of buffer, in bytes */ size_t deltasize, /* I - increment for future realloc's */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ int *status) /* IO - error status */ /* Open an existing FITS file in core memory. This is a specialized version of ffopen. */ { int driver, handle, hdutyp, slen, movetotype, extvers, extnum; char extname[FLEN_VALUE]; LONGLONG filesize; char urltype[MAX_PREFIX_LEN], infile[FLEN_FILENAME], outfile[FLEN_FILENAME]; char extspec[FLEN_FILENAME], rowfilter[FLEN_FILENAME]; char binspec[FLEN_FILENAME], colspec[FLEN_FILENAME]; char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME]; char *url, errmsg[FLEN_ERRMSG]; char *hdtype[3] = {"IMAGE", "TABLE", "BINTABLE"}; if (*status > 0) return(*status); *fptr = 0; /* initialize null file pointer */ if (need_to_initialize) /* this is called only once */ { if (need_to_initialize != 1) { /* This is bad. looks like memory has been corrupted. */ ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!"); ffpmsg("Fatal condition detected in ffomem."); *status = FILE_NOT_OPENED; return(*status); } *status = fits_init_cfitsio(); if (*status > 0) return(*status); } url = (char *) name; while (*url == ' ') /* ignore leading spaces in the file spec */ url++; /* parse the input file specification */ ffiurl(url, urltype, infile, outfile, extspec, rowfilter, binspec, colspec, status); strcpy(urltype, "memkeep://"); /* URL type for pre-existing memory file */ *status = urltype2driver(urltype, &driver); if (*status > 0) { ffpmsg("could not find driver for pre-existing memory file: (ffomem)"); return(*status); } /* call driver routine to open the memory file */ *status = mem_openmem( buffptr, buffsize,deltasize, mem_realloc, &handle); if (*status > 0) { ffpmsg("failed to open pre-existing memory file: (ffomem)"); return(*status); } /* get initial file size */ *status = (*driverTable[driver].size)(handle, &filesize); if (*status > 0) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed get the size of the memory file: (ffomem)"); return(*status); } /* allocate fitsfile structure and initialize = 0 */ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffomem)"); ffpmsg(url); return(*status = MEMORY_ALLOCATION); } /* allocate FITSfile structure and initialize = 0 */ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile)); if (!((*fptr)->Fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffomem)"); ffpmsg(url); free(*fptr); *fptr = 0; return(*status = MEMORY_ALLOCATION); } slen = strlen(url) + 1; slen = maxvalue(slen, 32); /* reserve at least 32 chars */ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */ if ( !(((*fptr)->Fptr)->filename) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for filename: (ffomem)"); ffpmsg(url); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* mem for headstart array */ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG)); if ( !(((*fptr)->Fptr)->headstart) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for headstart array: (ffomem)"); ffpmsg(url); free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* store the parameters describing the file */ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */ ((*fptr)->Fptr)->filehandle = handle; /* file handle */ ((*fptr)->Fptr)->driver = driver; /* driver number */ strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */ ((*fptr)->Fptr)->filesize = filesize; /* physical file size */ ((*fptr)->Fptr)->logfilesize = filesize; /* logical file size */ ((*fptr)->Fptr)->writemode = mode; /* read-write mode */ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */ ffldrc(*fptr, 0, REPORT_EOF, status); /* load first record */ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */ if (ffrhdu(*fptr, &hdutyp, status) > 0) /* determine HDU structure */ { ffpmsg( "ffomem could not interpret primary array header of file: (ffomem)"); ffpmsg(url); if (*status == UNKNOWN_REC) ffpmsg("This does not look like a FITS file."); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ } /* ---------------------------------------------------------- */ /* move to desired extension, if specified as part of the URL */ /* ---------------------------------------------------------- */ imagecolname[0] = '\0'; rowexpress[0] = '\0'; if (*extspec) { /* parse the extension specifier into individual parameters */ ffexts(extspec, &extnum, extname, &extvers, &movetotype, imagecolname, rowexpress, status); if (*status > 0) return(*status); if (extnum) { ffmahd(*fptr, extnum + 1, &hdutyp, status); } else if (*extname) /* move to named extension, if specified */ { ffmnhd(*fptr, movetotype, extname, extvers, status); } if (*status > 0) { ffpmsg("ffomem could not move to the specified extension:"); if (extnum > 0) { sprintf(errmsg, " extension number %d doesn't exist or couldn't be opened.",extnum); ffpmsg(errmsg); } else { sprintf(errmsg, " extension with EXTNAME = %s,", extname); ffpmsg(errmsg); if (extvers) { sprintf(errmsg, " and with EXTVERS = %d,", extvers); ffpmsg(errmsg); } if (movetotype != ANY_HDU) { sprintf(errmsg, " and with XTENSION = %s,", hdtype[movetotype]); ffpmsg(errmsg); } ffpmsg(" doesn't exist or couldn't be opened."); } return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffdkopn(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file on magnetic disk with either readonly or read/write access. The routine does not support CFITSIO's extended filename syntax and simply uses the entire input 'name' string as the name of the file. */ { if (*status > 0) return(*status); *status = OPEN_DISK_FILE; ffopen(fptr, name, mode, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffdopn(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. and move to the first HDU that contains 'interesting' data, if the primary array contains a null image (i.e., NAXIS = 0). */ { if (*status > 0) return(*status); *status = SKIP_NULL_PRIMARY; ffopen(fptr, name, mode, status); return(*status); } /*--------------------------------------------------------------------------*/ int fftopn(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. and move to the first HDU that contains 'interesting' table (not an image). */ { int hdutype; if (*status > 0) return(*status); *status = SKIP_IMAGE; ffopen(fptr, name, mode, status); if (ffghdt(*fptr, &hdutype, status) <= 0) { if (hdutype == IMAGE_HDU) *status = NOT_TABLE; } return(*status); } /*--------------------------------------------------------------------------*/ int ffiopn(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. and move to the first HDU that contains 'interesting' image (not an table). */ { int hdutype; if (*status > 0) return(*status); *status = SKIP_TABLE; ffopen(fptr, name, mode, status); if (ffghdt(*fptr, &hdutype, status) <= 0) { if (hdutype != IMAGE_HDU) *status = NOT_IMAGE; } return(*status); } /*--------------------------------------------------------------------------*/ int ffopentest(double version, /* I - CFITSIO version number, from the */ /* application program (fitsio.h file) */ fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. First test that the version of fitsio.h used to build the CFITSIO library is the same as the version used in building the application program that links to the library. */ { if (version != CFITSIO_VERSION) { printf("ERROR: Mismatch in the version of the fitsio.h include file used to build\n"); printf("the CFITSIO library, and the version included by the application program:\n"); printf(" Version used to build the CFITSIO library = %f\n",CFITSIO_VERSION); printf(" Version included by the application program = %f\n",version); return(FILE_NOT_OPENED); } /* now call the normal file open routine */ ffopen(fptr, name, mode, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffopen(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - full name of file to open */ int mode, /* I - 0 = open readonly; 1 = read/write */ int *status) /* IO - error status */ /* Open an existing FITS file with either readonly or read/write access. */ { fitsfile *newptr; int driver, hdutyp, hdunum, slen, writecopy, isopen; LONGLONG filesize; long rownum, nrows, goodrows; int extnum, extvers, handle, movetotype, tstatus = 0; char urltype[MAX_PREFIX_LEN], infile[FLEN_FILENAME], outfile[FLEN_FILENAME]; char origurltype[MAX_PREFIX_LEN], extspec[FLEN_FILENAME]; char extname[FLEN_VALUE], rowfilter[FLEN_FILENAME], tblname[FLEN_VALUE]; char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME]; char binspec[FLEN_FILENAME], colspec[FLEN_FILENAME], pixfilter[FLEN_FILENAME]; char histfilename[FLEN_FILENAME]; char filtfilename[FLEN_FILENAME]; char wtcol[FLEN_VALUE]; char minname[4][FLEN_VALUE], maxname[4][FLEN_VALUE]; char binname[4][FLEN_VALUE]; char *url; double minin[4], maxin[4], binsizein[4], weight; int imagetype, naxis = 1, haxis, recip; int skip_null = 0, skip_image = 0, skip_table = 0, open_disk_file = 0; char colname[4][FLEN_VALUE]; char errmsg[FLEN_ERRMSG]; char *hdtype[3] = {"IMAGE", "TABLE", "BINTABLE"}; char *rowselect = 0; if (*status > 0) return(*status); if (*status == SKIP_NULL_PRIMARY) { /* this special status value is used as a flag by ffdopn to tell */ /* ffopen to skip over a null primary array when opening the file. */ skip_null = 1; *status = 0; } else if (*status == SKIP_IMAGE) { /* this special status value is used as a flag by fftopn to tell */ /* ffopen to move to 1st significant table when opening the file. */ skip_image = 1; *status = 0; } else if (*status == SKIP_TABLE) { /* this special status value is used as a flag by ffiopn to tell */ /* ffopen to move to 1st significant image when opening the file. */ skip_table = 1; *status = 0; } else if (*status == OPEN_DISK_FILE) { /* this special status value is used as a flag by ffdkopn to tell */ /* ffopen to not interpret the input filename using CFITSIO's */ /* extended filename syntax, and simply open the specified disk file */ open_disk_file = 1; *status = 0; } *fptr = 0; /* initialize null file pointer */ writecopy = 0; /* have we made a write-able copy of the input file? */ if (need_to_initialize) { /* this is called only once */ if (need_to_initialize != 1) { /* This is bad. looks like memory has been corrupted. */ ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!"); ffpmsg("Fatal condition detected in ffopen."); *status = FILE_NOT_OPENED; return(*status); } *status = fits_init_cfitsio(); } if (*status > 0) return(*status); url = (char *) name; while (*url == ' ') /* ignore leading spaces in the filename */ url++; if (*url == '\0') { ffpmsg("Name of file to open is blank. (ffopen)"); return(*status = FILE_NOT_OPENED); } if (open_disk_file) { /* treat the input URL literally as the name of the file to open */ /* and don't try to parse the URL using the extended filename syntax */ strcpy(infile,url); strcpy(urltype, "file://"); outfile[0] = '\0'; extspec[0] = '\0'; binspec[0] = '\0'; colspec[0] = '\0'; rowfilter[0] = '\0'; pixfilter[0] = '\0'; } else { /* parse the input file specification */ fits_parse_input_filename(url, urltype, infile, outfile, extspec, rowfilter, binspec, colspec, pixfilter, status); } if (*status > 0) { ffpmsg("could not parse the input filename: (ffopen)"); ffpmsg(url); return(*status); } imagecolname[0] = '\0'; rowexpress[0] = '\0'; if (*extspec) { /* parse the extension specifier into individual parameters */ ffexts(extspec, &extnum, extname, &extvers, &movetotype, imagecolname, rowexpress, status); if (*status > 0) return(*status); } /*-------------------------------------------------------------------*/ /* special cases: */ /*-------------------------------------------------------------------*/ histfilename[0] = '\0'; filtfilename[0] = '\0'; if (*outfile && (*binspec || *imagecolname || *pixfilter)) { /* if binspec or imagecolumn are specified, then the */ /* output file name is intended for the final image, */ /* and not a copy of the input file. */ strcpy(histfilename, outfile); outfile[0] = '\0'; } else if (*outfile && (*rowfilter || *colspec)) { /* if rowfilter or colspece are specified, then the */ /* output file name is intended for the filtered file */ /* and not a copy of the input file. */ strcpy(filtfilename, outfile); outfile[0] = '\0'; } /*-------------------------------------------------------------------*/ /* check if this same file is already open, and if so, attach to it */ /*-------------------------------------------------------------------*/ if (fits_already_open(fptr, url, urltype, infile, extspec, rowfilter, binspec, colspec, mode, &isopen, status) > 0) { return(*status); } if (isopen) goto move2hdu; /* get the driver number corresponding to this urltype */ *status = urltype2driver(urltype, &driver); if (*status > 0) { ffpmsg("could not find driver for this file: (ffopen)"); ffpmsg(urltype); ffpmsg(url); return(*status); } /*------------------------------------------------------------------- deal with all those messy special cases which may require that a different driver be used: - is disk file compressed? - are ftp:, gsiftp:, or http: files compressed? - has user requested that a local copy be made of the ftp or http file? -------------------------------------------------------------------*/ if (driverTable[driver].checkfile) { strcpy(origurltype,urltype); /* Save the urltype */ /* 'checkfile' may modify the urltype, infile and outfile strings */ *status = (*driverTable[driver].checkfile)(urltype, infile, outfile); if (*status) { ffpmsg("checkfile failed for this file: (ffopen)"); ffpmsg(url); return(*status); } if (strcmp(origurltype, urltype)) /* did driver changed on us? */ { *status = urltype2driver(urltype, &driver); if (*status > 0) { ffpmsg("could not change driver for this file: (ffopen)"); ffpmsg(url); ffpmsg(urltype); return(*status); } } } /* call appropriate driver to open the file */ if (driverTable[driver].open) { *status = (*driverTable[driver].open)(infile, mode, &handle); if (*status > 0) { ffpmsg("failed to find or open the following file: (ffopen)"); ffpmsg(url); return(*status); } } else { ffpmsg("cannot open an existing file of this type: (ffopen)"); ffpmsg(url); return(*status = FILE_NOT_OPENED); } /* get initial file size */ *status = (*driverTable[driver].size)(handle, &filesize); if (*status > 0) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed get the size of the following file: (ffopen)"); ffpmsg(url); return(*status); } /* allocate fitsfile structure and initialize = 0 */ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffopen)"); ffpmsg(url); return(*status = MEMORY_ALLOCATION); } /* allocate FITSfile structure and initialize = 0 */ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile)); if (!((*fptr)->Fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffopen)"); ffpmsg(url); free(*fptr); *fptr = 0; return(*status = MEMORY_ALLOCATION); } slen = strlen(url) + 1; slen = maxvalue(slen, 32); /* reserve at least 32 chars */ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */ if ( !(((*fptr)->Fptr)->filename) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for filename: (ffopen)"); ffpmsg(url); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* mem for headstart array */ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG)); if ( !(((*fptr)->Fptr)->headstart) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for headstart array: (ffopen)"); ffpmsg(url); free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* store the parameters describing the file */ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */ ((*fptr)->Fptr)->filehandle = handle; /* file handle */ ((*fptr)->Fptr)->driver = driver; /* driver number */ strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */ ((*fptr)->Fptr)->filesize = filesize; /* physical file size */ ((*fptr)->Fptr)->logfilesize = filesize; /* logical file size */ ((*fptr)->Fptr)->writemode = mode; /* read-write mode */ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */ ffldrc(*fptr, 0, REPORT_EOF, status); /* load first record */ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */ if (ffrhdu(*fptr, &hdutyp, status) > 0) /* determine HDU structure */ { ffpmsg( "ffopen could not interpret primary array header of file: "); ffpmsg(url); if (*status == UNKNOWN_REC) ffpmsg("This does not look like a FITS file."); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* ------------------------------------------------------------- */ /* At this point, the input file has been opened. If outfile was */ /* specified, then we have opened a copy of the file, not the */ /* original file so it is safe to modify it if necessary */ /* ------------------------------------------------------------- */ if (*outfile) writecopy = 1; move2hdu: /* ---------------------------------------------------------- */ /* move to desired extension, if specified as part of the URL */ /* ---------------------------------------------------------- */ if (*extspec) { if (extnum) /* extension number was specified */ { ffmahd(*fptr, extnum + 1, &hdutyp, status); } else if (*extname) /* move to named extension, if specified */ { ffmnhd(*fptr, movetotype, extname, extvers, status); } if (*status > 0) /* clean up after error */ { ffpmsg("ffopen could not move to the specified extension:"); if (extnum > 0) { sprintf(errmsg, " extension number %d doesn't exist or couldn't be opened.",extnum); ffpmsg(errmsg); } else { sprintf(errmsg, " extension with EXTNAME = %s,", extname); ffpmsg(errmsg); if (extvers) { sprintf(errmsg, " and with EXTVERS = %d,", extvers); ffpmsg(errmsg); } if (movetotype != ANY_HDU) { sprintf(errmsg, " and with XTENSION = %s,", hdtype[movetotype]); ffpmsg(errmsg); } ffpmsg(" doesn't exist or couldn't be opened."); } ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } } else if (skip_null || skip_image || skip_table || (*imagecolname || *colspec || *rowfilter || *binspec)) { /* ------------------------------------------------------------------ If no explicit extension specifier is given as part of the file name, and, if a) skip_null is true (set if ffopen is called by ffdopn) or b) skip_image or skip_table is true (set if ffopen is called by fftopn or ffdopn) or c) other file filters are specified, then CFITSIO will attempt to move to the first 'interesting' HDU after opening an existing FITS file (or to first interesting table HDU if skip_image is true); An 'interesting' HDU is defined to be either an image with NAXIS > 0 (i.e., not a null array) or a table which has an EXTNAME value which does not contain any of the following strings: 'GTI' - Good Time Interval extension 'OBSTABLE' - used in Beppo SAX data files The main purpose for this is to allow CFITSIO to skip over a null primary and other non-interesting HDUs when opening an existing file, and move directly to the first extension that contains significant data. ------------------------------------------------------------------ */ fits_get_hdu_num(*fptr, &hdunum); if (hdunum == 1) { fits_get_img_dim(*fptr, &naxis, status); if (naxis == 0 || skip_image) /* skip primary array */ { while(1) { /* see if the next HDU is 'interesting' */ if (fits_movrel_hdu(*fptr, 1, &hdutyp, status)) { if (*status == END_OF_FILE) *status = 0; /* reset expected error */ /* didn't find an interesting HDU so move back to beginning */ fits_movabs_hdu(*fptr, 1, &hdutyp, status); break; } if (hdutyp == IMAGE_HDU && skip_image) { continue; /* skip images */ } else if (hdutyp != IMAGE_HDU && skip_table) { continue; /* skip tables */ } else if (hdutyp == IMAGE_HDU) { fits_get_img_dim(*fptr, &naxis, status); if (naxis > 0) break; /* found a non-null image */ } else { tstatus = 0; tblname[0] = '\0'; fits_read_key(*fptr, TSTRING, "EXTNAME", tblname, NULL,&tstatus); if ( (!strstr(tblname, "GTI") && !strstr(tblname, "gti")) && strncasecmp(tblname, "OBSTABLE", 8) ) break; /* found an interesting table */ } } /* end while */ } } /* end if (hdunum==1) */ } if (*imagecolname) { /* ----------------------------------------------------------------- */ /* we need to open an image contained in a single table cell */ /* First, determine which row of the table to use. */ /* ----------------------------------------------------------------- */ if (isdigit((int) *rowexpress)) /* is the row specification a number? */ { sscanf(rowexpress, "%ld", &rownum); if (rownum < 1) { ffpmsg("illegal rownum for image cell:"); ffpmsg(rowexpress); ffpmsg("Could not open the following image in a table cell:"); ffpmsg(extspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status = BAD_ROW_NUM); } } else if (fits_find_first_row(*fptr, rowexpress, &rownum, status) > 0) { ffpmsg("Failed to find row matching this expression:"); ffpmsg(rowexpress); ffpmsg("Could not open the following image in a table cell:"); ffpmsg(extspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } if (rownum == 0) { ffpmsg("row statisfying this expression doesn't exist::"); ffpmsg(rowexpress); ffpmsg("Could not open the following image in a table cell:"); ffpmsg(extspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status = BAD_ROW_NUM); } /* determine the name of the new file to contain copy of the image */ if (*histfilename && !(*pixfilter) ) strcpy(outfile, histfilename); /* the original outfile name */ else strcpy(outfile, "mem://_1"); /* create image file in memory */ /* Copy the image into new primary array and open it as the current */ /* fptr. This will close the table that contains the original image. */ /* create new empty file to hold copy of the image */ if (ffinit(&newptr, outfile, status) > 0) { ffpmsg("failed to create file for copy of image in table cell:"); ffpmsg(outfile); return(*status); } if (fits_copy_cell2image(*fptr, newptr, imagecolname, rownum, status) > 0) { ffpmsg("Failed to copy table cell to new primary array:"); ffpmsg(extspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* close the original file and set fptr to the new image */ ffclos(*fptr, status); *fptr = newptr; /* reset the pointer to the new table */ writecopy = 1; /* we are now dealing with a copy of the original file */ /* add some HISTORY; fits_copy_image_cell also wrote HISTORY keywords */ /* disable this; leave it up to calling routine to write any HISTORY keywords if (*extname) sprintf(card,"HISTORY in HDU '%.16s' of file '%.36s'",extname,infile); else sprintf(card,"HISTORY in HDU %d of file '%.45s'", extnum, infile); ffprec(*fptr, card, status); */ } /* --------------------------------------------------------------------- */ /* edit columns (and/or keywords) in the table, if specified in the URL */ /* --------------------------------------------------------------------- */ if (*colspec) { /* the column specifier will modify the file, so make sure */ /* we are already dealing with a copy, or else make a new copy */ if (!writecopy) /* Is the current file already a copy? */ writecopy = fits_is_this_a_copy(urltype); if (!writecopy) { if (*filtfilename && *outfile == '\0') strcpy(outfile, filtfilename); /* the original outfile name */ else strcpy(outfile, "mem://_1"); /* will create copy in memory */ writecopy = 1; } else { ((*fptr)->Fptr)->writemode = READWRITE; /* we have write access */ outfile[0] = '\0'; } if (ffedit_columns(fptr, outfile, colspec, status) > 0) { ffpmsg("editing columns in input table failed (ffopen)"); ffpmsg(" while trying to perform the following operation:"); ffpmsg(colspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } } /* ------------------------------------------------------------------- */ /* select rows from the table, if specified in the URL */ /* or select a subimage (if this is an image HDU and not a table) */ /* ------------------------------------------------------------------- */ if (*rowfilter) { fits_get_hdu_type(*fptr, &hdutyp, status); /* get type of HDU */ if (hdutyp == IMAGE_HDU) { /* this is an image so 'rowfilter' is an image section specification */ if (*filtfilename && *outfile == '\0') strcpy(outfile, filtfilename); /* the original outfile name */ else if (*outfile == '\0') /* output file name not already defined? */ strcpy(outfile, "mem://_2"); /* will create file in memory */ /* create new file containing the image section, plus a copy of */ /* any other HDUs that exist in the input file. This routine */ /* will close the original image file and return a pointer */ /* to the new file. */ if (fits_select_image_section(fptr, outfile, rowfilter, status) > 0) { ffpmsg("on-the-fly selection of image section failed (ffopen)"); ffpmsg(" while trying to use the following section filter:"); ffpmsg(rowfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } writecopy = 1; } else { /* this is a table HDU, so the rowfilter is really a row filter */ if (*binspec) { /* since we are going to make a histogram of the selected rows, */ /* it would be a waste of time and memory to make a whole copy of */ /* the selected rows. Instead, just construct an array of TRUE */ /* or FALSE values that indicate which rows are to be included */ /* in the histogram and pass that to the histogram generating */ /* routine */ fits_get_num_rows(*fptr, &nrows, status); /* get no. of rows */ rowselect = (char *) calloc(nrows, 1); if (!rowselect) { ffpmsg( "failed to allocate memory for selected columns array (ffopen)"); ffpmsg(" while trying to select rows with the following filter:"); ffpmsg(rowfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } if (fits_find_rows(*fptr, rowfilter, 1L, nrows, &goodrows, rowselect, status) > 0) { ffpmsg("selection of rows in input table failed (ffopen)"); ffpmsg(" while trying to select rows with the following filter:"); ffpmsg(rowfilter); free(rowselect); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } } else { if (!writecopy) /* Is the current file already a copy? */ writecopy = fits_is_this_a_copy(urltype); if (!writecopy) { if (*filtfilename && *outfile == '\0') strcpy(outfile, filtfilename); /* the original outfile name */ else if (*outfile == '\0') /* output filename not already defined? */ strcpy(outfile, "mem://_2"); /* will create copy in memory */ } else { ((*fptr)->Fptr)->writemode = READWRITE; /* we have write access */ outfile[0] = '\0'; } /* select rows in the table. If a copy of the input file has */ /* not already been made, then this routine will make a copy */ /* and then close the input file, so that the modifications will */ /* only be made on the copy, not the original */ if (ffselect_table(fptr, outfile, rowfilter, status) > 0) { ffpmsg("on-the-fly selection of rows in input table failed (ffopen)"); ffpmsg(" while trying to select rows with the following filter:"); ffpmsg(rowfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* write history records */ ffphis(*fptr, "CFITSIO used the following filtering expression to create this table:", status); ffphis(*fptr, name, status); } /* end of no binspec case */ } /* end of table HDU case */ } /* end of rowfilter exists case */ /* ------------------------------------------------------------------- */ /* make an image histogram by binning columns, if specified in the URL */ /* ------------------------------------------------------------------- */ if (*binspec) { if (*histfilename && !(*pixfilter) ) strcpy(outfile, histfilename); /* the original outfile name */ else strcpy(outfile, "mem://_3"); /* create histogram in memory */ /* if not already copied the file */ /* parse the binning specifier into individual parameters */ ffbins(binspec, &imagetype, &haxis, colname, minin, maxin, binsizein, minname, maxname, binname, &weight, wtcol, &recip, status); /* Create the histogram primary array and open it as the current fptr */ /* This will close the table that was used to create the histogram. */ ffhist(fptr, outfile, imagetype, haxis, colname, minin, maxin, binsizein, minname, maxname, binname, weight, wtcol, recip, rowselect, status); if (rowselect) free(rowselect); if (*status > 0) { ffpmsg("on-the-fly histogramming of input table failed (ffopen)"); ffpmsg(" while trying to execute the following histogram specification:"); ffpmsg(binspec); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* write history records */ ffphis(*fptr, "CFITSIO used the following expression to create this histogram:", status); ffphis(*fptr, name, status); } if (*pixfilter) { if (*histfilename) strcpy(outfile, histfilename); /* the original outfile name */ else strcpy(outfile, "mem://_4"); /* create in memory */ /* if not already copied the file */ /* Ensure type of HDU is consistent with pixel filtering */ fits_get_hdu_type(*fptr, &hdutyp, status); /* get type of HDU */ if (hdutyp == IMAGE_HDU) { pixel_filter_helper(fptr, outfile, pixfilter, status); if (*status > 0) { ffpmsg("pixel filtering of input image failed (ffopen)"); ffpmsg(" while trying to execute the following:"); ffpmsg(pixfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ return(*status); } /* write history records */ ffphis(*fptr, "CFITSIO used the following expression to create this image:", status); ffphis(*fptr, name, status); return *status; } else { ffpmsg("cannot use pixel filter on non-IMAGE HDU"); ffpmsg(pixfilter); ffclos(*fptr, status); *fptr = 0; /* return null file pointer */ *status = NOT_IMAGE; return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffreopen(fitsfile *openfptr, /* I - FITS file pointer to open file */ fitsfile **newfptr, /* O - pointer to new re opened file */ int *status) /* IO - error status */ /* Reopen an existing FITS file with either readonly or read/write access. The reopened file shares the same FITSfile structure but may point to a different HDU within the file. */ { if (*status > 0) return(*status); /* check that the open file pointer is valid */ if (!openfptr) return(*status = NULL_INPUT_PTR); else if ((openfptr->Fptr)->validcode != VALIDSTRUC) /* check magic value */ return(*status = BAD_FILEPTR); /* allocate fitsfile structure and initialize = 0 */ *newfptr = (fitsfile *) calloc(1, sizeof(fitsfile)); (*newfptr)->Fptr = openfptr->Fptr; /* both point to the same structure */ (*newfptr)->HDUposition = 0; /* set initial position to primary array */ (((*newfptr)->Fptr)->open_count)++; /* increment the file usage counter */ return(*status); } /*--------------------------------------------------------------------------*/ int fits_store_Fptr(FITSfile *Fptr, /* O - FITS file pointer */ int *status) /* IO - error status */ /* store the new Fptr address for future use by fits_already_open */ { int ii; if (*status > 0) return(*status); for (ii = 0; ii < NMAXFILES; ii++) { if (FptrTable[ii] == 0) { FptrTable[ii] = Fptr; break; } } return(*status); } /*--------------------------------------------------------------------------*/ int fits_clear_Fptr(FITSfile *Fptr, /* O - FITS file pointer */ int *status) /* IO - error status */ /* clear the Fptr address from the Fptr Table */ { int ii; for (ii = 0; ii < NMAXFILES; ii++) { if (FptrTable[ii] == Fptr) { FptrTable[ii] = 0; break; } } return(*status); } /*--------------------------------------------------------------------------*/ int fits_already_open(fitsfile **fptr, /* I/O - FITS file pointer */ char *url, char *urltype, char *infile, char *extspec, char *rowfilter, char *binspec, char *colspec, int mode, /* I - 0 = open readonly; 1 = read/write */ int *isopen, /* O - 1 = file is already open */ int *status) /* IO - error status */ /* Check if the file to be opened is already open. If so, then attach to it. */ /* this function was changed so that for files of access method FILE:// the file paths are compared using standard URL syntax and absolute paths (as opposed to relative paths). This eliminates some instances where a file is already opened but it is not realized because it was opened with another file path. For instance, if the CWD is /a/b/c and I open /a/b/c/foo.fits then open ./foo.fits the previous version of this function would not have reconized that the two files were the same. This version does recognize that the two files are the same. */ { FITSfile *oldFptr; int ii; char oldurltype[MAX_PREFIX_LEN], oldinfile[FLEN_FILENAME]; char oldextspec[FLEN_FILENAME], oldoutfile[FLEN_FILENAME]; char oldrowfilter[FLEN_FILENAME]; char oldbinspec[FLEN_FILENAME], oldcolspec[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char tmpStr[FLEN_FILENAME]; char tmpinfile[FLEN_FILENAME]; *isopen = 0; if(strcasecmp(urltype,"FILE://") == 0) { fits_path2url(infile,tmpinfile,status); if(tmpinfile[0] != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,tmpinfile); fits_clean_url(cwd,tmpinfile,status); } } else strcpy(tmpinfile,infile); for (ii = 0; ii < NMAXFILES; ii++) /* check every buffer */ { if (FptrTable[ii] != 0) { oldFptr = FptrTable[ii]; ffiurl(oldFptr->filename, oldurltype, oldinfile, oldoutfile, oldextspec, oldrowfilter, oldbinspec, oldcolspec, status); if (*status > 0) { ffpmsg("could not parse the previously opened filename: (ffopen)"); ffpmsg(oldFptr->filename); return(*status); } if(strcasecmp(oldurltype,"FILE://") == 0) { fits_path2url(oldinfile,tmpStr,status); if(tmpStr[0] != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,tmpStr); fits_clean_url(cwd,tmpStr,status); } strcpy(oldinfile,tmpStr); } if (!strcmp(urltype, oldurltype) && !strcmp(tmpinfile, oldinfile) ) { /* identical type of file and root file name */ if ( (!rowfilter[0] && !oldrowfilter[0] && !binspec[0] && !oldbinspec[0] && !colspec[0] && !oldcolspec[0]) /* no filtering or binning specs for either file, so */ /* this is a case where the same file is being reopened. */ /* It doesn't matter if the extensions are different */ || /* or */ (!strcmp(rowfilter, oldrowfilter) && !strcmp(binspec, oldbinspec) && !strcmp(colspec, oldcolspec) && !strcmp(extspec, oldextspec) ) ) /* filtering specs are given and are identical, and */ /* the same extension is specified */ { if (mode == READWRITE && oldFptr->writemode == READONLY) { /* cannot assume that a file previously opened with READONLY can now be written to (e.g., files on CDROM, or over the the network, or STDIN), so return with an error. */ ffpmsg( "cannot reopen file READWRITE when previously opened READONLY"); ffpmsg(url); return(*status = FILE_NOT_OPENED); } *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { ffpmsg( "failed to allocate structure for following file: (ffopen)"); ffpmsg(url); return(*status = MEMORY_ALLOCATION); } (*fptr)->Fptr = oldFptr; /* point to the structure */ (*fptr)->HDUposition = 0; /* set initial position */ (((*fptr)->Fptr)->open_count)++; /* increment usage counter */ if (binspec[0]) /* if binning specified, don't move */ extspec[0] = '\0'; /* all the filtering has already been applied, so ignore */ rowfilter[0] = '\0'; binspec[0] = '\0'; colspec[0] = '\0'; *isopen = 1; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fits_is_this_a_copy(char *urltype) /* I - type of file */ /* specialized routine that returns 1 if the file is known to be a temporary copy of the originally opened file. Otherwise it returns 0. */ { int iscopy; if (!strncmp(urltype, "mem", 3) ) iscopy = 1; /* file copy is in memory */ else if (!strncmp(urltype, "compress", 8) ) iscopy = 1; /* compressed diskfile that is uncompressed in memory */ else if (!strncmp(urltype, "http", 4) ) iscopy = 1; /* copied file using http protocol */ else if (!strncmp(urltype, "ftp", 3) ) iscopy = 1; /* copied file using ftp protocol */ else if (!strncmp(urltype, "gsiftp", 6) ) iscopy = 1; /* copied file using gsiftp protocol */ else if (!strncpy(urltype, "stdin", 5) ) iscopy = 1; /* piped stdin has been copied to memory */ else iscopy = 0; /* file is not known to be a copy */ return(iscopy); } /*--------------------------------------------------------------------------*/ int ffedit_columns( fitsfile **fptr, /* IO - pointer to input table; on output it */ /* points to the new selected rows table */ char *outfile, /* I - name for output file */ char *expr, /* I - column edit expression */ int *status) /* modify columns in a table and/or header keywords in the HDU */ { fitsfile *newptr; int ii, hdunum, slen, colnum = -1, testnum, deletecol = 0, savecol = 0; int numcols = 0, *colindex = 0, tstatus = 0; char *cptr, *cptr2, *cptr3, clause[FLEN_FILENAME], keyname[FLEN_KEYWORD]; char colname[FLEN_VALUE], oldname[FLEN_VALUE], colformat[FLEN_VALUE]; char *file_expr = NULL, testname[FLEN_VALUE], card[FLEN_CARD]; if (*outfile) { /* create new empty file in to hold the selected rows */ if (ffinit(&newptr, outfile, status) > 0) { ffpmsg("failed to create file for copy (ffedit_columns)"); return(*status); } fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */ /* copy all HDUs to the output copy */ for (ii = 1; 1; ii++) { if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0) break; fits_copy_hdu(*fptr, newptr, 0, status); } if (*status == END_OF_FILE) { *status = 0; /* got the expected EOF error; reset = 0 */ } else if (*status > 0) { ffclos(newptr, status); ffpmsg("failed to copy all HDUs from input file (ffedit_columns)"); return(*status); } /* close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = newptr; /* reset the pointer to the new table */ /* move back to the selected table HDU */ if (fits_movabs_hdu(*fptr, hdunum, NULL, status) > 0) { ffpmsg("failed to copy the input file (ffedit_columns)"); return(*status); } } /* remove the "col " from the beginning of the column edit expression */ cptr = expr + 4; while (*cptr == ' ') cptr++; /* skip leading white space */ /* Check if need to import expression from a file */ if( *cptr=='@' ) { if( ffimport_file( cptr+1, &file_expr, status ) ) return(*status); cptr = file_expr; while (*cptr == ' ') cptr++; /* skip leading white space... again */ } tstatus = 0; ffgncl(*fptr, &numcols, &tstatus); /* get initial # of cols */ /* parse expression and get first clause, if more than 1 */ while ((slen = fits_get_token(&cptr, ";", clause, NULL)) > 0 ) { if( *cptr==';' ) cptr++; clause[slen] = '\0'; if (clause[0] == '!' || clause[0] == '-') { /* ===================================== */ /* Case I. delete this column or keyword */ /* ===================================== */ if (ffgcno(*fptr, CASEINSEN, &clause[1], &colnum, status) <= 0) { /* a column with this name exists, so try to delete it */ if (ffdcol(*fptr, colnum, status) > 0) { ffpmsg("failed to delete column in input file:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status); } deletecol = 1; /* set flag that at least one col was deleted */ numcols--; colnum = -1; } else { ffcmsg(); /* clear previous error message from ffgcno */ /* try deleting a keyword with this name */ *status = 0; if (ffdkey(*fptr, &clause[1], status) > 0) { ffpmsg("column or keyword to be deleted does not exist:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status); } } } else { /* ===================================================== */ /* Case II: this is either a column name, (case 1) or a new column name followed by double = ("==") followed by the old name which is to be renamed. (case 2A) or a column or keyword name followed by a single "=" and a calculation expression (case 2B) */ /* ===================================================== */ cptr2 = clause; slen = fits_get_token(&cptr2, "( =", colname, NULL); if (slen == 0) { ffpmsg("error: column or keyword name is blank:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status= URL_PARSE_ERROR); } /* If this is a keyword of the form #KEYWORD# then transform to the form #KEYWORDn where n is the previously used column number */ if (colname[0] == '#' && strstr(colname+1, "#") == (colname + strlen(colname) - 1)) { if (colnum <= 0) { ffpmsg("The keyword name:"); ffpmsg(colname); ffpmsg("is invalid unless a column has been previously"); ffpmsg("created or editted by a calculator command"); return(*status = URL_PARSE_ERROR); } colname[strlen(colname)-1] = '\0'; /* Make keyword name and put it in oldname */ ffkeyn(colname+1, colnum, oldname, status); if (*status) return (*status); /* Re-copy back into colname */ strcpy(colname+1,oldname); } else if (strstr(colname, "#") == (colname + strlen(colname) - 1)) { /* colname is of the form "NAME#"; if a) colnum is defined, and b) a column with literal name "NAME#" does not exist, and c) a keyword with name "NAMEn" (where n=colnum) exists, then transfrom the colname string to "NAMEn", otherwise do nothing. */ if (colnum > 0) { /* colnum must be defined */ tstatus = 0; ffgcno(*fptr, CASEINSEN, colname, &testnum, &tstatus); if (tstatus != 0 && tstatus != COL_NOT_UNIQUE) { /* OK, column doesn't exist, now see if keyword exists */ ffcmsg(); /* clear previous error message from ffgcno */ strcpy(testname, colname); testname[strlen(testname)-1] = '\0'; /* Make keyword name and put it in oldname */ ffkeyn(testname, colnum, oldname, status); if (*status) return (*status); tstatus = 0; if (!fits_read_card(*fptr, oldname, card, &tstatus)) { /* Keyword does exist; copy real name back into colname */ strcpy(colname,oldname); } } } } /* if we encountered an opening parenthesis, then we need to */ /* find the closing parenthesis, and concatinate the 2 strings */ /* This supports expressions like: [col #EXTNAME(Extension name)="GTI"] */ if (*cptr2 == '(') { fits_get_token(&cptr2, ")", oldname, NULL); strcat(colname, oldname); strcat(colname, ")"); cptr2++; } while (*cptr2 == ' ') cptr2++; /* skip white space */ if (*cptr2 != '=') { /* ------------------------------------ */ /* case 1 - simply the name of a column */ /* ------------------------------------ */ /* look for matching column */ ffgcno(*fptr, CASEINSEN, colname, &testnum, status); while (*status == COL_NOT_UNIQUE) { /* the column name contained wild cards, and it */ /* matches more than one column in the table. */ colnum = testnum; /* keep this column in the output file */ savecol = 1; if (!colindex) colindex = (int *) calloc(999, sizeof(int)); colindex[colnum - 1] = 1; /* flag this column number */ /* look for other matching column names */ ffgcno(*fptr, CASEINSEN, colname, &testnum, status); if (*status == COL_NOT_FOUND) *status = 999; /* temporary status flag value */ } if (*status <= 0) { colnum = testnum; /* keep this column in the output file */ savecol = 1; if (!colindex) colindex = (int *) calloc(999, sizeof(int)); colindex[colnum - 1] = 1; /* flag this column number */ } else if (*status == 999) { /* this special flag value does not represent an error */ *status = 0; } else { ffpmsg("Syntax error in columns specifier in input URL:"); ffpmsg(cptr2); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } } else { /* ----------------------------------------------- */ /* case 2 where the token ends with an equals sign */ /* ----------------------------------------------- */ cptr2++; /* skip over the first '=' */ if (*cptr2 == '=') { /*................................................. */ /* Case A: rename a column or keyword; syntax is "new_name == old_name" */ /*................................................. */ cptr2++; /* skip the 2nd '=' */ while (*cptr2 == ' ') cptr2++; /* skip white space */ fits_get_token(&cptr2, " ", oldname, NULL); /* get column number of the existing column */ if (ffgcno(*fptr, CASEINSEN, oldname, &colnum, status) <= 0) { /* modify the TTYPEn keyword value with the new name */ ffkeyn("TTYPE", colnum, keyname, status); if (ffmkys(*fptr, keyname, colname, NULL, status) > 0) { ffpmsg("failed to rename column in input file"); ffpmsg(" oldname ="); ffpmsg(oldname); ffpmsg(" newname ="); ffpmsg(colname); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status); } /* keep this column in the output file */ savecol = 1; if (!colindex) colindex = (int *) calloc(999, sizeof(int)); colindex[colnum - 1] = 1; /* flag this column number */ } else { /* try renaming a keyword */ ffcmsg(); /* clear error message stack */ *status = 0; if (ffmnam(*fptr, oldname, colname, status) > 0) { ffpmsg("column or keyword to be renamed does not exist:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status); } } } else { /*...................................................... */ /* Case B: */ /* this must be a general column/keyword calc expression */ /* "name = expression" or "colname(TFORM) = expression" */ /*...................................................... */ /* parse the name and TFORM values, if present */ colformat[0] = '\0'; cptr3 = colname; fits_get_token(&cptr3, "(", oldname, NULL); if (cptr3[0] == '(' ) { cptr3++; /* skip the '(' */ fits_get_token(&cptr3, ")", colformat, NULL); } /* calculate values for the column or keyword */ /* cptr2 = the expression to be calculated */ /* oldname = name of the column or keyword */ /* colformat = column format, or keyword comment string */ if (fits_calculator(*fptr, cptr2, *fptr, oldname, colformat, status) > 0) { ffpmsg("Unable to calculate expression"); return(*status); } /* test if this is a column and not a keyword */ tstatus = 0; ffgcno(*fptr, CASEINSEN, oldname, &testnum, &tstatus); if (tstatus == 0) { /* keep this column in the output file */ colnum = testnum; savecol = 1; if (!colindex) colindex = (int *) calloc(999, sizeof(int)); colindex[colnum - 1] = 1; if (colnum > numcols)numcols++; } else { ffcmsg(); /* clear the error message stack */ } } } } } if (savecol && !deletecol) { /* need to delete all but the specified columns */ for (ii = numcols; ii > 0; ii--) { if (!colindex[ii-1]) /* delete this column */ { if (ffdcol(*fptr, ii, status) > 0) { ffpmsg("failed to delete column in input file:"); ffpmsg(clause); if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status); } } } } if( colindex ) free( colindex ); if( file_expr ) free( file_expr ); return(*status); } /*--------------------------------------------------------------------------*/ int fits_copy_cell2image( fitsfile *fptr, /* I - point to input table */ fitsfile *newptr, /* O - existing output file; new image HDU will be appended to it */ char *colname, /* I - column name / number containing the image*/ long rownum, /* I - number of the row containing the image */ int *status) /* IO - error status */ /* Copy a table cell of a given row and column into an image extension. The output file must already have been created. A new image extension will be created in that file. This routine was written by Craig Markwardt, GSFC */ { unsigned char buffer[30000]; int hdutype, colnum, typecode, bitpix, naxis, maxelem, tstatus; LONGLONG naxes[9], nbytes, firstbyte, ntodo; LONGLONG repeat, startpos, elemnum, rowlen, tnull; long twidth, incre; double scale, zero; char tform[20]; char card[FLEN_CARD]; char templt[FLEN_CARD] = ""; /* Table-to-image keyword translation table */ /* INPUT OUTPUT */ /* 01234567 01234567 */ char *patterns[][2] = {{"TSCALn", "BSCALE" }, /* Standard FITS keywords */ {"TZEROn", "BZERO" }, {"TUNITn", "BUNIT" }, {"TNULLn", "BLANK" }, {"TDMINn", "DATAMIN" }, {"TDMAXn", "DATAMAX" }, {"iCTYPn", "CTYPEi" }, /* Coordinate labels */ {"iCTYna", "CTYPEia" }, {"iCUNIn", "CUNITi" }, /* Coordinate units */ {"iCUNna", "CUNITia" }, {"iCRVLn", "CRVALi" }, /* WCS keywords */ {"iCRVna", "CRVALia" }, {"iCDLTn", "CDELTi" }, {"iCDEna", "CDELTia" }, {"iCRPXn", "CRPIXi" }, {"iCRPna", "CRPIXia" }, {"ijPCna", "PCi_ja" }, {"ijCDna", "CDi_ja" }, {"iVn_ma", "PVi_ma" }, {"iSn_ma", "PSi_ma" }, {"iCRDna", "CRDERia" }, {"iCSYna", "CSYERia" }, {"iCROTn", "CROTAi" }, {"WCAXna", "WCSAXESa"}, {"WCSNna", "WCSNAMEa"}, {"LONPna", "LONPOLEa"}, {"LATPna", "LATPOLEa"}, {"EQUIna", "EQUINOXa"}, {"MJDOBn", "MJD-OBS" }, {"MJDAn", "MJD-AVG" }, {"RADEna", "RADESYSa"}, {"iCNAna", "CNAMEia" }, {"DAVGn", "DATE-AVG"}, /* Delete table keywords related to other columns */ {"T????#a", "-" }, {"TC??#a", "-" }, {"TWCS#a", "-" }, {"TDIM#", "-" }, {"iCTYPm", "-" }, {"iCUNIm", "-" }, {"iCRVLm", "-" }, {"iCDLTm", "-" }, {"iCRPXm", "-" }, {"iCTYma", "-" }, {"iCUNma", "-" }, {"iCRVma", "-" }, {"iCDEma", "-" }, {"iCRPma", "-" }, {"ijPCma", "-" }, {"ijCDma", "-" }, {"iVm_ma", "-" }, {"iSm_ma", "-" }, {"iCRDma", "-" }, {"iCSYma", "-" }, {"iCROTm", "-" }, {"WCAXma", "-" }, {"WCSNma", "-" }, {"LONPma", "-" }, {"LATPma", "-" }, {"EQUIma", "-" }, {"MJDOBm", "-" }, {"MJDAm", "-" }, {"RADEma", "-" }, {"iCNAma", "-" }, {"DAVGm", "-" }, {"EXTNAME", "-" }, /* Remove structural keywords*/ {"EXTVER", "-" }, {"EXTLEVEL","-" }, {"CHECKSUM","-" }, {"DATASUM", "-" }, {"*", "+" }}; /* copy all other keywords */ int npat; if (*status > 0) return(*status); /* get column number */ if (ffgcno(fptr, CASEINSEN, colname, &colnum, status) > 0) { ffpmsg("column containing image in table cell does not exist:"); ffpmsg(colname); return(*status); } /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if ( ffgcprll(fptr, colnum, rownum, 1L, 1L, 0, &scale, &zero, tform, &twidth, &typecode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, (char *) buffer, status) > 0 ) return(*status); /* get the actual column name, in case a column number was given */ ffkeyn("", colnum, templt, &tstatus); ffgcnn(fptr, CASEINSEN, templt, colname, &colnum, &tstatus); if (hdutype != BINARY_TBL) { ffpmsg("This extension is not a binary table."); ffpmsg(" Cannot open the image in a binary table cell."); return(*status = NOT_BTABLE); } if (typecode < 0) { /* variable length array */ typecode *= -1; /* variable length arrays are 1-dimensional by default */ naxis = 1; naxes[0] = repeat; } else { /* get the dimensions of the image */ ffgtdmll(fptr, colnum, 9, &naxis, naxes, status); } if (*status > 0) { ffpmsg("Error getting the dimensions of the image"); return(*status); } /* determine BITPIX value for the image */ if (typecode == TBYTE) { bitpix = BYTE_IMG; nbytes = repeat; } else if (typecode == TSHORT) { bitpix = SHORT_IMG; nbytes = repeat * 2; } else if (typecode == TLONG) { bitpix = LONG_IMG; nbytes = repeat * 4; } else if (typecode == TFLOAT) { bitpix = FLOAT_IMG; nbytes = repeat * 4; } else if (typecode == TDOUBLE) { bitpix = DOUBLE_IMG; nbytes = repeat * 8; } else if (typecode == TLONGLONG) { bitpix = LONGLONG_IMG; nbytes = repeat * 8; } else if (typecode == TLOGICAL) { bitpix = BYTE_IMG; nbytes = repeat; } else { ffpmsg("Error: the following image column has invalid datatype:"); ffpmsg(colname); ffpmsg(tform); ffpmsg("Cannot open an image in a single row of this column."); return(*status = BAD_TFORM); } /* create new image in output file */ if (ffcrimll(newptr, bitpix, naxis, naxes, status) > 0) { ffpmsg("failed to write required primary array keywords in the output file"); return(*status); } npat = sizeof(patterns)/sizeof(patterns[0][0])/2; /* skip over the first 8 keywords, starting just after TFIELDS */ fits_translate_keywords(fptr, newptr, 9, patterns, npat, colnum, 0, 0, status); /* add some HISTORY */ sprintf(card,"HISTORY This image was copied from row %ld of column '%s',", rownum, colname); /* disable this; leave it up to the caller to write history if needed. ffprec(newptr, card, status); */ /* the use of ffread routine, below, requires that any 'dirty' */ /* buffers in memory be flushed back to the file first */ ffflsh(fptr, FALSE, status); /* finally, copy the data, one buffer size at a time */ ffmbyt(fptr, startpos, TRUE, status); firstbyte = 1; /* the upper limit on the number of bytes must match the declaration */ /* read up to the first 30000 bytes in the normal way with ffgbyt */ ntodo = minvalue(30000, nbytes); ffgbyt(fptr, ntodo, buffer, status); ffptbb(newptr, 1, firstbyte, ntodo, buffer, status); nbytes -= ntodo; firstbyte += ntodo; /* read any additional bytes with low-level ffread routine, for speed */ while (nbytes && (*status <= 0) ) { ntodo = minvalue(30000, nbytes); ffread((fptr)->Fptr, (long) ntodo, buffer, status); ffptbb(newptr, 1, firstbyte, ntodo, buffer, status); nbytes -= ntodo; firstbyte += ntodo; } /* Re-scan the header so that CFITSIO knows about all the new keywords */ ffrdef(newptr,status); return(*status); } /*--------------------------------------------------------------------------*/ int fits_copy_image2cell( fitsfile *fptr, /* I - pointer to input image extension */ fitsfile *newptr, /* I - pointer to output table */ char *colname, /* I - name of column containing the image */ long rownum, /* I - number of the row containing the image */ int copykeyflag, /* I - controls which keywords to copy */ int *status) /* IO - error status */ /* Copy an image extension into a table cell at a given row and column. The table must have already been created. If the "colname" column exists, it will be used, otherwise a new column will be created in the table. The "copykeyflag" parameter controls which keywords to copy from the input image to the output table header (with any appropriate translation). copykeyflag = 0 -- no keywords will be copied copykeyflag = 1 -- essentially all keywords will be copied copykeyflag = 2 -- copy only the WCS related keywords This routine was written by Craig Markwardt, GSFC */ { tcolumn *colptr; unsigned char buffer[30000]; int ii, hdutype, colnum, typecode, bitpix, naxis, ncols, hdunum; char tformchar, tform[20], card[FLEN_CARD]; LONGLONG imgstart, naxes[9], nbytes, repeat, ntodo,firstbyte; char filename[FLEN_FILENAME+20]; int npat; int naxis1; LONGLONG naxes1[9] = {0,0,0,0,0,0,0,0,0}, repeat1, width1; int typecode1; unsigned char dummy = 0; LONGLONG headstart, datastart, dataend; /* Image-to-table keyword translation table */ /* INPUT OUTPUT */ /* 01234567 01234567 */ char *patterns[][2] = {{"BSCALE", "TSCALn" }, /* Standard FITS keywords */ {"BZERO", "TZEROn" }, {"BUNIT", "TUNITn" }, {"BLANK", "TNULLn" }, {"DATAMIN", "TDMINn" }, {"DATAMAX", "TDMAXn" }, {"CTYPEi", "iCTYPn" }, /* Coordinate labels */ {"CTYPEia", "iCTYna" }, {"CUNITi", "iCUNIn" }, /* Coordinate units */ {"CUNITia", "iCUNna" }, {"CRVALi", "iCRVLn" }, /* WCS keywords */ {"CRVALia", "iCRVna" }, {"CDELTi", "iCDLTn" }, {"CDELTia", "iCDEna" }, {"CRPIXj", "jCRPXn" }, {"CRPIXja", "jCRPna" }, {"PCi_ja", "ijPCna" }, {"CDi_ja", "ijCDna" }, {"PVi_ma", "iVn_ma" }, {"PSi_ma", "iSn_ma" }, {"WCSAXESa","WCAXna" }, {"WCSNAMEa","WCSNna" }, {"CRDERia", "iCRDna" }, {"CSYERia", "iCSYna" }, {"CROTAi", "iCROTn" }, {"LONPOLEa","LONPna"}, {"LATPOLEa","LATPna"}, {"EQUINOXa","EQUIna"}, {"MJD-OBS", "MJDOBn" }, {"MJD-AVG", "MJDAn" }, {"RADESYSa","RADEna"}, {"CNAMEia", "iCNAna" }, {"DATE-AVG","DAVGn"}, {"NAXISi", "-" }, /* Remove structural keywords*/ {"PCOUNT", "-" }, {"GCOUNT", "-" }, {"EXTEND", "-" }, {"EXTNAME", "-" }, {"EXTVER", "-" }, {"EXTLEVEL","-" }, {"CHECKSUM","-" }, {"DATASUM", "-" }, {"*", "+" }}; /* copy all other keywords */ if (*status > 0) return(*status); if (fptr == 0 || newptr == 0) return (*status = NULL_INPUT_PTR); if (ffghdt(fptr, &hdutype, status) > 0) { ffpmsg("could not get input HDU type"); return (*status); } if (hdutype != IMAGE_HDU) { ffpmsg("The input extension is not an image."); ffpmsg(" Cannot open the image."); return(*status = NOT_IMAGE); } if (ffghdt(newptr, &hdutype, status) > 0) { ffpmsg("could not get output HDU type"); return (*status); } if (hdutype != BINARY_TBL) { ffpmsg("The output extension is not a table."); return(*status = NOT_BTABLE); } if (ffgiprll(fptr, 9, &bitpix, &naxis, naxes, status) > 0) { ffpmsg("Could not read image parameters."); return (*status); } /* Determine total number of pixels in the image */ repeat = 1; for (ii = 0; ii < naxis; ii++) repeat *= naxes[ii]; /* Determine the TFORM value for the table cell */ if (bitpix == BYTE_IMG) { typecode = TBYTE; tformchar = 'B'; nbytes = repeat; } else if (bitpix == SHORT_IMG) { typecode = TSHORT; tformchar = 'I'; nbytes = repeat*2; } else if (bitpix == LONG_IMG) { typecode = TLONG; tformchar = 'J'; nbytes = repeat*4; } else if (bitpix == FLOAT_IMG) { typecode = TFLOAT; tformchar = 'E'; nbytes = repeat*4; } else if (bitpix == DOUBLE_IMG) { typecode = TDOUBLE; tformchar = 'D'; nbytes = repeat*8; } else if (bitpix == LONGLONG_IMG) { typecode = TLONGLONG; tformchar = 'K'; nbytes = repeat*8; } else { ffpmsg("Error: the image has an invalid datatype."); return (*status = BAD_BITPIX); } /* get column number */ ffpmrk(); ffgcno(newptr, CASEINSEN, colname, &colnum, status); ffcmrk(); /* Column does not exist; create it */ if (*status) { *status = 0; sprintf(tform, "%.0f%c", (double) repeat, tformchar); ffgncl(newptr, &ncols, status); colnum = ncols+1; fficol(newptr, colnum, colname, tform, status); ffptdmll(newptr, colnum, naxis, naxes, status); if (*status) { ffpmsg("Could not insert new column into output table."); return *status; } } else { ffgtdmll(newptr, colnum, 9, &naxis1, naxes1, status); if (*status > 0 || naxis != naxis1) { ffpmsg("Input image dimensions and output table cell dimensions do not match."); return (*status = BAD_DIMEN); } for (ii=0; ii 0) || (typecode1 != typecode) || (repeat1 != repeat)) { ffpmsg("Input image data type does not match output table cell type."); return (*status = BAD_TFORM); } } /* copy keywords from input image to output table, if required */ if (copykeyflag) { npat = sizeof(patterns)/sizeof(patterns[0][0])/2; if (copykeyflag == 2) { /* copy only the WCS-related keywords */ patterns[npat-1][1] = "-"; } /* The 3rd parameter value = 5 means skip the first 4 keywords in the image */ fits_translate_keywords(fptr, newptr, 5, patterns, npat, colnum, 0, 0, status); } /* Here is all the code to compute offsets: * * byte offset from start of row to column (dest table) * * byte offset from start of file to image data (source image) */ /* Force the writing of the row of the table by writing the last byte of the array, which grows the table, and/or shifts following extensions */ ffpcl(newptr, TBYTE, colnum, rownum, repeat, 1, &dummy, status); /* byte offset within the row to the start of the image column */ colptr = (newptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ firstbyte = colptr->tbcol + 1; /* get starting address of input image to be read */ ffghadll(fptr, &headstart, &datastart, &dataend, status); imgstart = datastart; sprintf(card, "HISTORY Table column '%s' row %ld copied from image", colname, rownum); /* Don't automatically write History keywords; leave this up to the caller. ffprec(newptr, card, status); */ /* write HISTORY keyword with the file name (this is now disabled)*/ filename[0] = '\0'; hdunum = 0; strcpy(filename, "HISTORY "); ffflnm(fptr, filename+strlen(filename), status); ffghdn(fptr, &hdunum); sprintf(filename+strlen(filename),"[%d]", hdunum-1); /* ffprec(newptr, filename, status); */ /* the use of ffread routine, below, requires that any 'dirty' */ /* buffers in memory be flushed back to the file first */ ffflsh(fptr, FALSE, status); /* move to the first byte of the input image */ ffmbyt(fptr, imgstart, TRUE, status); ntodo = minvalue(30000L, nbytes); ffgbyt(fptr, ntodo, buffer, status); /* read input image */ ffptbb(newptr, rownum, firstbyte, ntodo, buffer, status); /* write to table */ nbytes -= ntodo; firstbyte += ntodo; /* read any additional bytes with low-level ffread routine, for speed */ while (nbytes && (*status <= 0) ) { ntodo = minvalue(30000L, nbytes); ffread(fptr->Fptr, (long) ntodo, buffer, status); ffptbb(newptr, rownum, firstbyte, ntodo, buffer, status); nbytes -= ntodo; firstbyte += ntodo; } /* Re-scan the header so that CFITSIO knows about all the new keywords */ ffrdef(newptr,status); return(*status); } /*--------------------------------------------------------------------------*/ int fits_select_image_section( fitsfile **fptr, /* IO - pointer to input image; on output it */ /* points to the new subimage */ char *outfile, /* I - name for output file */ char *expr, /* I - Image section expression */ int *status) { /* copies an image section from the input file to a new output file. Any HDUs preceding or following the image are also copied to the output file. */ fitsfile *newptr; int ii, hdunum; /* create new empty file to hold the image section */ if (ffinit(&newptr, outfile, status) > 0) { ffpmsg( "failed to create output file for image section:"); ffpmsg(outfile); return(*status); } fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */ /* copy all preceding extensions to the output file */ for (ii = 1; ii < hdunum; ii++) { fits_movabs_hdu(*fptr, ii, NULL, status); if (fits_copy_hdu(*fptr, newptr, 0, status) > 0) { ffclos(newptr, status); return(*status); } } /* move back to the original HDU position */ fits_movabs_hdu(*fptr, hdunum, NULL, status); if (fits_copy_image_section(*fptr, newptr, expr, status) > 0) { ffclos(newptr, status); return(*status); } /* copy any remaining HDUs to the output file */ for (ii = hdunum + 1; 1; ii++) { if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0) break; fits_copy_hdu(*fptr, newptr, 0, status); } if (*status == END_OF_FILE) *status = 0; /* got the expected EOF error; reset = 0 */ else if (*status > 0) { ffclos(newptr, status); return(*status); } /* close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = newptr; /* reset the pointer to the new table */ /* move back to the image subsection */ if (ii - 1 != hdunum) fits_movabs_hdu(*fptr, hdunum, NULL, status); else { /* may have to reset BSCALE and BZERO pixel scaling, */ /* since the keywords were previously turned off */ if (ffrdef(*fptr, status) > 0) { ffclos(*fptr, status); return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int fits_copy_image_section( fitsfile *fptr, /* I - pointer to input image */ fitsfile *newptr, /* I - pointer to output image */ char *expr, /* I - Image section expression */ int *status) { /* copies an image section from the input file to a new output HDU */ int bitpix, naxis, numkeys, nkey; long naxes[9], smin, smax, sinc, fpixels[9], lpixels[9], incs[9]; char *cptr, keyname[FLEN_KEYWORD], card[FLEN_CARD]; int ii, tstatus, anynull; int klen, kk, jj; long outnaxes[9], outsize, buffsize, dummy[2]; double *buffer = 0, crpix, cdelt; if (*status > 0) return(*status); /* get the size of the input image */ fits_get_img_type(fptr, &bitpix, status); fits_get_img_dim(fptr, &naxis, status); if (fits_get_img_size(fptr, naxis, naxes, status) > 0) return(*status); if (naxis < 1 || naxis > 9) { ffpmsg( "Input image either had NAXIS = 0 (NULL image) or has > 9 dimensions"); return(*status = BAD_NAXIS); } /* create output image with same size and type as the input image */ /* Will update the size later */ fits_create_img(newptr, bitpix, naxis, naxes, status); /* copy all other non-structural keywords from the input to output file */ fits_get_hdrspace(fptr, &numkeys, NULL, status); for (nkey = 4; nkey <= numkeys; nkey++) /* skip the first few keywords */ { fits_read_record(fptr, nkey, card, status); if (fits_get_keyclass(card) > TYP_CMPRS_KEY) { /* write the record to the output file */ fits_write_record(newptr, card, status); } } if (*status > 0) { ffpmsg("error copying header from input image to output image"); return(*status); } /* parse the section specifier to get min, max, and inc for each axis */ /* and the size of each output image axis */ outsize = 1; cptr = expr; for (ii=0; ii < naxis; ii++) { if (fits_get_section_range(&cptr, &smin, &smax, &sinc, status) > 0) { ffpmsg("error parsing the following image section specifier:"); ffpmsg(expr); return(*status); } if (smax == 0) smax = naxes[ii]; /* use whole axis by default */ else if (smin == 0) smin = naxes[ii]; /* use inverted whole axis */ if (smin > naxes[ii] || smax > naxes[ii]) { ffpmsg("image section exceeds dimensions of input image:"); ffpmsg(expr); return(*status = BAD_NAXIS); } fpixels[ii] = smin; lpixels[ii] = smax; incs[ii] = sinc; if (smin <= smax) outnaxes[ii] = (smax - smin + sinc) / sinc; else outnaxes[ii] = (smin - smax + sinc) / sinc; outsize = outsize * outnaxes[ii]; /* modify the NAXISn keyword */ fits_make_keyn("NAXIS", ii + 1, keyname, status); fits_modify_key_lng(newptr, keyname, outnaxes[ii], NULL, status); /* modify the WCS keywords if necessary */ if (fpixels[ii] != 1 || incs[ii] != 1) { for (kk=-1;kk<26; kk++) /* modify any alternate WCS keywords */ { /* read the CRPIXn keyword if it exists in the input file */ fits_make_keyn("CRPIX", ii + 1, keyname, status); if (kk != -1) { klen = strlen(keyname); keyname[klen]='A' + kk; keyname[klen + 1] = '\0'; } tstatus = 0; if (fits_read_key(fptr, TDOUBLE, keyname, &crpix, NULL, &tstatus) == 0) { /* calculate the new CRPIXn value */ if (fpixels[ii] <= lpixels[ii]) crpix = (crpix - (fpixels[ii] - 1.0) - .5) / incs[ii] + 0.5; else crpix = (fpixels[ii] - (crpix - 1.0) - .5) / incs[ii] + 0.5; /* modify the value in the output file */ fits_modify_key_dbl(newptr, keyname, crpix, 15, NULL, status); if (incs[ii] != 1 || fpixels[ii] > lpixels[ii]) { /* read the CDELTn keyword if it exists in the input file */ fits_make_keyn("CDELT", ii + 1, keyname, status); if (kk != -1) { klen = strlen(keyname); keyname[klen]='A' + kk; keyname[klen + 1] = '\0'; } tstatus = 0; if (fits_read_key(fptr, TDOUBLE, keyname, &cdelt, NULL, &tstatus) == 0) { /* calculate the new CDELTn value */ if (fpixels[ii] <= lpixels[ii]) cdelt = cdelt * incs[ii]; else cdelt = cdelt * (-incs[ii]); /* modify the value in the output file */ fits_modify_key_dbl(newptr, keyname, cdelt, 15, NULL, status); } /* modify the CDi_j keywords if they exist in the input file */ fits_make_keyn("CD1_", ii + 1, keyname, status); if (kk != -1) { klen = strlen(keyname); keyname[klen]='A' + kk; keyname[klen + 1] = '\0'; } for (jj=0; jj < 9; jj++) /* look for up to 9 dimensions */ { keyname[2] = '1' + jj; tstatus = 0; if (fits_read_key(fptr, TDOUBLE, keyname, &cdelt, NULL, &tstatus) == 0) { /* calculate the new CDi_j value */ if (fpixels[ii] <= lpixels[ii]) cdelt = cdelt * incs[ii]; else cdelt = cdelt * (-incs[ii]); /* modify the value in the output file */ fits_modify_key_dbl(newptr, keyname, cdelt, 15, NULL, status); } } } /* end of if (incs[ii]... loop */ } /* end of fits_read_key loop */ } /* end of for (kk loop */ } } /* end of main NAXIS loop */ if (ffrdef(newptr, status) > 0) /* force the header to be scanned */ { return(*status); } /* write a dummy value to the last pixel in the output section */ /* This will force memory to be allocated for the FITS files if it */ /* is being written in memory, before we allocate some more memory */ /* below. Hopefully this leads to better memory management and */ /* reduces the probability that the memory for the FITS file will have */ /* to be reallocated to a new location later. */ /* turn off any scaling of the pixel values */ fits_set_bscale(fptr, 1.0, 0.0, status); fits_set_bscale(newptr, 1.0, 0.0, status); dummy[0] = 0; if (fits_write_img(newptr, TLONG, outsize, 1, dummy, status) > 0) { ffpmsg("fits_copy_image_section: error writing to the last image pixel"); return(*status); } /* allocate memory for the entire image section */ buffsize = (abs(bitpix) / 8) * outsize; buffer = (double *) malloc(buffsize); if (!buffer) { ffpmsg("fits_copy_image_section: no memory for image section"); return(*status = MEMORY_ALLOCATION); } /* read the image section then write it to the output file */ if (bitpix == 8) { ffgsvb(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0, (unsigned char *) buffer, &anynull, status); ffpprb(newptr, 1, 1, outsize, (unsigned char *) buffer, status); } else if (bitpix == 16) { ffgsvi(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0, (short *) buffer, &anynull, status); ffppri(newptr, 1, 1, outsize, (short *) buffer, status); } else if (bitpix == 32) { ffgsvk(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0, (int *) buffer, &anynull, status); ffpprk(newptr, 1, 1, outsize, (int *) buffer, status); } else if (bitpix == -32) { ffgsve(fptr, 1, naxis, naxes, fpixels, lpixels, incs, FLOATNULLVALUE, (float *) buffer, &anynull, status); ffppne(newptr, 1, 1, outsize, (float *) buffer, FLOATNULLVALUE, status); } else if (bitpix == -64) { ffgsvd(fptr, 1, naxis, naxes, fpixels, lpixels, incs, DOUBLENULLVALUE, buffer, &anynull, status); ffppnd(newptr, 1, 1, outsize, buffer, DOUBLENULLVALUE, status); } else if (bitpix == 64) { ffgsvjj(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0, (LONGLONG *) buffer, &anynull, status); ffpprjj(newptr, 1, 1, outsize, (LONGLONG *) buffer, status); } free(buffer); /* finished with the memory */ if (*status > 0) { ffpmsg("fits_copy_image_section: error copying image section"); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_section_range(char **ptr, long *secmin, long *secmax, long *incre, int *status) /* Parse the input image section specification string, returning the min, max and increment values. Typical string = "1:512:2" or "1:512" */ { int slen, isanumber; char token[FLEN_VALUE]; if (*status > 0) return(*status); slen = fits_get_token(ptr, " ,:", token, &isanumber); /* get 1st token */ if (*token == '*') /* wild card means to use the whole range */ { *secmin = 1; *secmax = 0; } else if (*token == '-' && *(token+1) == '*' ) /* invert the whole range */ { *secmin = 0; *secmax = 1; } else { if (slen == 0 || !isanumber || **ptr != ':') return(*status = URL_PARSE_ERROR); /* the token contains the min value */ *secmin = atol(token); (*ptr)++; /* skip the colon between the min and max values */ slen = fits_get_token(ptr, " ,:", token, &isanumber); /* get token */ if (slen == 0 || !isanumber) return(*status = URL_PARSE_ERROR); /* the token contains the max value */ *secmax = atol(token); } if (**ptr == ':') { (*ptr)++; /* skip the colon between the max and incre values */ slen = fits_get_token(ptr, " ,", token, &isanumber); /* get token */ if (slen == 0 || !isanumber) return(*status = URL_PARSE_ERROR); *incre = atol(token); } else *incre = 1; /* default increment if none is supplied */ if (**ptr == ',') (*ptr)++; while (**ptr == ' ') /* skip any trailing blanks */ (*ptr)++; if (*secmin < 0 || *secmax < 0 || *incre < 1) *status = URL_PARSE_ERROR; return(*status); } /*--------------------------------------------------------------------------*/ int ffselect_table( fitsfile **fptr, /* IO - pointer to input table; on output it */ /* points to the new selected rows table */ char *outfile, /* I - name for output file */ char *expr, /* I - Boolean expression */ int *status) { fitsfile *newptr; int ii, hdunum; if (*outfile) { /* create new empty file in to hold the selected rows */ if (ffinit(&newptr, outfile, status) > 0) { ffpmsg( "failed to create file for selected rows from input table"); ffpmsg(outfile); return(*status); } fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */ /* copy all preceding extensions to the output file */ for (ii = 1; ii < hdunum; ii++) { fits_movabs_hdu(*fptr, ii, NULL, status); if (fits_copy_hdu(*fptr, newptr, 0, status) > 0) { ffclos(newptr, status); return(*status); } } /* copy all the header keywords from the input to output file */ fits_movabs_hdu(*fptr, hdunum, NULL, status); if (fits_copy_header(*fptr, newptr, status) > 0) { ffclos(newptr, status); return(*status); } /* set number of rows = 0 */ fits_modify_key_lng(newptr, "NAXIS2", 0, NULL,status); (newptr->Fptr)->numrows = 0; (newptr->Fptr)->origrows = 0; if (ffrdef(newptr, status) > 0) /* force the header to be scanned */ { ffclos(newptr, status); return(*status); } } else newptr = *fptr; /* will delete rows in place in the table */ /* copy rows which satisfy the selection expression to the output table */ /* or delete the nonqualifying rows if *fptr = newptr. */ if (fits_select_rows(*fptr, newptr, expr, status) > 0) { if (*outfile) ffclos(newptr, status); return(*status); } if (*outfile) { /* copy any remaining HDUs to the output copy */ for (ii = hdunum + 1; 1; ii++) { if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0) break; fits_copy_hdu(*fptr, newptr, 0, status); } if (*status == END_OF_FILE) *status = 0; /* got the expected EOF error; reset = 0 */ else if (*status > 0) { ffclos(newptr, status); return(*status); } /* close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = newptr; /* reset the pointer to the new table */ /* move back to the selected table HDU */ fits_movabs_hdu(*fptr, hdunum, NULL, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffparsecompspec(fitsfile *fptr, /* I - FITS file pointer */ char *compspec, /* I - image compression specification */ int *status) /* IO - error status */ /* Parse the image compression specification that was give in square brackets following the output FITS file name, as in these examples: myfile.fits[compress] - default Rice compression, row by row myfile.fits[compress TYPE] - the first letter of TYPE defines the compression algorithm: R = Rice G = GZIP H = HCOMPRESS P = PLIO myfile.fits[compress TYPE 100,100] - the numbers give the dimensions of the compression tiles. Default is NAXIS1, 1, 1, ... myfile.fits[compress; 5] The number following the semicolon mufile.fits[compress TYPE; 5] gives the value of the noisebits myfile.fits[compress TYPE 100,100; 5] parameter that is used when quantizing floating point images. The compression parameters are saved in the fptr->Fptr structure for use when writing FITS images. */ { char *ptr1; /* initialize with default values */ int ii, compresstype = RICE_1, noisebits = 4, smooth = 0, scale = 1, intval; long tilesize[9] = {0,1,1,1,1,1,1,1,1}; ptr1 = compspec; while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; if (strncmp(ptr1, "compress", 8) && strncmp(ptr1, "COMPRESS", 8) ) { /* apparently this string does not specify compression parameters */ return(*status = URL_PARSE_ERROR); } ptr1 += 8; while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; /* ========================= */ /* look for compression type */ /* ========================= */ if (*ptr1 == 'r' || *ptr1 == 'R') { compresstype = RICE_1; while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0') ptr1++; } else if (*ptr1 == 'g' || *ptr1 == 'G') { compresstype = GZIP_1; while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0') ptr1++; } else if (*ptr1 == 'p' || *ptr1 == 'P') { compresstype = PLIO_1; while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0') ptr1++; } else if (*ptr1 == 'h' || *ptr1 == 'H') { compresstype = HCOMPRESS_1; while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0') ptr1++; } /* ======================== */ /* look for tile dimensions */ /* ======================== */ while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; ii = 0; while (isdigit( (int) *ptr1) && ii < 9) { tilesize[ii] = atol(ptr1); /* read the integer value */ ii++; while (isdigit((int) *ptr1)) /* skip over the integer */ ptr1++; if (*ptr1 == ',') ptr1++; /* skip over the comma */ while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; } /* ========================================================= */ /* look for other parameters */ /* ========================================================= */ if (*ptr1 == ';') { ptr1++; while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; /* get first integer parameter */ if (!isdigit((int) *ptr1) ) return(*status = URL_PARSE_ERROR); intval = atol(ptr1); /* read the integer value */ if (compresstype == HCOMPRESS_1) scale = intval; else noisebits = intval; while (isdigit((int) *ptr1)) /* skip over the integer */ ptr1++; if (*ptr1 == ',') { ptr1++; /* skip over the comma */ while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; /* get 2nd integer parameter */ if (!isdigit((int) *ptr1) ) return(*status = URL_PARSE_ERROR); intval = atol(ptr1); /* read the integer value */ if (compresstype == HCOMPRESS_1) smooth = intval; else return(*status = URL_PARSE_ERROR); while (isdigit((int) *ptr1)) /* skip over the integer */ ptr1++; } } while (*ptr1 == ' ') /* ignore blanks */ ptr1++; if (*ptr1 != 0) /* remaining junk in the string?? */ return(*status = URL_PARSE_ERROR); /* ================================= */ /* finished parsing; save the values */ /* ================================= */ (fptr->Fptr)->request_compress_type = compresstype; for (ii = 0; ii < 9; ii++) (fptr->Fptr)->request_tilesize[ii] = tilesize[ii]; if (compresstype == HCOMPRESS_1) { (fptr->Fptr)->request_hcomp_scale = scale; (fptr->Fptr)->request_hcomp_smooth = smooth; } else { (fptr->Fptr)->request_noise_nbits = noisebits; } return(*status); } /*--------------------------------------------------------------------------*/ int ffdkinit(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - name of file to create */ int *status) /* IO - error status */ /* Create and initialize a new FITS file on disk. This routine differs from ffinit in that the input 'name' is literally taken as the name of the disk file to be created, and it does not support CFITSIO's extended filename syntax. */ { if (*status > 0) return(*status); *status = CREATE_DISK_FILE; ffinit(fptr, name,status); return(*status); } /*--------------------------------------------------------------------------*/ int ffinit(fitsfile **fptr, /* O - FITS file pointer */ const char *name, /* I - name of file to create */ int *status) /* IO - error status */ /* Create and initialize a new FITS file. */ { int driver, slen, clobber = 0; char *url; char urltype[MAX_PREFIX_LEN], outfile[FLEN_FILENAME]; char tmplfile[FLEN_FILENAME], compspec[80]; int handle, create_disk_file = 0; if (*status > 0) return(*status); if (*status == CREATE_DISK_FILE) { create_disk_file = 1; *status = 0; } *fptr = 0; /* initialize null file pointer */ if (need_to_initialize) { /* this is called only once */ if (need_to_initialize != 1) { /* This is bad. looks like memory has been corrupted. */ ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!"); ffpmsg("Fatal condition detected in ffinit."); *status = FILE_NOT_CREATED; return(*status); } *status = fits_init_cfitsio(); } if (*status > 0) return(*status); url = (char *) name; while (*url == ' ') /* ignore leading spaces in the filename */ url++; if (*url == '\0') { ffpmsg("Name of file to create is blank. (ffinit)"); return(*status = FILE_NOT_CREATED); } if (create_disk_file) { strcpy(outfile, url); strcpy(urltype, "file://"); tmplfile[0] = '\0'; compspec[0] = '\0'; } else { /* check for clobber symbol, i.e, overwrite existing file */ if (*url == '!') { clobber = TRUE; url++; } else clobber = FALSE; /* parse the output file specification */ ffourl(url, urltype, outfile, tmplfile, compspec, status); if (*status > 0) { ffpmsg("could not parse the output filename: (ffinit)"); ffpmsg(url); return(*status); } } /* find which driver corresponds to the urltype */ *status = urltype2driver(urltype, &driver); if (*status) { ffpmsg("could not find driver for this file: (ffinit)"); ffpmsg(url); return(*status); } /* delete pre-existing file, if asked to do so */ if (clobber) { if (driverTable[driver].remove) (*driverTable[driver].remove)(outfile); } /* call appropriate driver to create the file */ if (driverTable[driver].create) { *status = (*driverTable[driver].create)(outfile, &handle); if (*status) { ffpmsg("failed to create new file (already exists?):"); ffpmsg(url); return(*status); } } else { ffpmsg("cannot create a new file of this type: (ffinit)"); ffpmsg(url); return(*status = FILE_NOT_CREATED); } /* allocate fitsfile structure and initialize = 0 */ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffopen)"); ffpmsg(url); return(*status = MEMORY_ALLOCATION); } /* allocate FITSfile structure and initialize = 0 */ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile)); if (!((*fptr)->Fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for following file: (ffopen)"); ffpmsg(url); free(*fptr); *fptr = 0; return(*status = MEMORY_ALLOCATION); } slen = strlen(url) + 1; slen = maxvalue(slen, 32); /* reserve at least 32 chars */ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */ if ( !(((*fptr)->Fptr)->filename) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for filename: (ffinit)"); ffpmsg(url); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = FILE_NOT_CREATED); } /* mem for headstart array */ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG)); if ( !(((*fptr)->Fptr)->headstart) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for headstart array: (ffinit)"); ffpmsg(url); free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* store the parameters describing the file */ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */ ((*fptr)->Fptr)->filehandle = handle; /* store the file pointer */ ((*fptr)->Fptr)->driver = driver; /* driver number */ strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */ ((*fptr)->Fptr)->filesize = 0; /* physical file size */ ((*fptr)->Fptr)->logfilesize = 0; /* logical file size */ ((*fptr)->Fptr)->writemode = 1; /* read-write mode */ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */ ffldrc(*fptr, 0, IGNORE_EOF, status); /* initialize first record */ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */ /* if template file was given, use it to define structure of new file */ if (tmplfile[0]) ffoptplt(*fptr, tmplfile, status); /* parse and save image compression specification, if given */ if (compspec[0]) ffparsecompspec(*fptr, compspec, status); return(*status); /* successful return */ } /*--------------------------------------------------------------------------*/ /* ffimem == fits_create_memfile */ int ffimem(fitsfile **fptr, /* O - FITS file pointer */ void **buffptr, /* I - address of memory pointer */ size_t *buffsize, /* I - size of buffer, in bytes */ size_t deltasize, /* I - increment for future realloc's */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ int *status) /* IO - error status */ /* Create and initialize a new FITS file in memory */ { int driver, slen; char urltype[MAX_PREFIX_LEN]; int handle; if (*status > 0) return(*status); *fptr = 0; /* initialize null file pointer */ if (need_to_initialize) { /* this is called only once */ if (need_to_initialize != 1) { /* This is bad. looks like memory has been corrupted. */ ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!"); ffpmsg("Fatal condition detected in ffimem."); *status = FILE_NOT_CREATED; return(*status); } *status = fits_init_cfitsio(); } if (*status > 0) return(*status); strcpy(urltype, "memkeep://"); /* URL type for pre-existing memory file */ *status = urltype2driver(urltype, &driver); if (*status > 0) { ffpmsg("could not find driver for pre-existing memory file: (ffimem)"); return(*status); } /* call driver routine to "open" the memory file */ *status = mem_openmem( buffptr, buffsize, deltasize, mem_realloc, &handle); if (*status > 0) { ffpmsg("failed to open pre-existing memory file: (ffimem)"); return(*status); } /* allocate fitsfile structure and initialize = 0 */ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile)); if (!(*fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for memory file: (ffimem)"); return(*status = MEMORY_ALLOCATION); } /* allocate FITSfile structure and initialize = 0 */ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile)); if (!((*fptr)->Fptr)) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate structure for memory file: (ffimem)"); free(*fptr); *fptr = 0; return(*status = MEMORY_ALLOCATION); } slen = 32; /* reserve at least 32 chars */ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */ if ( !(((*fptr)->Fptr)->filename) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for filename: (ffimem)"); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* mem for headstart array */ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG)); if ( !(((*fptr)->Fptr)->headstart) ) { (*driverTable[driver].close)(handle); /* close the file */ ffpmsg("failed to allocate memory for headstart array: (ffinit)"); free( ((*fptr)->Fptr)->filename); free((*fptr)->Fptr); free(*fptr); *fptr = 0; /* return null file pointer */ return(*status = MEMORY_ALLOCATION); } /* store the parameters describing the file */ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */ ((*fptr)->Fptr)->filehandle = handle; /* file handle */ ((*fptr)->Fptr)->driver = driver; /* driver number */ strcpy(((*fptr)->Fptr)->filename, "memfile"); /* dummy filename */ ((*fptr)->Fptr)->filesize = *buffsize; /* physical file size */ ((*fptr)->Fptr)->logfilesize = *buffsize; /* logical file size */ ((*fptr)->Fptr)->writemode = 1; /* read-write mode */ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */ ffldrc(*fptr, 0, IGNORE_EOF, status); /* initialize first record */ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */ return(*status); } /*--------------------------------------------------------------------------*/ int fits_init_cfitsio(void) /* initialize anything that is required before using the CFITSIO routines */ { int status; union u_tag { short ival; char cval[2]; } u; need_to_initialize = 0; /* test for correct byteswapping. */ u.ival = 1; if ((BYTESWAPPED && u.cval[0] != 1) || (BYTESWAPPED == FALSE && u.cval[1] != 1) ) { printf ("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); printf(" Byteswapping is not being done correctly on this system.\n"); printf(" Check the MACHINE and BYTESWAPPED definitions in fitsio2.h\n"); printf(" Please report this problem to the author at\n"); printf(" pence@tetra.gsfc.nasa.gov\n"); printf( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); return(1); } /* test that LONGLONG is an 8 byte integer */ if (sizeof(LONGLONG) != 8) { printf ("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); printf(" CFITSIO did not find an 8-byte long integer data type.\n"); printf(" sizeof(LONGLONG) = %d\n",(int)sizeof(LONGLONG)); printf(" Please report this problem to the author at\n"); printf(" pence@tetra.gsfc.nasa.gov\n"); printf( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); return(1); } /* register the standard I/O drivers that are always available */ /* 1--------------------disk file driver-----------------------*/ status = fits_register_driver("file://", file_init, file_shutdown, file_setoptions, file_getoptions, file_getversion, file_checkfile, file_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the file:// driver (init_cfitsio)"); return(status); } /* 2------------ output temporary memory file driver ----------------*/ status = fits_register_driver("mem://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ NULL, /* open function not allowed */ mem_create, mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the mem:// driver (init_cfitsio)"); return(status); } /* 3--------------input pre-existing memory file driver----------------*/ status = fits_register_driver("memkeep://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ NULL, /* file open driver function is not used */ NULL, /* create function not allowed */ mem_truncate, mem_close_keep, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the memkeep:// driver (init_cfitsio)"); return(status); } /* 4-------------------stdin stream driver----------------------*/ /* the stdin stream is copied to memory then opened in memory */ status = fits_register_driver("stdin://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, stdin_checkfile, stdin_open, NULL, /* create function not allowed */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the stdin:// driver (init_cfitsio)"); return(status); } /* 5-------------------stdin file stream driver----------------------*/ /* the stdin stream is copied to a disk file then the disk file is opened */ status = fits_register_driver("stdinfile://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ stdin_open, NULL, /* create function not allowed */ #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the stdinfile:// driver (init_cfitsio)"); return(status); } /* 6-----------------------stdout stream driver------------------*/ status = fits_register_driver("stdout://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ NULL, /* open function not required */ mem_create, mem_truncate, stdout_close, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the stdout:// driver (init_cfitsio)"); return(status); } /* 7------------------iraf disk file to memory driver -----------*/ status = fits_register_driver("irafmem://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ mem_iraf_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the irafmem:// driver (init_cfitsio)"); return(status); } /* 8------------------raw binary file to memory driver -----------*/ status = fits_register_driver("rawfile://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ mem_rawfile_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the rawfile:// driver (init_cfitsio)"); return(status); } /* 9------------------compressed disk file to memory driver -----------*/ status = fits_register_driver("compress://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ mem_compress_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the compress:// driver (init_cfitsio)"); return(status); } /* 10------------------compressed disk file to memory driver -----------*/ /* Identical to compress://, except it allows READWRITE access */ status = fits_register_driver("compressmem://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ mem_compress_openrw, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the compressmem:// driver (init_cfitsio)"); return(status); } /* 11------------------compressed disk file to disk file driver -------*/ status = fits_register_driver("compressfile://", file_init, file_shutdown, file_setoptions, file_getoptions, file_getversion, NULL, /* checkfile not needed */ file_compress_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the compressfile:// driver (init_cfitsio)"); return(status); } /* 12---create file in memory, then compress it to disk file on close--*/ status = fits_register_driver("compressoutfile://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ NULL, /* open function not allowed */ mem_create_comp, mem_truncate, mem_close_comp, file_remove, /* delete existing compressed disk file */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg( "failed to register the compressoutfile:// driver (init_cfitsio)"); return(status); } /* Register Optional drivers */ #ifdef HAVE_NET_SERVICES /* 13--------------------root driver-----------------------*/ status = fits_register_driver("root://", root_init, root_shutdown, root_setoptions, root_getoptions, root_getversion, NULL, /* checkfile not needed */ root_open, root_create, NULL, /* No truncate possible */ root_close, NULL, /* No remove possible */ root_size, /* no size possible */ root_flush, root_seek, /* Though will always succeed */ root_read, root_write); if (status) { ffpmsg("failed to register the root:// driver (init_cfitsio)"); return(status); } /* 14--------------------http driver-----------------------*/ status = fits_register_driver("http://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, http_checkfile, http_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the http:// driver (init_cfitsio)"); return(status); } /* 15--------------------http file driver-----------------------*/ status = fits_register_driver("httpfile://", file_init, file_shutdown, file_setoptions, file_getoptions, file_getversion, NULL, /* checkfile not needed */ http_file_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the httpfile:// driver (init_cfitsio)"); return(status); } /* 16--------------------http memory driver-----------------------*/ /* same as http:// driver, except memory file can be opened READWRITE */ status = fits_register_driver("httpmem://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, http_checkfile, http_file_open, /* this will simply call http_open */ NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the httpmem:// driver (init_cfitsio)"); return(status); } /* 17--------------------httpcompress file driver-----------------------*/ status = fits_register_driver("httpcompress://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ http_compress_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the httpcompress:// driver (init_cfitsio)"); return(status); } /* 18--------------------ftp driver-----------------------*/ status = fits_register_driver("ftp://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, ftp_checkfile, ftp_open, NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the ftp:// driver (init_cfitsio)"); return(status); } /* 19--------------------ftp file driver-----------------------*/ status = fits_register_driver("ftpfile://", file_init, file_shutdown, file_setoptions, file_getoptions, file_getversion, NULL, /* checkfile not needed */ ftp_file_open, file_create, #ifdef HAVE_FTRUNCATE file_truncate, #else NULL, /* no file truncate function */ #endif file_close, file_remove, file_size, file_flush, file_seek, file_read, file_write); if (status) { ffpmsg("failed to register the ftpfile:// driver (init_cfitsio)"); return(status); } /* 20--------------------ftp mem driver-----------------------*/ /* same as ftp:// driver, except memory file can be opened READWRITE */ status = fits_register_driver("ftpmem://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, ftp_checkfile, ftp_file_open, /* this will simply call ftp_open */ NULL, /* create function not required */ mem_truncate, mem_close_free, NULL, /* remove function not required */ mem_size, NULL, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the ftpmem:// driver (init_cfitsio)"); return(status); } /* 21--------------------ftp compressed file driver------------------*/ status = fits_register_driver("ftpcompress://", mem_init, mem_shutdown, mem_setoptions, mem_getoptions, mem_getversion, NULL, /* checkfile not needed */ ftp_compress_open, 0, /* create function not required */ mem_truncate, mem_close_free, 0, /* remove function not required */ mem_size, 0, /* flush function not required */ mem_seek, mem_read, mem_write); if (status) { ffpmsg("failed to register the ftpcompress:// driver (init_cfitsio)"); return(status); } /* === End of net drivers section === */ #endif /* ==================== SHARED MEMORY DRIVER SECTION ======================= */ #ifdef HAVE_SHMEM_SERVICES /* 22--------------------shared memory driver-----------------------*/ status = fits_register_driver("shmem://", smem_init, smem_shutdown, smem_setoptions, smem_getoptions, smem_getversion, NULL, /* checkfile not needed */ smem_open, smem_create, NULL, /* truncate file not supported yet */ smem_close, smem_remove, smem_size, smem_flush, smem_seek, smem_read, smem_write ); if (status) { ffpmsg("failed to register the shmem:// driver (init_cfitsio)"); return(status); } #endif /* ==================== END OF SHARED MEMORY DRIVER SECTION ================ */ #ifdef HAVE_GSIFTP /* 23--------------------gsiftp driver-----------------------*/ status = fits_register_driver("gsiftp://", gsiftp_init, gsiftp_shutdown, gsiftp_setoptions, gsiftp_getoptions, gsiftp_getversion, gsiftp_checkfile, gsiftp_open, gsiftp_create, #ifdef HAVE_FTRUNCATE gsiftp_truncate, #else NULL, #endif gsiftp_close, NULL, /* remove function not yet implemented */ gsiftp_size, gsiftp_flush, gsiftp_seek, gsiftp_read, gsiftp_write); if (status) { ffpmsg("failed to register the gsiftp:// driver (init_cfitsio)"); return(status); } #endif return(status); } /*--------------------------------------------------------------------------*/ int fits_register_driver(char *prefix, int (*init)(void), int (*shutdown)(void), int (*setoptions)(int option), int (*getoptions)(int *options), int (*getversion)(int *version), int (*checkfile) (char *urltype, char *infile, char *outfile), int (*open)(char *filename, int rwmode, int *driverhandle), int (*create)(char *filename, int *driverhandle), int (*truncate)(int driverhandle, LONGLONG filesize), int (*close)(int driverhandle), int (*fremove)(char *filename), int (*size)(int driverhandle, LONGLONG *size), int (*flush)(int driverhandle), int (*seek)(int driverhandle, LONGLONG offset), int (*read) (int driverhandle, void *buffer, long nbytes), int (*write)(int driverhandle, void *buffer, long nbytes) ) /* register all the functions needed to support an I/O driver */ { int status; if (no_of_drivers < 0 ) { /* This is bad. looks like memory has been corrupted. */ ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!"); ffpmsg("Fatal condition detected in fits_register_driver."); return(TOO_MANY_DRIVERS); } if (no_of_drivers + 1 > MAX_DRIVERS) return(TOO_MANY_DRIVERS); if (prefix == NULL) return(BAD_URL_PREFIX); if (init != NULL) { status = (*init)(); if (status) return(status); } /* fill in data in table */ strncpy(driverTable[no_of_drivers].prefix, prefix, MAX_PREFIX_LEN); driverTable[no_of_drivers].prefix[MAX_PREFIX_LEN - 1] = 0; driverTable[no_of_drivers].init = init; driverTable[no_of_drivers].shutdown = shutdown; driverTable[no_of_drivers].setoptions = setoptions; driverTable[no_of_drivers].getoptions = getoptions; driverTable[no_of_drivers].getversion = getversion; driverTable[no_of_drivers].checkfile = checkfile; driverTable[no_of_drivers].open = open; driverTable[no_of_drivers].create = create; driverTable[no_of_drivers].truncate = truncate; driverTable[no_of_drivers].close = close; driverTable[no_of_drivers].remove = fremove; driverTable[no_of_drivers].size = size; driverTable[no_of_drivers].flush = flush; driverTable[no_of_drivers].seek = seek; driverTable[no_of_drivers].read = read; driverTable[no_of_drivers].write = write; no_of_drivers++; /* increment the number of drivers */ return(0); } /*--------------------------------------------------------------------------*/ int ffiurl(char *url, /* input filename */ char *urltype, /* e.g., 'file://', 'http://', 'mem://' */ char *infilex, /* root filename (may be complete path) */ char *outfile, /* optional output file name */ char *extspec, /* extension spec: +n or [extname, extver] */ char *rowfilterx, /* boolean row filter expression */ char *binspec, /* histogram binning specifier */ char *colspec, /* column or keyword modifier expression */ int *status) /* parse the input URL into its basic components. This routine is big and ugly and should be redesigned someday! */ { return fits_parse_input_filename(url, urltype, infilex, outfile, extspec, rowfilterx, binspec, colspec, 0, status); } /*--------------------------------------------------------------------------*/ int ffifile(char *url, /* input filename */ char *urltype, /* e.g., 'file://', 'http://', 'mem://' */ char *infilex, /* root filename (may be complete path) */ char *outfile, /* optional output file name */ char *extspec, /* extension spec: +n or [extname, extver] */ char *rowfilterx, /* boolean row filter expression */ char *binspec, /* histogram binning specifier */ char *colspec, /* column or keyword modifier expression */ char *pixfilter, /* pixel filter expression */ int *status) /* fits_parse_input_filename parse the input URL into its basic components. This routine is big and ugly and should be redesigned someday! */ { int ii, jj, slen, infilelen, plus_ext = 0, collen; char *ptr1, *ptr2, *ptr3, *tmptr; int hasAt, hasDot, hasOper, followingOper, spaceTerm, rowFilter; int colStart, binStart, pixStart; /* must have temporary variable for these, in case inputs are NULL */ char *infile; char *rowfilter; char *tmpstr; if (*status > 0) return(*status); /* Initialize null strings */ if (infilex) *infilex = '\0'; if (urltype) *urltype = '\0'; if (outfile) *outfile = '\0'; if (extspec) *extspec = '\0'; if (binspec) *binspec = '\0'; if (colspec) *colspec = '\0'; if (rowfilterx) *rowfilterx = '\0'; if (pixfilter) *pixfilter = '\0'; slen = strlen(url); if (slen == 0) /* blank filename ?? */ return(*status); /* allocate memory for 3 strings, each as long as the input url */ infile = (char *) calloc(3, slen + 1); if (!infile) return(*status = MEMORY_ALLOCATION); rowfilter = &infile[slen + 1]; tmpstr = &rowfilter[slen + 1]; ptr1 = url; /* -------------------------------------------------------- */ /* get urltype (e.g., file://, ftp://, http://, etc.) */ /* --------------------------------------------------------- */ if (*ptr1 == '-' && ( *(ptr1 +1) == 0 || *(ptr1 +1) == ' ' || *(ptr1 +1) == '[' || *(ptr1 +1) == '(' ) ) { /* "-" means read file from stdin. Also support "- ", */ /* "-[extname]" and '-(outfile.fits)" but exclude disk file */ /* names that begin with a minus sign, e.g., "-55d33m.fits" */ if (urltype) strcat(urltype, "stdin://"); ptr1++; } else if (!strncasecmp(ptr1, "stdin", 5)) { if (urltype) strcat(urltype, "stdin://"); ptr1 = ptr1 + 5; } else { ptr2 = strstr(ptr1, "://"); ptr3 = strstr(ptr1, "(" ); if (ptr3 && (ptr3 < ptr2) ) { /* the urltype follows a '(' character, so it must apply */ /* to the output file, and is not the urltype of the input file */ ptr2 = 0; /* so reset pointer to zero */ } if (ptr2) /* copy the explicit urltype string */ { if (urltype) strncat(urltype, ptr1, ptr2 - ptr1 + 3); ptr1 = ptr2 + 3; } else if (!strncmp(ptr1, "ftp:", 4) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "ftp://"); ptr1 += 4; } else if (!strncmp(ptr1, "gsiftp:", 7) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "gsiftp://"); ptr1 += 7; } else if (!strncmp(ptr1, "http:", 5) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "http://"); ptr1 += 5; } else if (!strncmp(ptr1, "mem:", 4) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "mem://"); ptr1 += 4; } else if (!strncmp(ptr1, "shmem:", 6) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "shmem://"); ptr1 += 6; } else if (!strncmp(ptr1, "file:", 5) ) { /* the 2 //'s are optional */ if (urltype) strcat(urltype, "file://"); ptr1 += 5; } else /* assume file driver */ { if (urltype) strcat(urltype, "file://"); } } /* ---------------------------------------------------------- If this is a http:// type file, then the cgi file name could include the '[' character, which should not be interpreted as part of CFITSIO's Extended File Name Syntax. Test for this case by seeing if the last character is a ']' or ')'. If it is not, then just treat the whole input string as the file name and do not attempt to interprete the name using the extended filename syntax. ----------------------------------------------------------- */ if (urltype && !strncmp(urltype, "http://", 7) ) { /* test for opening parenthesis or bracket in the file name */ if( strchr(ptr1, '(' ) || strchr(ptr1, '[' ) ) { slen = strlen(ptr1); ptr3 = ptr1 + slen - 1; while (*ptr3 == ' ') /* ignore trailing blanks */ ptr3--; if (*ptr3 != ']' && *ptr3 != ')' ) { /* name doesn't end with a ']' or ')' so don't try */ /* to parse this unusual string (may be cgi string) */ if (infilex) strcpy(infilex, ptr1); free(infile); return(*status); } } } /* ---------------------------------------------------------- Look for VMS style filenames like: disk:[directory.subdirectory]filename.ext, or [directory.subdirectory]filename.ext Check if the first character is a '[' and urltype != stdin or if there is a ':[' string in the remaining url string. If so, then need to move past this bracket character before search for the opening bracket of a filter specification. ----------------------------------------------------------- */ tmptr = ptr1; if (*ptr1 == '[') { if (*url != '-') tmptr = ptr1 + 1; /* this bracket encloses a VMS directory name */ } else { tmptr = strstr(ptr1, ":["); if (tmptr) /* these 2 chars are part of the VMS disk and directory */ tmptr += 2; else tmptr = ptr1; } /* ------------------------ */ /* get the input file name */ /* ------------------------ */ ptr2 = strchr(tmptr, '('); /* search for opening parenthesis ( */ ptr3 = strchr(tmptr, '['); /* search for opening bracket [ */ if (ptr2 == ptr3) /* simple case: no [ or ( in the file name */ { strcat(infile, ptr1); } else if (!ptr3 || /* no bracket, so () enclose output file name */ (ptr2 && (ptr2 < ptr3)) ) /* () enclose output name before bracket */ { strncat(infile, ptr1, ptr2 - ptr1); ptr2++; ptr1 = strchr(ptr2, ')' ); /* search for closing ) */ if (!ptr1) { free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ) */ } if (outfile) strncat(outfile, ptr2, ptr1 - ptr2); /* the opening [ could have been part of output name, */ /* e.g., file(out[compress])[3][#row > 5] */ /* so search again for opening bracket following the closing ) */ ptr3 = strchr(ptr1, '['); } else /* bracket comes first, so there is no output name */ { strncat(infile, ptr1, ptr3 - ptr1); } /* strip off any trailing blanks in the names */ slen = strlen(infile); while ( (--slen) > 0 && infile[slen] == ' ') infile[slen] = '\0'; if (outfile) { slen = strlen(outfile); while ( (--slen) > 0 && outfile[slen] == ' ') outfile[slen] = '\0'; } /* --------------------------------------------- */ /* check if this is an IRAF file (.imh extension */ /* --------------------------------------------- */ if (strstr(infile, ".imh")) { if (urltype) strcpy(urltype, "irafmem://"); } /* --------------------------------------------- */ /* check if the 'filename+n' convention has been */ /* used to specifiy which HDU number to open */ /* --------------------------------------------- */ jj = strlen(infile); for (ii = jj - 1; ii >= 0; ii--) { if (infile[ii] == '+') /* search backwards for '+' sign */ break; } if (ii > 0 && (jj - ii) < 7) /* limit extension numbers to 5 digits */ { infilelen = ii; ii++; ptr1 = infile+ii; /* pointer to start of sequence */ for (; ii < jj; ii++) { if (!isdigit((int) infile[ii] ) ) /* are all the chars digits? */ break; } if (ii == jj) { /* yes, the '+n' convention was used. Copy */ /* the digits to the output extspec string. */ plus_ext = 1; if (extspec) strncpy(extspec, ptr1, jj - infilelen); infile[infilelen] = '\0'; /* delete the extension number */ } } /* -------------------------------------------------------------------- */ /* if '*' was given for the output name expand it to the root file name */ /* -------------------------------------------------------------------- */ if (outfile && outfile[0] == '*') { /* scan input name backwards to the first '/' character */ for (ii = jj - 1; ii >= 0; ii--) { if (infile[ii] == '/' || ii == 0) { strcpy(outfile, &infile[ii + 1]); break; } } } /* ------------------------------------------ */ /* copy strings from local copy to the output */ /* ------------------------------------------ */ if (infilex) strcpy(infilex, infile); /* ---------------------------------------------------------- */ /* if no '[' character in the input string, then we are done. */ /* ---------------------------------------------------------- */ if (!ptr3) { free(infile); return(*status); } /* ------------------------------------------- */ /* see if [ extension specification ] is given */ /* ------------------------------------------- */ if (!plus_ext) /* extension no. not already specified? Then */ /* first brackets must enclose extension name or # */ /* or it encloses a image subsection specification */ /* or a raw binary image specifier */ /* Or, the extension specification may have been */ /* omitted and we have to guess what the user intended */ { ptr1 = ptr3 + 1; /* pointer to first char after the [ */ ptr2 = strchr(ptr1, ']' ); /* search for closing ] */ if (!ptr2) { ffpmsg("input file URL is missing closing bracket ']'"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } /* ---------------------------------------------- */ /* First, test if this is a rawfile specifier */ /* which looks something like: '[ib512,512:2880]' */ /* Test if first character is b,i,j,d,r,f, or u, */ /* and optional second character is b or l, */ /* followed by one or more digits, */ /* finally followed by a ',', ':', or ']' */ /* ---------------------------------------------- */ if (*ptr1 == 'b' || *ptr1 == 'B' || *ptr1 == 'i' || *ptr1 == 'I' || *ptr1 == 'j' || *ptr1 == 'J' || *ptr1 == 'd' || *ptr1 == 'D' || *ptr1 == 'r' || *ptr1 == 'R' || *ptr1 == 'f' || *ptr1 == 'F' || *ptr1 == 'u' || *ptr1 == 'U') { /* next optional character may be a b or l (for Big or Little) */ ptr1++; if (*ptr1 == 'b' || *ptr1 == 'B' || *ptr1 == 'l' || *ptr1 == 'L') ptr1++; if (isdigit((int) *ptr1)) /* must have at least 1 digit */ { while (isdigit((int) *ptr1)) ptr1++; /* skip over digits */ if (*ptr1 == ',' || *ptr1 == ':' || *ptr1 == ']' ) { /* OK, this looks like a rawfile specifier */ if (urltype) { if (strstr(urltype, "stdin") ) strcpy(urltype, "rawstdin://"); else strcpy(urltype, "rawfile://"); } /* append the raw array specifier to infilex */ if (infilex) { strcat(infilex, ptr3); ptr1 = strchr(infilex, ']'); /* find the closing ] char */ if (ptr1) *(ptr1 + 1) = '\0'; /* terminate string after the ] */ } if (extspec) strcpy(extspec, "0"); /* the 0 ext number is implicit */ tmptr = strchr(ptr2 + 1, '[' ); /* search for another [ char */ /* copy any remaining characters into rowfilterx */ if (tmptr && rowfilterx) { strcat(rowfilterx, tmptr + 1); tmptr = strchr(rowfilterx, ']' ); /* search for closing ] */ if (tmptr) *tmptr = '\0'; /* overwrite the ] with null terminator */ } free(infile); /* finished parsing, so return */ return(*status); } } } /* end of rawfile specifier test */ /* -------------------------------------------------------- */ /* Not a rawfile, so next, test if this is an image section */ /* i.e., an integer followed by a ':' or a '*' or '-*' */ /* -------------------------------------------------------- */ ptr1 = ptr3 + 1; /* reset pointer to first char after the [ */ tmptr = ptr1; while (*tmptr == ' ') tmptr++; /* skip leading blanks */ while (isdigit((int) *tmptr)) tmptr++; /* skip over leading digits */ if (*tmptr == ':' || *tmptr == '*' || *tmptr == '-') { /* this is an image section specifier */ strcat(rowfilter, ptr3); /* don't want to assume 0 extension any more; may imply an image extension. if (extspec) strcpy(extspec, "0"); */ } else { /* ----------------------------------------------------------------- Not an image section or rawfile spec so may be an extension spec. Examples of valid extension specifiers: [3] - 3rd extension; 0 = primary array [events] - events extension [events, 2] - events extension, with EXTVER = 2 [events,2] - spaces are optional [events, 3, b] - same as above, plus XTENSION = 'BINTABLE' [PICS; colName(12)] - an image in row 12 of the colName column in the PICS table extension [PICS; colName(exposure > 1000)] - as above, but find image in first row with with exposure column value > 1000. [Rate Table] - extension name can contain spaces! [Rate Table;colName(exposure>1000)] Examples of other types of specifiers (Not extension specifiers) [bin] !!! this is ambiguous, and can't be distinguished from a valid extension specifier [bini X=1:512:16] (also binb, binj, binr, and bind are allowed) [binr (X,Y) = 5] [bin @binfilter.txt] [col Time;rate] [col PI=PHA * 1.1] [col -Time; status] [X > 5] [X>5] [@filter.txt] [StatusCol] !!! this is ambiguous, and can't be distinguished from a valid extension specifier [StatusCol==0] [StatusCol || x>6] [gtifilter()] [regfilter("region.reg")] There will always be some ambiguity between an extension name and a boolean row filtering expression, (as in a couple of the above examples). If there is any doubt, the expression should be treated as an extension specification; The user can always add an explicit expression specifier to override this interpretation. The following decision logic will be used: 1) locate the first token, terminated with a space, comma, semi-colon, or closing bracket. 2) the token is not part of an extension specifier if any of the following is true: - if the token begins with '@' and contains a '.' - if the token contains an operator: = > < || && - if the token begins with "gtifilter(" or "regfilter(" - if the token is terminated by a space and is followed by additional characters (not a ']') AND any of the following: - the token is 'col' - the token is 3 or 4 chars long and begins with 'bin' - the second token begins with an operator: ! = < > | & + - * / % 3) otherwise, the string is assumed to be an extension specifier ----------------------------------------------------------------- */ tmptr = ptr1; while(*tmptr == ' ') tmptr++; hasAt = 0; hasDot = 0; hasOper = 0; followingOper = 0; spaceTerm = 0; rowFilter = 0; colStart = 0; binStart = 0; pixStart = 0; if (*tmptr == '@') /* test for leading @ symbol */ hasAt = 1; if ( !strncasecmp(tmptr, "col ", 4) ) colStart = 1; if ( !strncasecmp(tmptr, "bin", 3) ) binStart = 1; if ( !strncasecmp(tmptr, "pix", 3) ) pixStart = 1; if ( !strncasecmp(tmptr, "gtifilter(", 10) || !strncasecmp(tmptr, "regfilter(", 10) ) { rowFilter = 1; } else { /* parse the first token of the expression */ for (ii = 0; ii < ptr2 - ptr1 + 1; ii++, tmptr++) { if (*tmptr == '.') hasDot = 1; else if (*tmptr == '=' || *tmptr == '>' || *tmptr == '<' || (*tmptr == '|' && *(tmptr+1) == '|') || (*tmptr == '&' && *(tmptr+1) == '&') ) hasOper = 1; else if (*tmptr == ',' || *tmptr == ';' || *tmptr == ']') { break; } else if (*tmptr == ' ') /* a space char? */ { while(*tmptr == ' ') /* skip spaces */ tmptr++; if (*tmptr == ']') /* is this the end? */ break; spaceTerm = 1; /* 1st token is terminated by space */ /* test if this is a column or binning specifier */ if (colStart || (ii <= 4 && (binStart || pixStart)) ) rowFilter = 1; else { /* check if next character is an operator */ if (*tmptr == '=' || *tmptr == '>' || *tmptr == '<' || *tmptr == '|' || *tmptr == '&' || *tmptr == '!' || *tmptr == '+' || *tmptr == '-' || *tmptr == '*' || *tmptr == '/' || *tmptr == '%') followingOper = 1; } break; } } } /* test if this is NOT an extension specifier */ if ( rowFilter || (pixStart && spaceTerm) || (hasAt && hasDot) || hasOper || (spaceTerm && followingOper) ) { /* this is (probably) not an extension specifier */ /* so copy all chars to filter spec string */ strcat(rowfilter, ptr3); } else { /* this appears to be a legit extension specifier */ /* copy the extension specification */ if (extspec) strncat(extspec, ptr1, ptr2 - ptr1); /* copy any remaining chars to filter spec string */ strcat(rowfilter, ptr2 + 1); } } } /* end of if (!plus_ext) */ else { /* ------------------------------------------------------------------ */ /* already have extension, so this must be a filter spec of some sort */ /* ------------------------------------------------------------------ */ strcat(rowfilter, ptr3); } /* strip off any trailing blanks from filter */ slen = strlen(rowfilter); while ( (--slen) >= 0 && rowfilter[slen] == ' ') rowfilter[slen] = '\0'; if (!rowfilter[0]) { free(infile); return(*status); /* nothing left to parse */ } /* ------------------------------------------------ */ /* does the filter contain a binning specification? */ /* ------------------------------------------------ */ ptr1 = strstr(rowfilter, "[bin"); /* search for "[bin" */ if (!ptr1) ptr1 = strstr(rowfilter, "[BIN"); /* search for "[BIN" */ if (!ptr1) ptr1 = strstr(rowfilter, "[Bin"); /* search for "[Bin" */ if (ptr1) { ptr2 = ptr1 + 4; /* end of the '[bin' string */ if (*ptr2 == 'b' || *ptr2 == 'i' || *ptr2 == 'j' || *ptr2 == 'r' || *ptr2 == 'd') ptr2++; /* skip the datatype code letter */ if ( *ptr2 != ' ' && *ptr2 != ']') ptr1 = NULL; /* bin string must be followed by space or ] */ } if (ptr1) { /* found the binning string */ if (binspec) { strcpy(binspec, ptr1 + 1); ptr2 = strchr(binspec, ']'); if (ptr2) /* terminate the binning filter */ { *ptr2 = '\0'; if ( *(--ptr2) == ' ') /* delete trailing spaces */ *ptr2 = '\0'; } else { ffpmsg("input file URL is missing closing bracket ']'"); ffpmsg(rowfilter); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } /* delete the binning spec from the row filter string */ ptr2 = strchr(ptr1, ']'); strcpy(tmpstr, ptr2+1); /* copy any chars after the binspec */ strcpy(ptr1, tmpstr); /* overwrite binspec */ } /* --------------------------------------------------------- */ /* does the filter contain a column selection specification? */ /* --------------------------------------------------------- */ ptr1 = strstr(rowfilter, "[col "); if (!ptr1) { ptr1 = strstr(rowfilter, "[COL "); if (!ptr1) ptr1 = strstr(rowfilter, "[Col "); } if (ptr1) { /* find the end of the column specifier */ ptr2 = ptr1 + 5; while (*ptr2 != ']') { if (*ptr2 == '\0') { ffpmsg("input file URL is missing closing bracket ']'"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } if (*ptr2 == '\'') /* start of a literal string */ { ptr2 = strchr(ptr2 + 1, '\''); /* find closing quote */ if (!ptr2) { ffpmsg ("literal string in input file URL is missing closing single quote"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } if (*ptr2 == '[') /* set of nested square brackets */ { ptr2 = strchr(ptr2 + 1, ']'); /* find closing bracket */ if (!ptr2) { ffpmsg ("nested brackets in input file URL is missing closing bracket"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } ptr2++; /* continue search for the closing bracket character */ } collen = ptr2 - ptr1 - 1; if (colspec) /* copy the column specifier to output string */ { strncpy(colspec, ptr1 + 1, collen); colspec[collen] = '\0'; while (colspec[--collen] == ' ') colspec[collen] = '\0'; /* strip trailing blanks */ } /* delete the column selection spec from the row filter string */ strcpy(tmpstr, ptr2 + 1); /* copy any chars after the colspec */ strcpy(ptr1, tmpstr); /* overwrite binspec */ } /* --------------------------------------------------------- */ /* does the filter contain a pixel filter specification? */ /* --------------------------------------------------------- */ ptr1 = strstr(rowfilter, "[pix"); if (!ptr1) { ptr1 = strstr(rowfilter, "[PIX"); if (!ptr1) ptr1 = strstr(rowfilter, "[Pix"); } if (ptr1) { ptr2 = ptr1 + 4; /* end of the '[pix' string */ if (*ptr2 == 'b' || *ptr2 == 'i' || *ptr2 == 'j' || *ptr2 == 'B' || *ptr2 == 'I' || *ptr2 == 'J' || *ptr2 == 'r' || *ptr2 == 'd' || *ptr2 == 'R' || *ptr2 == 'D') ptr2++; /* skip the datatype code letter */ if (*ptr2 == '1') ptr2++; /* skip the single HDU indicator */ if ( *ptr2 != ' ') ptr1 = NULL; /* pix string must be followed by space */ } if (ptr1) { /* find the end of the pixel filter */ while (*ptr2 != ']') { if (*ptr2 == '\0') { ffpmsg("input file URL is missing closing bracket ']'"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } if (*ptr2 == '\'') /* start of a literal string */ { ptr2 = strchr(ptr2 + 1, '\''); /* find closing quote */ if (!ptr2) { ffpmsg ("literal string in input file URL is missing closing single quote"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } if (*ptr2 == '[') /* set of nested square brackets */ { ptr2 = strchr(ptr2 + 1, ']'); /* find closing bracket */ if (!ptr2) { ffpmsg ("nested brackets in input file URL is missing closing bracket"); free(infile); return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } } ptr2++; /* continue search for the closing bracket character */ } collen = ptr2 - ptr1 - 1; if (pixfilter) /* copy the column specifier to output string */ { strncpy(pixfilter, ptr1 + 1, collen); pixfilter[collen] = '\0'; while (pixfilter[--collen] == ' ') pixfilter[collen] = '\0'; /* strip trailing blanks */ } /* delete the pixel filter from the row filter string */ strcpy(tmpstr, ptr2 + 1); /* copy any chars after the pixel filter */ strcpy(ptr1, tmpstr); /* overwrite binspec */ } /* copy the remaining string to the rowfilter output... should only */ /* contain a rowfilter expression of the form "[expr]" */ if (rowfilterx && rowfilter[0]) { ptr2 = rowfilter + strlen(rowfilter) - 1; if( rowfilter[0]=='[' && *ptr2==']' ) { *ptr2 = '\0'; strcpy(rowfilterx, rowfilter+1); } else { ffpmsg("input file URL lacks valid row filter expression"); *status = URL_PARSE_ERROR; } } free(infile); return(*status); } /*--------------------------------------------------------------------------*/ int ffexist(const char *infile, /* I - input filename or URL */ int *exists, /* O - 2 = a compressed version of file exists */ /* 1 = yes, disk file exists */ /* 0 = no, disk file could not be found */ /* -1 = infile is not a disk file (could */ /* be a http, ftp, gsiftp, smem, or stdin file) */ int *status) /* I/O status */ /* test if the input file specifier is an existing file on disk If the specified file can't be found, it then searches for a compressed version of the file. */ { FILE *diskfile; char rootname[FLEN_FILENAME]; char *ptr1; if (*status > 0) return(*status); /* strip off any extname or filters from the name */ ffrtnm( (char *)infile, rootname, status); ptr1 = strstr(rootname, "://"); if (ptr1 || *rootname == '-') { if (!strncmp(rootname, "file", 4) ) { ptr1 = ptr1 + 3; /* pointer to start of the disk file name */ } else { *exists = -1; /* this is not a disk file */ return (*status); } } else { ptr1 = rootname; } /* see if the disk file exists */ if (file_openfile(ptr1, 0, &diskfile)) { /* no, couldn't open file, so see if there is a compressed version */ if (file_is_compressed(ptr1) ) { *exists = 2; /* a compressed version of the file exists */ } else { *exists = 0; /* neither file nor compressed version exist */ } } else { /* yes, file exists */ *exists = 1; fclose(diskfile); } return(*status); } /*--------------------------------------------------------------------------*/ int ffrtnm(char *url, char *rootname, int *status) /* parse the input URL, returning the root name (filetype://basename). */ { int ii, jj, slen, infilelen; char *ptr1, *ptr2, *ptr3; char urltype[MAX_PREFIX_LEN]; char infile[FLEN_FILENAME]; if (*status > 0) return(*status); ptr1 = url; *rootname = '\0'; *urltype = '\0'; *infile = '\0'; /* get urltype (e.g., file://, ftp://, http://, etc.) */ if (*ptr1 == '-') /* "-" means read file from stdin */ { strcat(urltype, "-"); ptr1++; } else if (!strncmp(ptr1, "stdin", 5) || !strncmp(ptr1, "STDIN", 5)) { strcat(urltype, "-"); ptr1 = ptr1 + 5; } else { ptr2 = strstr(ptr1, "://"); ptr3 = strstr(ptr1, "(" ); if (ptr3 && (ptr3 < ptr2) ) { /* the urltype follows a '(' character, so it must apply */ /* to the output file, and is not the urltype of the input file */ ptr2 = 0; /* so reset pointer to zero */ } if (ptr2) /* copy the explicit urltype string */ { strncat(urltype, ptr1, ptr2 - ptr1 + 3); ptr1 = ptr2 + 3; } else if (!strncmp(ptr1, "ftp:", 4) ) { /* the 2 //'s are optional */ strcat(urltype, "ftp://"); ptr1 += 4; } else if (!strncmp(ptr1, "gsiftp:", 7) ) { /* the 2 //'s are optional */ strcat(urltype, "gsiftp://"); ptr1 += 7; } else if (!strncmp(ptr1, "http:", 5) ) { /* the 2 //'s are optional */ strcat(urltype, "http://"); ptr1 += 5; } else if (!strncmp(ptr1, "mem:", 4) ) { /* the 2 //'s are optional */ strcat(urltype, "mem://"); ptr1 += 4; } else if (!strncmp(ptr1, "shmem:", 6) ) { /* the 2 //'s are optional */ strcat(urltype, "shmem://"); ptr1 += 6; } else if (!strncmp(ptr1, "file:", 5) ) { /* the 2 //'s are optional */ ptr1 += 5; } /* else assume file driver */ } /* get the input file name */ ptr2 = strchr(ptr1, '('); /* search for opening parenthesis ( */ ptr3 = strchr(ptr1, '['); /* search for opening bracket [ */ if (ptr2 == ptr3) /* simple case: no [ or ( in the file name */ { strcat(infile, ptr1); } else if (!ptr3) /* no bracket, so () enclose output file name */ { strncat(infile, ptr1, ptr2 - ptr1); ptr2++; ptr1 = strchr(ptr2, ')' ); /* search for closing ) */ if (!ptr1) return(*status = URL_PARSE_ERROR); /* error, no closing ) */ } else if (ptr2 && (ptr2 < ptr3)) /* () enclose output name before bracket */ { strncat(infile, ptr1, ptr2 - ptr1); ptr2++; ptr1 = strchr(ptr2, ')' ); /* search for closing ) */ if (!ptr1) return(*status = URL_PARSE_ERROR); /* error, no closing ) */ } else /* bracket comes first, so there is no output name */ { strncat(infile, ptr1, ptr3 - ptr1); } /* strip off any trailing blanks in the names */ slen = strlen(infile); for (ii = slen - 1; ii > 0; ii--) { if (infile[ii] == ' ') infile[ii] = '\0'; else break; } /* --------------------------------------------- */ /* check if the 'filename+n' convention has been */ /* used to specifiy which HDU number to open */ /* --------------------------------------------- */ jj = strlen(infile); for (ii = jj - 1; ii >= 0; ii--) { if (infile[ii] == '+') /* search backwards for '+' sign */ break; } if (ii > 0 && (jj - ii) < 5) /* limit extension numbers to 4 digits */ { infilelen = ii; ii++; for (; ii < jj; ii++) { if (!isdigit((int) infile[ii] ) ) /* are all the chars digits? */ break; } if (ii == jj) { /* yes, the '+n' convention was used. */ infile[infilelen] = '\0'; /* delete the extension number */ } } strcat(rootname, urltype); /* construct the root name */ strcat(rootname, infile); return(*status); } /*--------------------------------------------------------------------------*/ int ffourl(char *url, /* I - full input URL */ char *urltype, /* O - url type */ char *outfile, /* O - base file name */ char *tpltfile, /* O - template file name, if any */ char *compspec, /* O - compression specification, if any */ int *status) /* parse the output URL into its basic components. */ { char *ptr1, *ptr2, *ptr3; if (*status > 0) return(*status); if (urltype) *urltype = '\0'; if (outfile) *outfile = '\0'; if (tpltfile) *tpltfile = '\0'; if (compspec) *compspec = '\0'; ptr1 = url; while (*ptr1 == ' ') /* ignore leading blanks */ ptr1++; if ( ( (*ptr1 == '-') && ( *(ptr1 +1) == 0 || *(ptr1 +1) == ' ' ) ) || !strcmp(ptr1, "stdout") || !strcmp(ptr1, "STDOUT")) /* "-" means write to stdout; also support "- " */ /* but exclude disk file names that begin with a minus sign */ /* e.g., "-55d33m.fits" */ { if (urltype) strcpy(urltype, "stdout://"); } else { /* not writing to stdout */ /* get urltype (e.g., file://, ftp://, http://, etc.) */ ptr2 = strstr(ptr1, "://"); if (ptr2) /* copy the explicit urltype string */ { if (urltype) strncat(urltype, ptr1, ptr2 - ptr1 + 3); ptr1 = ptr2 + 3; } else /* assume file driver */ { if (urltype) strcat(urltype, "file://"); } /* look for template file name, enclosed in parenthesis */ ptr2 = strchr(ptr1, '('); /* look for image compression parameters, enclosed in sq. brackets */ ptr3 = strchr(ptr1, '['); if (outfile) { if (ptr2) /* template file was specified */ strncat(outfile, ptr1, ptr2 - ptr1); else if (ptr3) /* compression was specified */ strncat(outfile, ptr1, ptr3 - ptr1); else /* no template file or compression */ strcpy(outfile, ptr1); } if (ptr2) /* template file was specified */ { ptr2++; ptr1 = strchr(ptr2, ')' ); /* search for closing ) */ if (!ptr1) { return(*status = URL_PARSE_ERROR); /* error, no closing ) */ } if (tpltfile) strncat(tpltfile, ptr2, ptr1 - ptr2); } if (ptr3) /* compression was specified */ { ptr3++; ptr1 = strchr(ptr3, ']' ); /* search for closing ] */ if (!ptr1) { return(*status = URL_PARSE_ERROR); /* error, no closing ] */ } if (compspec) strncat(compspec, ptr3, ptr1 - ptr3); } /* check if a .gz compressed output file is to be created */ /* by seeing if the filename ends in '.gz' */ if (urltype && outfile) { if (!strcmp(urltype, "file://") ) { ptr1 = strstr(outfile, ".gz"); if (ptr1) { /* make sure the ".gz" is at the end of the file name */ ptr1 += 3; if (*ptr1 == 0 || *ptr1 == ' ' ) strcpy(urltype, "compressoutfile://"); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffexts(char *extspec, int *extnum, char *extname, int *extvers, int *hdutype, char *imagecolname, char *rowexpress, int *status) { /* Parse the input extension specification string, returning either the extension number or the values of the EXTNAME, EXTVERS, and XTENSION keywords in desired extension. Also return the name of the column containing an image, and an expression to be used to determine which row to use, if present. */ char *ptr1, *ptr2; int slen, nvals; int notint = 1; /* initially assume specified extname is not an integer */ char tmpname[FLEN_VALUE], *loc; *extnum = 0; *extname = '\0'; *extvers = 0; *hdutype = ANY_HDU; *imagecolname = '\0'; *rowexpress = '\0'; if (*status > 0) return(*status); ptr1 = extspec; /* pointer to first char */ while (*ptr1 == ' ') /* skip over any leading blanks */ ptr1++; if (isdigit((int) *ptr1)) /* is the extension specification a number? */ { notint = 0; /* looks like extname may actually be the ext. number */ *extnum = strtol(ptr1, &loc, 10); /* read the string as an integer */ while (*loc == ' ') /* skip over trailing blanks */ loc++; /* check for read error, or junk following the integer */ if ((*loc != '\0' && *loc != ';' ) || (errno == ERANGE) ) { *extnum = 0; notint = 1; /* no, extname was not a simple integer after all */ } if ( *extnum < 0 || *extnum > 99999) { *extnum = 0; /* this is not a reasonable extension number */ ffpmsg("specified extension number is out of range:"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } } /* This logic was too simple, and failed on extnames like '1000TEMP' where it would try to move to the 1000th extension if (isdigit((int) *ptr1)) { sscanf(ptr1, "%d", extnum); if (*extnum < 0 || *extnum > 9999) { *extnum = 0; ffpmsg("specified extension number is out of range:"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } } */ if (notint) { /* not a number, so EXTNAME must be specified, followed by */ /* optional EXTVERS and XTENSION values */ /* don't use space char as end indicator, because there */ /* may be imbedded spaces in the EXTNAME value */ slen = strcspn(ptr1, ",:;"); /* length of EXTNAME */ strncat(extname, ptr1, slen); /* EXTNAME value */ /* now remove any trailing blanks */ while (slen > 0 && *(extname + slen -1) == ' ') { *(extname + slen -1) = '\0'; slen--; } ptr1 += slen; slen = strspn(ptr1, " ,:"); /* skip delimiter characters */ ptr1 += slen; slen = strcspn(ptr1, " ,:;"); /* length of EXTVERS */ if (slen) { nvals = sscanf(ptr1, "%d", extvers); /* EXTVERS value */ if (nvals != 1) { ffpmsg("illegal EXTVER value in input URL:"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } ptr1 += slen; slen = strspn(ptr1, " ,:"); /* skip delimiter characters */ ptr1 += slen; slen = strcspn(ptr1, ";"); /* length of HDUTYPE */ if (slen) { if (*ptr1 == 'b' || *ptr1 == 'B') *hdutype = BINARY_TBL; else if (*ptr1 == 't' || *ptr1 == 'T' || *ptr1 == 'a' || *ptr1 == 'A') *hdutype = ASCII_TBL; else if (*ptr1 == 'i' || *ptr1 == 'I') *hdutype = IMAGE_HDU; else { ffpmsg("unknown type of HDU in input URL:"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } } } else { strcpy(tmpname, extname); ffupch(tmpname); if (!strcmp(tmpname, "PRIMARY") || !strcmp(tmpname, "P") ) *extname = '\0'; /* return extnum = 0 */ } } ptr1 = strchr(ptr1, ';'); if (ptr1) { /* an image is to be opened; the image is contained in a single */ /* cell of a binary table. A column name and an expression to */ /* determine which row to use has been entered. */ ptr1++; /* skip over the ';' delimiter */ while (*ptr1 == ' ') /* skip over any leading blanks */ ptr1++; ptr2 = strchr(ptr1, '('); if (!ptr2) { ffpmsg("illegal specification of image in table cell in input URL:"); ffpmsg(" did not find a row expression enclosed in ( )"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } strncat(imagecolname, ptr1, ptr2 - ptr1); /* copy column name */ ptr2++; /* skip over the '(' delimiter */ while (*ptr2 == ' ') /* skip over any leading blanks */ ptr2++; ptr1 = strchr(ptr2, ')'); if (!ptr2) { ffpmsg("illegal specification of image in table cell in input URL:"); ffpmsg(" missing closing ')' character in row expression"); ffpmsg(extspec); return(*status = URL_PARSE_ERROR); } strncat(rowexpress, ptr2, ptr1 - ptr2); /* row expression */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffextn(char *url, /* I - input filename/URL */ int *extension_num, /* O - returned extension number */ int *status) { /* Parse the input url string and return the number of the extension that CFITSIO would automatically move to if CFITSIO were to open this input URL. The extension numbers are one's based, so 1 = the primary array, 2 = the first extension, etc. The extension number that gets returned is determined by the following algorithm: 1. If the input URL includes a binning specification (e.g. 'myfile.fits[3][bin X,Y]') then the returned extension number will always = 1, since CFITSIO would create a temporary primary image on the fly in this case. The same is true if an image within a single cell of a binary table is opened. 2. Else if the input URL specifies an extension number (e.g., 'myfile.fits[3]' or 'myfile.fits+3') then the specified extension number (+ 1) is returned. 3. Else if the extension name is specified in brackets (e.g., this 'myfile.fits[EVENTS]') then the file will be opened and searched for the extension number. If the input URL is '-' (reading from the stdin file stream) this is not possible and an error will be returned. 4. Else if the URL does not specify an extension (e.g. 'myfile.fits') then a special extension number = -99 will be returned to signal that no extension was specified. This feature is mainly for compatibility with existing FTOOLS software. CFITSIO would open the primary array by default (extension_num = 1) in this case. */ fitsfile *fptr; char urltype[20]; char infile[FLEN_FILENAME]; char outfile[FLEN_FILENAME]; char extspec[FLEN_FILENAME]; char extname[FLEN_FILENAME]; char rowfilter[FLEN_FILENAME]; char binspec[FLEN_FILENAME]; char colspec[FLEN_FILENAME]; char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME]; char *cptr; int extnum, extvers, hdutype, tstatus = 0; if (*status > 0) return(*status); /* parse the input URL into its basic components */ ffiurl(url, urltype, infile, outfile, extspec, rowfilter,binspec, colspec, status); if (*status > 0) return(*status); if (*binspec) /* is there a binning specification? */ { *extension_num = 1; /* a temporary primary array image is created */ return(*status); } if (*extspec) /* is an extension specified? */ { ffexts(extspec, &extnum, extname, &extvers, &hdutype, imagecolname, rowexpress, status); if (*status > 0) return(*status); if (*imagecolname) /* is an image within a table cell being opened? */ { *extension_num = 1; /* a temporary primary array image is created */ return(*status); } if (*extname) { /* have to open the file to search for the extension name (curses!) */ if (!strcmp(urltype, "stdin://")) /* opening stdin would destroying it! */ return(*status = URL_PARSE_ERROR); /* First, strip off any filtering specification */ strcpy(infile, url); cptr = strchr(infile, ']'); /* locate the closing bracket */ if (!cptr) { return(*status = URL_PARSE_ERROR); } else { cptr++; *cptr = '\0'; /* terminate URl after the extension spec */ } if (ffopen(&fptr, infile, READONLY, status) > 0) /* open the file */ { ffclos(fptr, &tstatus); return(*status); } ffghdn(fptr, &extnum); /* where am I in the file? */ *extension_num = extnum; ffclos(fptr, status); return(*status); } else { *extension_num = extnum + 1; /* return the specified number (+ 1) */ return(*status); } } else { *extension_num = -99; /* no specific extension was specified */ /* defaults to primary array */ return(*status); } } /*--------------------------------------------------------------------------*/ int ffurlt(fitsfile *fptr, char *urlType, int *status) /* return the prefix string associated with the driver in use by the fitsfile pointer fptr */ { strcpy(urlType, driverTable[fptr->Fptr->driver].prefix); return(*status); } /*--------------------------------------------------------------------------*/ int ffimport_file( char *filename, /* Text file to read */ char **contents, /* Pointer to pointer to hold file */ int *status ) /* CFITSIO error code */ /* Read and concatenate all the lines from the given text file. User must free the pointer returned in contents. Pointer is guaranteed to hold 2 characters more than the length of the text... allows the calling routine to append (or prepend) a newline (or quotes?) without reallocating memory. */ { int allocLen, totalLen, llen, eoline; char *lines,line[256]; FILE *aFile; if( *status > 0 ) return( *status ); totalLen = 0; allocLen = 1024; lines = (char *)malloc( allocLen * sizeof(char) ); if( !lines ) { ffpmsg("Couldn't allocate memory to hold ASCII file contents."); return(*status = MEMORY_ALLOCATION ); } lines[0] = '\0'; if( (aFile = fopen( filename, "r" ))==NULL ) { sprintf(line,"Could not open ASCII file %s.",filename); ffpmsg(line); free( lines ); return(*status = FILE_NOT_OPENED); } while( fgets(line,256,aFile)!=NULL ) { llen = strlen(line); if ((llen > 1) && (line[0] == '/' && line[1] == '/')) continue; /* skip comment lines begging with // */ eoline = 0; /* replace CR and newline chars at end of line with nulls */ if ((llen > 0) && (line[llen-1]=='\n' || line[llen-1] == '\r')) { line[--llen] = '\0'; eoline = 1; /* found an end of line character */ if ((llen > 0) && (line[llen-1]=='\n' || line[llen-1] == '\r')) { line[--llen] = '\0'; } } if( totalLen + llen + 3 >= allocLen ) { allocLen += 256; lines = (char *)realloc(lines, allocLen * sizeof(char) ); if( ! lines ) { ffpmsg("Couldn't allocate memory to hold ASCII file contents."); *status = MEMORY_ALLOCATION; break; } } strcpy( lines+totalLen, line ); totalLen += llen; if (eoline) { strcpy( lines+totalLen, " "); /* add a space between lines */ totalLen += 1; } } fclose(aFile); *contents = lines; return( *status ); } /*--------------------------------------------------------------------------*/ int fits_get_token(char **ptr, char *delimiter, char *token, int *isanumber) /* O - is this token a number? */ /* parse off the next token, delimited by a character in 'delimiter', from the input ptr string; increment *ptr to the end of the token. Returns the length of the token, not including the delimiter char; */ { int slen, ii; *token = '\0'; while (**ptr == ' ') /* skip over leading blanks */ (*ptr)++; slen = strcspn(*ptr, delimiter); /* length of next token */ if (slen) { strncat(token, *ptr, slen); /* copy token */ (*ptr) += slen; /* skip over the token */ if (isanumber) { *isanumber = 1; for (ii = 0; ii < slen; ii++) { if ( !isdigit((int) token[ii]) && token[ii] != '.' && token[ii] != '-' && token[ii] != '+' && token[ii] != 'E' && token[ii] != 'e') { *isanumber = 0; break; } } } } return(slen); } /*---------------------------------------------------------------------------*/ char *fits_split_names( char *list) /* I - input list of names */ { /* A sequence of calls to fits_split_names will split the input string into name tokens. The string typically contains a list of file or column names. The names must be delimited by a comma and/or spaces. This routine ignores spaces and commas that occur within parentheses, brackets, or curly brackets. It also strips any leading and trailing blanks from the returned name. This routine is similar to the ANSI C 'strtok' function: The first call to fits_split_names has a non-null input string. It finds the first name in the string and terminates it by overwriting the next character of the string with a '\0' and returns a pointer to the name. Each subsequent call, indicated by a NULL value of the input string, returns the next name, searching from just past the end of the previous name. It returns NULL when no further names are found. The following line illustrates how a string would be split into 3 names: myfile[1][bin (x,y)=4], file2.fits file3.fits ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ 1st name 2nd name 3rd name */ int depth = 0; char *start; static char *ptr; if (list) /* reset ptr if a string is given */ ptr = list; while (*ptr == ' ')ptr++; /* skip leading white space */ if (*ptr == '\0')return(0); /* no remaining file names */ start = ptr; while (*ptr != '\0') { if ((*ptr == '[') || (*ptr == '(') || (*ptr == '{')) depth ++; else if ((*ptr == '}') || (*ptr == ')') || (*ptr == ']')) depth --; else if ((depth == 0) && (*ptr == ',' || *ptr == ' ')) { *ptr = '\0'; /* terminate the filename here */ ptr++; /* save pointer to start of next filename */ break; } ptr++; } return(start); } /*--------------------------------------------------------------------------*/ int urltype2driver(char *urltype, int *driver) /* compare input URL with list of known drivers, returning the matching driver numberL. */ { int ii; /* find matching driver; search most recent drivers first */ for (ii=no_of_drivers - 1; ii >= 0; ii--) { if (0 == strcmp(driverTable[ii].prefix, urltype)) { *driver = ii; return(0); } } return(NO_MATCHING_DRIVER); } /*--------------------------------------------------------------------------*/ int ffclos(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* close the FITS file by completing the current HDU, flushing it to disk, then calling the system dependent routine to physically close the FITS file */ { int tstatus = NO_CLOSE_ERROR, zerostatus = 0; if (!fptr) return(*status = NULL_INPUT_PTR); else if ((fptr->Fptr)->validcode != VALIDSTRUC) /* check for magic value */ return(*status = BAD_FILEPTR); /* close and flush the current HDU */ if (*status > 0) ffchdu(fptr, &tstatus); /* turn off the error message from ffchdu */ else ffchdu(fptr, status); ((fptr->Fptr)->open_count)--; /* decrement usage counter */ if ((fptr->Fptr)->open_count == 0) /* if no other files use structure */ { ffflsh(fptr, TRUE, status); /* flush and disassociate IO buffers */ /* call driver function to actually close the file */ if ( (*driverTable[(fptr->Fptr)->driver].close)((fptr->Fptr)->filehandle) ) { if (*status <= 0) { *status = FILE_NOT_CLOSED; /* report if no previous error */ ffpmsg("failed to close the following file: (ffclos)"); ffpmsg((fptr->Fptr)->filename); } } fits_clear_Fptr( fptr->Fptr, status); /* clear Fptr address */ free((fptr->Fptr)->headstart); /* free memory for headstart array */ free((fptr->Fptr)->filename); /* free memory for the filename */ (fptr->Fptr)->filename = 0; (fptr->Fptr)->validcode = 0; /* magic value to indicate invalid fptr */ free(fptr->Fptr); /* free memory for the FITS file structure */ free(fptr); /* free memory for the FITS file structure */ } else { /* to minimize the fallout from any previous error (e.g., trying to open a non-existent extension in a already opened file), always call ffflsh with status = 0. */ /* just flush the buffers, don't disassociate them */ if (*status > 0) ffflsh(fptr, FALSE, &zerostatus); else ffflsh(fptr, FALSE, status); free(fptr); /* free memory for the FITS file structure */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffdelt(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* close and DELETE the FITS file. */ { char *basename; int slen, tstatus = 0; if (!fptr) return(*status = NULL_INPUT_PTR); else if ((fptr->Fptr)->validcode != VALIDSTRUC) /* check for magic value */ return(*status = BAD_FILEPTR); ffchdu(fptr, status); /* close the current HDU, ignore any errors */ ffflsh(fptr, TRUE, status); /* flush and disassociate IO buffers */ /* call driver function to actually close the file */ if ( (*driverTable[(fptr->Fptr)->driver].close)((fptr->Fptr)->filehandle) ) { if (*status <= 0) { *status = FILE_NOT_CLOSED; /* report error if no previous error */ ffpmsg("failed to close the following file: (ffdelt)"); ffpmsg((fptr->Fptr)->filename); } } /* call driver function to actually delete the file */ if ( (driverTable[(fptr->Fptr)->driver].remove) ) { /* parse the input URL to get the base filename */ slen = strlen((fptr->Fptr)->filename); basename = (char *) malloc(slen +1); if (!basename) return(*status = MEMORY_ALLOCATION); ffiurl((fptr->Fptr)->filename, NULL, basename, NULL, NULL, NULL, NULL, NULL, &tstatus); if ((*driverTable[(fptr->Fptr)->driver].remove)(basename)) { ffpmsg("failed to delete the following file: (ffdelt)"); ffpmsg((fptr->Fptr)->filename); if (!(*status)) *status = FILE_NOT_CLOSED; } free(basename); } fits_clear_Fptr( fptr->Fptr, status); /* clear Fptr address */ free((fptr->Fptr)->headstart); /* free memory for headstart array */ free((fptr->Fptr)->filename); /* free memory for the filename */ (fptr->Fptr)->filename = 0; (fptr->Fptr)->validcode = 0; /* magic value to indicate invalid fptr */ free(fptr->Fptr); /* free memory for the FITS file structure */ free(fptr); /* free memory for the FITS file structure */ return(*status); } /*--------------------------------------------------------------------------*/ int fftrun( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG filesize, /* I - size to truncate the file */ int *status) /* O - error status */ /* low level routine to truncate a file to a new smaller size. */ { if (driverTable[(fptr->Fptr)->driver].truncate) { ffflsh(fptr, FALSE, status); /* flush all the buffers first */ (fptr->Fptr)->filesize = filesize; (fptr->Fptr)->logfilesize = filesize; (fptr->Fptr)->bytepos = filesize; ffbfeof(fptr, status); /* eliminate any buffers beyond current EOF */ return (*status = (*driverTable[(fptr->Fptr)->driver].truncate)((fptr->Fptr)->filehandle, filesize) ); } else return(*status); } /*--------------------------------------------------------------------------*/ int ffflushx( FITSfile *fptr) /* I - FITS file pointer */ /* low level routine to flush internal file buffers to the file. */ { if (driverTable[fptr->driver].flush) return ( (*driverTable[fptr->driver].flush)(fptr->filehandle) ); else return(0); /* no flush function defined for this driver */ } /*--------------------------------------------------------------------------*/ int ffseek( FITSfile *fptr, /* I - FITS file pointer */ LONGLONG position) /* I - byte position to seek to */ /* low level routine to seek to a position in a file. */ { return( (*driverTable[fptr->driver].seek)(fptr->filehandle, position) ); } /*--------------------------------------------------------------------------*/ int ffwrite( FITSfile *fptr, /* I - FITS file pointer */ long nbytes, /* I - number of bytes to write */ void *buffer, /* I - buffer to write */ int *status) /* O - error status */ /* low level routine to write bytes to a file. */ { if ( (*driverTable[fptr->driver].write)(fptr->filehandle, buffer, nbytes) ) { ffpmsg("Error writing data buffer to file:"); ffpmsg(fptr->filename); *status = WRITE_ERROR; } return(*status); } /*--------------------------------------------------------------------------*/ int ffread( FITSfile *fptr, /* I - FITS file pointer */ long nbytes, /* I - number of bytes to read */ void *buffer, /* O - buffer to read into */ int *status) /* O - error status */ /* low level routine to read bytes from a file. */ { int readstatus; readstatus = (*driverTable[fptr->driver].read)(fptr->filehandle, buffer, nbytes); if (readstatus == END_OF_FILE) *status = END_OF_FILE; else if (readstatus > 0) { ffpmsg("Error reading data buffer from file:"); ffpmsg(fptr->filename); *status = READ_ERROR; } return(*status); } /*--------------------------------------------------------------------------*/ int fftplt(fitsfile **fptr, /* O - FITS file pointer */ const char *filename, /* I - name of file to create */ const char *tempname, /* I - name of template file */ int *status) /* IO - error status */ /* Create and initialize a new FITS file based on a template file. Uses C fopen and fgets functions. */ { if (*status > 0) return(*status); if ( ffinit(fptr, filename, status) ) /* create empty file */ return(*status); ffoptplt(*fptr, tempname, status); /* open and use template */ return(*status); } /*--------------------------------------------------------------------------*/ int ffoptplt(fitsfile *fptr, /* O - FITS file pointer */ const char *tempname, /* I - name of template file */ int *status) /* IO - error status */ /* open template file and use it to create new file */ { fitsfile *tptr; int tstatus = 0, nkeys, nadd, ii; char card[FLEN_CARD]; if (*status > 0) return(*status); if (tempname == NULL || *tempname == '\0') /* no template file? */ return(*status); /* try opening template */ ffopen(&tptr, (char *) tempname, READONLY, &tstatus); if (tstatus) /* not a FITS file, so treat it as an ASCII template */ { ffxmsg(2, card); /* clear the error message */ fits_execute_template(fptr, (char *) tempname, status); ffmahd(fptr, 1, 0, status); /* move back to the primary array */ return(*status); } else /* template is a valid FITS file */ { ffmahd(tptr, 1, NULL, status); /* make sure we are at the beginning */ while (*status <= 0) { ffghsp(tptr, &nkeys, &nadd, status); /* get no. of keywords */ for (ii = 1; ii <= nkeys; ii++) /* copy keywords */ { ffgrec(tptr, ii, card, status); ffprec(fptr, card, status); } ffmrhd(tptr, 1, 0, status); /* move to next HDU until error */ ffcrhd(fptr, status); /* create empty new HDU in output file */ } if (*status == END_OF_FILE) { *status = 0; /* expected error condition */ } ffclos(tptr, status); /* close the template file */ } ffmahd(fptr, 1, 0, status); /* move to the primary array */ return(*status); } /*--------------------------------------------------------------------------*/ void ffrprt( FILE *stream, int status) /* Print out report of cfitsio error status and messages on the error stack. Uses C FILE stream. */ { char status_str[FLEN_STATUS], errmsg[FLEN_ERRMSG]; if (status) { fits_get_errstatus(status, status_str); /* get the error description */ fprintf(stream, "\nFITSIO status = %d: %s\n", status, status_str); while ( fits_read_errmsg(errmsg) ) /* get error stack messages */ fprintf(stream, "%s\n", errmsg); } return; } /*--------------------------------------------------------------------------*/ int pixel_filter_helper( fitsfile **fptr, /* IO - pointer to input image; on output it */ /* points to the new image */ char *outfile, /* I - name for output file */ char *expr, /* I - Image filter expression */ int *status) { PixelFilter filter = { 0 }; char * DEFAULT_TAG = "X"; int ii, hdunum; int singleHDU = 0; filter.count = 1; filter.ifptr = fptr; filter.tag = &DEFAULT_TAG; /* create new empty file for result */ if (ffinit(&filter.ofptr, outfile, status) > 0) { ffpmsg("failed to create output file for pixel filter:"); ffpmsg(outfile); return(*status); } fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */ expr += 3; /* skip 'pix' */ switch (expr[0]) { case 'b': case 'B': filter.bitpix = BYTE_IMG; break; case 'i': case 'I': filter.bitpix = SHORT_IMG; break; case 'j': case 'J': filter.bitpix = LONG_IMG; break; case 'r': case 'R': filter.bitpix = FLOAT_IMG; break; case 'd': case 'D': filter.bitpix = DOUBLE_IMG; break; } if (filter.bitpix) /* skip bitpix indicator */ ++expr; if (*expr == '1') { ++expr; singleHDU = 1; } if (*expr != ' ') { ffpmsg("pixel filtering expression not space separated:"); ffpmsg(expr); } while (*expr == ' ') ++expr; /* copy all preceding extensions to the output file */ for (ii = 1; !singleHDU && ii < hdunum; ii++) { fits_movabs_hdu(*fptr, ii, NULL, status); if (fits_copy_hdu(*fptr, filter.ofptr, 0, status) > 0) { ffclos(filter.ofptr, status); return(*status); } } /* move back to the original HDU position */ fits_movabs_hdu(*fptr, hdunum, NULL, status); filter.expression = expr; if (fits_pixel_filter(&filter, status)) { ffpmsg("failed to execute image filter:"); ffpmsg(expr); ffclos(filter.ofptr, status); return(*status); } /* copy any remaining HDUs to the output file */ for (ii = hdunum + 1; !singleHDU; ii++) { if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0) break; fits_copy_hdu(*fptr, filter.ofptr, 0, status); } if (*status == END_OF_FILE) *status = 0; /* got the expected EOF error; reset = 0 */ else if (*status > 0) { ffclos(filter.ofptr, status); return(*status); } /* close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = filter.ofptr; /* reset the pointer to the new table */ /* move back to the image subsection */ if (ii - 1 != hdunum) fits_movabs_hdu(*fptr, hdunum, NULL, status); return(*status); } indi-0.5/src/cfitsio/getkey.c0000644000175000017500000033025510610474375014013 0ustar jrjr/* This file, getkey.c, contains routines that read keywords from */ /* a FITS header. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include /* stddef.h is apparently needed to define size_t */ #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffghsp(fitsfile *fptr, /* I - FITS file pointer */ int *nexist, /* O - number of existing keywords in header */ int *nmore, /* O - how many more keywords will fit */ int *status) /* IO - error status */ /* returns the number of existing keywords (not counting the END keyword) and the number of more keyword that will fit in the current header without having to insert more FITS blocks. */ { if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); *nexist = (int) (( ((fptr->Fptr)->headend) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) ) / 80); if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if (nmore) *nmore = -1; /* data not written yet, so room for any keywords */ } else { /* calculate space available between the data and the END card */ if (nmore) *nmore = (int) (((fptr->Fptr)->datastart - (fptr->Fptr)->headend) / 80 - 1); } return(*status); } /*--------------------------------------------------------------------------*/ int ffghps(fitsfile *fptr, /* I - FITS file pointer */ int *nexist, /* O - number of existing keywords in header */ int *position, /* O - position of next keyword to be read */ int *status) /* IO - error status */ /* return the number of existing keywords and the position of the next keyword that will be read. */ { if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); *nexist = (int) (( ((fptr->Fptr)->headend) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) ) / 80); *position = (int) (( ((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) ) / 80 + 1); return(*status); } /*--------------------------------------------------------------------------*/ int ffnchk(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* function returns the position of the first null character (ASCII 0), if any, in the current header. Null characters are illegal, but the other CFITSIO routines that read the header will not detect this error, because the null gets interpreted as a normal end of string character. */ { long ii, nblock; LONGLONG bytepos; int length, nullpos; char block[2881]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { return(0); /* Don't check a file that is just being created. */ /* It cannot contain nulls since CFITSIO wrote it. */ } else { /* calculate number of blocks in the header */ nblock = (long) (( (fptr->Fptr)->datastart - (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) / 2880); } bytepos = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]; ffmbyt(fptr, bytepos, REPORT_EOF, status); /* move to read pos. */ block[2880] = '\0'; for (ii = 0; ii < nblock; ii++) { if (ffgbyt(fptr, 2880, block, status) > 0) return(0); /* read error of some sort */ length = strlen(block); if (length != 2880) { nullpos = (ii * 2880) + length + 1; return(nullpos); } } return(0); } /*--------------------------------------------------------------------------*/ int ffmaky(fitsfile *fptr, /* I - FITS file pointer */ int nrec, /* I - one-based keyword number to move to */ int *status) /* IO - error status */ { /* move pointer to the specified absolute keyword position. E.g. this keyword will then be read by the next call to ffgnky. */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] + ( (nrec - 1) * 80); return(*status); } /*--------------------------------------------------------------------------*/ int ffmrky(fitsfile *fptr, /* I - FITS file pointer */ int nmove, /* I - relative number of keywords to move */ int *status) /* IO - error status */ { /* move pointer to the specified keyword position relative to the current position. E.g. this keyword will then be read by the next call to ffgnky. */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->nextkey += (nmove * 80); return(*status); } /*--------------------------------------------------------------------------*/ int ffgnky(fitsfile *fptr, /* I - FITS file pointer */ char *card, /* O - card string */ int *status) /* IO - error status */ /* read the next keyword from the header - used internally by cfitsio */ { int jj, nrec; LONGLONG bytepos, endhead; char message[FLEN_ERRMSG]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); card[0] = '\0'; /* make sure card is terminated, even affer read error */ /* Check that nextkey points to a legal keyword position. Note that headend is the current end of the header, i.e., the position where a new keyword would be appended, however, if there are more than 1 FITS block worth of blank keywords at the end of the header (36 keywords per 2880 byte block) then the actual physical END card must be located at a starting position which is just 2880 bytes prior to the start of the data unit. */ bytepos = (fptr->Fptr)->nextkey; endhead = maxvalue( ((fptr->Fptr)->headend), ((fptr->Fptr)->datastart - 2880) ); /* nextkey must be < endhead and > than headstart */ if (bytepos > endhead || bytepos < (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) { nrec= (int) ((bytepos - (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]) / 80 + 1); sprintf(message, "Cannot get keyword number %d. It does not exist.", nrec); ffpmsg(message); return(*status = KEY_OUT_BOUNDS); } ffmbyt(fptr, bytepos, REPORT_EOF, status); /* move to read pos. */ card[80] = '\0'; /* make sure card is terminate, even if ffgbyt fails */ if (ffgbyt(fptr, 80, card, status) <= 0) { (fptr->Fptr)->nextkey += 80; /* increment pointer to next keyword */ /* strip off trailing blanks with terminated string */ jj = 79; while (jj >= 0 && card[jj] == ' ') jj--; card[jj + 1] = '\0'; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgnxk( fitsfile *fptr, /* I - FITS file pointer */ char **inclist, /* I - list of included keyword names */ int ninc, /* I - number of names in inclist */ char **exclist, /* I - list of excluded keyword names */ int nexc, /* I - number of names in exclist */ char *card, /* O - first matching keyword */ int *status) /* IO - error status */ /* Return the next keyword that matches one of the names in inclist but does not match any of the names in exclist. The search goes from the current position to the end of the header, only. Wild card characters may be used in the name lists ('*', '?' and '#'). */ { int casesn, match, exact, namelen; long ii, jj; char keybuf[FLEN_CARD], keyname[FLEN_KEYWORD]; card[0] = '\0'; if (*status > 0) return(*status); casesn = FALSE; /* get next card, and return with an error if hit end of header */ while( ffgcrd(fptr, "*", keybuf, status) <= 0) { ffgknm(keybuf, keyname, &namelen, status); /* get the keyword name */ /* does keyword match any names in the include list? */ for (ii = 0; ii < ninc; ii++) { ffcmps(inclist[ii], keyname, casesn, &match, &exact); if (match) { /* does keyword match any names in the exclusion list? */ jj = -1; while ( ++jj < nexc ) { ffcmps(exclist[jj], keyname, casesn, &match, &exact); if (match) break; } if (jj >= nexc) { /* not in exclusion list, so return this keyword */ strcat(card, keybuf); return(*status); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgky( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ char *keyname, /* I - name of keyword to read */ void *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the keyword value and comment from the FITS header. Reads a keyword value with the datatype specified by the 2nd argument. */ { long longval; double doubleval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TSTRING) { ffgkys(fptr, keyname, (char *) value, comm, status); } else if (datatype == TBYTE) { if (ffgkyj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > UCHAR_MAX || longval < 0) *status = NUM_OVERFLOW; else *(unsigned char *) value = (unsigned char) longval; } } else if (datatype == TSBYTE) { if (ffgkyj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > 127 || longval < -128) *status = NUM_OVERFLOW; else *(signed char *) value = (signed char) longval; } } else if (datatype == TUSHORT) { if (ffgkyj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > USHRT_MAX || longval < 0) *status = NUM_OVERFLOW; else *(unsigned short *) value = (unsigned short) longval; } } else if (datatype == TSHORT) { if (ffgkyj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > SHRT_MAX || longval < SHRT_MIN) *status = NUM_OVERFLOW; else *(short *) value = (short) longval; } } else if (datatype == TUINT) { if (ffgkyj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > (long) UINT_MAX || longval < 0) *status = NUM_OVERFLOW; else *(unsigned int *) value = longval; } } else if (datatype == TINT) { if (ffgkyj(fptr, keyname, &longval, comm, status) <= 0) { if (longval > INT_MAX || longval < INT_MIN) *status = NUM_OVERFLOW; else *(int *) value = longval; } } else if (datatype == TLOGICAL) { ffgkyl(fptr, keyname, (int *) value, comm, status); } else if (datatype == TULONG) { if (ffgkyd(fptr, keyname, &doubleval, comm, status) <= 0) { if (doubleval > (double) ULONG_MAX || doubleval < 0) *status = NUM_OVERFLOW; else *(unsigned long *) value = (unsigned long) doubleval; } } else if (datatype == TLONG) { ffgkyj(fptr, keyname, (long *) value, comm, status); } else if (datatype == TLONGLONG) { ffgkyjj(fptr, keyname, (LONGLONG *) value, comm, status); } else if (datatype == TFLOAT) { ffgkye(fptr, keyname, (float *) value, comm, status); } else if (datatype == TDOUBLE) { ffgkyd(fptr, keyname, (double *) value, comm, status); } else if (datatype == TCOMPLEX) { ffgkyc(fptr, keyname, (float *) value, comm, status); } else if (datatype == TDBLCOMPLEX) { ffgkym(fptr, keyname, (double *) value, comm, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgkey( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ char *keyval, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the keyword value and comment. The value is just the literal string of characters in the value field of the keyword. In the case of a string valued keyword, the returned value includes the leading and closing quote characters. The value may be up to 70 characters long, and the comment may be up to 72 characters long. If the keyword has no value (no equal sign in column 9) then a null value is returned. */ { char card[FLEN_CARD]; keyval[0] = '\0'; if (comm) comm[0] = '\0'; if (*status > 0) return(*status); if (ffgcrd(fptr, keyname, card, status) > 0) /* get the 80-byte card */ return(*status); ffpsvc(card, keyval, comm, status); /* parse the value and comment */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgrec( fitsfile *fptr, /* I - FITS file pointer */ int nrec, /* I - number of keyword to read */ char *card, /* O - keyword card */ int *status) /* IO - error status */ /* Read (get) the nrec-th keyword, returning the entire keyword card up to 80 characters long. The first keyword in the header has nrec = 1, not 0. The returned card value is null terminated with any trailing blank characters removed. If nrec = 0, then this routine simply moves the current header pointer to the top of the header. */ { if (*status > 0) return(*status); if (nrec == 0) { ffmaky(fptr, 1, status); /* simply move to beginning of header */ card[0] = '\0'; /* and return null card */ } else if (nrec > 0) { ffmaky(fptr, nrec, status); ffgnky(fptr, card, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcrd( fitsfile *fptr, /* I - FITS file pointer */ char *name, /* I - name of keyword to read */ char *card, /* O - keyword card */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the entire keyword card up to 80 characters long. The first keyword in the header has nrec = 1, not 0. The returned card value is null terminated with any trailing blank characters removed. If the input name contains wild cards ('?' matches any single char and '*' matches any sequence of chars, # matches any string of decimal digits) then the search ends once the end of header is reached and does not automatically resume from the top of the header. */ { int nkeys, nextkey, ntodo, namelen, namelen_limit, namelenminus1, cardlen; int ii = 0, jj, kk, wild, match, exact, hier = 0; char keyname[FLEN_KEYWORD], cardname[FLEN_KEYWORD]; char *ptr1, *ptr2, *gotstar; if (*status > 0) return(*status); *keyname = '\0'; while (name[ii] == ' ') /* skip leading blanks in name */ ii++; strncat(keyname, &name[ii], FLEN_KEYWORD - 1); namelen = strlen(keyname); while (namelen > 0 && keyname[namelen - 1] == ' ') namelen--; /* ignore trailing blanks in name */ keyname[namelen] = '\0'; /* terminate the name */ for (ii=0; ii < namelen; ii++) keyname[ii] = toupper(keyname[ii]); /* make upper case */ if (FSTRNCMP("HIERARCH", keyname, 8) == 0) { if (namelen == 8) { /* special case: just looking for any HIERARCH keyword */ hier = 1; } else { /* ignore the leading HIERARCH and look for the 'real' name */ /* starting with first non-blank character following HIERARCH */ ptr1 = keyname; ptr2 = &keyname[8]; while(*ptr2 == ' ') ptr2++; namelen = 0; while(*ptr2) { *ptr1 = *ptr2; ptr1++; ptr2++; namelen++; } *ptr1 = '\0'; } } /* does input name contain wild card chars? ('?', '*', or '#') */ /* wild cards are currently not supported with HIERARCH keywords */ namelen_limit = namelen; gotstar = 0; if (namelen < 9 && (strchr(keyname,'?') || (gotstar = strchr(keyname,'*')) || strchr(keyname,'#')) ) { wild = 1; /* if we found a '*' wild card in the name, there might be */ /* more than one. Support up to 2 '*' in the template. */ /* Thus we need to compare keywords whose names have at least */ /* namelen - 2 characters. */ if (gotstar) namelen_limit -= 2; } else wild = 0; ffghps(fptr, &nkeys, &nextkey, status); /* get no. keywords and position */ namelenminus1 = maxvalue(namelen - 1, 1); ntodo = nkeys - nextkey + 1; /* first, read from next keyword to end */ for (jj=0; jj < 2; jj++) { for (kk = 0; kk < ntodo; kk++) { ffgnky(fptr, card, status); /* get next keyword */ if (hier) { if (FSTRNCMP("HIERARCH", card, 8) == 0) return(*status); /* found a HIERARCH keyword */ } else { ffgknm(card, cardname, &cardlen, status); /* get the keyword name */ if (cardlen >= namelen_limit) /* can't match if card < name */ { /* if there are no wild cards, lengths must be the same */ if (!( !wild && cardlen != namelen) ) { for (ii=0; ii < cardlen; ii++) { /* make sure keyword is in uppercase */ if (cardname[ii] > 96) { /* This assumes the ASCII character set in which */ /* upper case characters start at ASCII(97) */ /* Timing tests showed that this is 20% faster */ /* than calling the isupper function. */ cardname[ii] = toupper(cardname[ii]); /* make upper case */ } } if (wild) { ffcmps(keyname, cardname, 1, &match, &exact); if (match) return(*status); /* found a matching keyword */ } else if (keyname[namelenminus1] == cardname[namelenminus1]) { /* test the last character of the keyword name first, on */ /* the theory that it is less likely to match then the first */ /* character since many keywords begin with 'T', for example */ if (FSTRNCMP(keyname, cardname, namelenminus1) == 0) { return(*status); /* found the matching keyword */ } } } } } } if (wild || jj == 1) break; /* stop at end of header if template contains wildcards */ ffmaky(fptr, 1, status); /* reset pointer to beginning of header */ ntodo = nextkey - 1; /* number of keyword to read */ } return(*status = KEY_NO_EXIST); /* couldn't find the keyword */ } /*--------------------------------------------------------------------------*/ int ffgknm( char *card, /* I - keyword card */ char *name, /* O - name of the keyword */ int *length, /* O - length of the keyword name */ int *status) /* IO - error status */ /* Return the name of the keyword, and the name length. This supports the ESO HIERARCH convention where keyword names may be > 8 characters long. */ { char *ptr1, *ptr2; int ii; *name = '\0'; *length = 0; /* support for ESO HIERARCH keywords; find the '=' */ if (FSTRNCMP(card, "HIERARCH ", 9) == 0) { ptr2 = strchr(card, '='); if (!ptr2) /* no value indicator ??? */ { /* this probably indicates an error, so just return FITS name */ strcat(name, "HIERARCH"); *length = 8; return(*status); } /* find the start and end of the HIERARCH name */ ptr1 = &card[9]; while (*ptr1 == ' ') /* skip spaces */ ptr1++; strncat(name, ptr1, ptr2 - ptr1); ii = ptr2 - ptr1; while (ii > 0 && name[ii - 1] == ' ') /* remove trailing spaces */ ii--; name[ii] = '\0'; *length = ii; } else { for (ii = 0; ii < 8; ii++) { /* look for string terminator, or a blank */ if (*(card+ii) != ' ' && *(card+ii) !='\0') { *(name+ii) = *(card+ii); } else { name[ii] = '\0'; *length = ii; return(*status); } } /* if we got here, keyword is 8 characters long */ name[8] = '\0'; *length = 8; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgunt( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ char *unit, /* O - keyword units */ int *status) /* IO - error status */ /* Read (get) the units string from the comment field of the existing keyword. This routine uses a local FITS convention (not defined in the official FITS standard) in which the units are enclosed in square brackets following the '/' comment field delimiter, e.g.: KEYWORD = 12 / [kpc] comment string goes here */ { char valstring[FLEN_VALUE]; char comm[FLEN_COMMENT]; char *loc; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ if (comm[0] == '[') { loc = strchr(comm, ']'); /* find the closing bracket */ if (loc) *loc = '\0'; /* terminate the string */ strcpy(unit, &comm[1]); /* copy the string */ } else unit[0] = '\0'; return(*status); } /*--------------------------------------------------------------------------*/ int ffgkys( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ char *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Get KeYword with a String value: Read (get) a simple string valued keyword. The returned value may be up to 68 chars long ( + 1 null terminator char). The routine does not support the HEASARC convention for continuing long string values over multiple keywords. The ffgkls routine may be used to read long continued strings. The returned comment string may be up to 69 characters long (including null terminator). */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ value[0] = '\0'; ffc2s(valstring, value, status); /* remove quotes from string */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkls( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ char **value, /* O - pointer to keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Get Keyword with possible Long String value: Read (get) the named keyword, returning the value and comment. The returned value string may be arbitrarily long (by using the HEASARC convention for continuing long string values over multiple keywords) so this routine allocates the required memory for the returned string value. It is up to the calling routine to free the memory once it is finished with the value string. The returned comment string may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; int contin; size_t len; if (*status > 0) return(*status); *value = NULL; /* initialize a null pointer in case of error */ ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ if (*status > 0) return(*status); if (!valstring[0]) /* null value string? */ { *value = (char *) malloc(1); /* allocate and return a null string */ **value = '\0'; } else { /* allocate space, plus 1 for null */ *value = (char *) malloc(strlen(valstring) + 1); ffc2s(valstring, *value, status); /* convert string to value */ len = strlen(*value); /* If last character is a & then value may be continued on next keyword */ contin = 1; while (contin) { if (len && *(*value+len-1) == '&') /* is last char an anpersand? */ { ffgcnt(fptr, valstring, status); if (*valstring) /* a null valstring indicates no continuation */ { *(*value+len-1) = '\0'; /* erase the trailing & char */ len += strlen(valstring) - 1; *value = (char *) realloc(*value, len + 1); /* increase size */ strcat(*value, valstring); /* append the continued chars */ } else contin = 0; } else contin = 0; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcnt( fitsfile *fptr, /* I - FITS file pointer */ char *value, /* O - continued string value */ int *status) /* IO - error status */ /* Attempt to read the next keyword, returning the string value if it is a continuation of the previous string keyword value. This uses the HEASARC convention for continuing long string values over multiple keywords. Each continued string is terminated with a backslash character, and the continuation follows on the next keyword which must have the name CONTINUE without an equal sign in column 9 of the card. If the next card is not a continuation, then the returned value string will be null. */ { int tstatus; char card[FLEN_CARD], strval[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); tstatus = 0; value[0] = '\0'; if (ffgnky(fptr, card, &tstatus) > 0) /* read next keyword */ return(*status); /* hit end of header */ if (strncmp(card, "CONTINUE ", 10) == 0) /* a continuation card? */ { strncpy(card, "D2345678= ", 10); /* overwrite a dummy keyword name */ ffpsvc(card, strval, comm, &tstatus); /* get the string value */ ffc2s(strval, value, &tstatus); /* remove the surrounding quotes */ if (tstatus) /* return null if error status was returned */ value[0] = '\0'; } else ffmrky(fptr, -1, status); /* reset the keyword pointer */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyl( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ int *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The returned value = 1 if the keyword is true, else = 0 if false. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2l(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyj( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ long *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The value will be implicitly converted to a (long) integer if it not already of this datatype. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2i(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyjj( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ LONGLONG *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The value will be implicitly converted to a (long) integer if it not already of this datatype. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2j(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkye( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ float *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The value will be implicitly converted to a float if it not already of this datatype. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2r(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyd( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ double *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The value will be implicitly converted to a double if it not already of this datatype. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ ffc2d(valstring, value, status); /* convert string to value */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyc( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ float *value, /* O - keyword value (real,imag) */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The keyword must have a complex value. No implicit data conversion will be performed. */ { char valstring[FLEN_VALUE], message[81]; int len; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ if (valstring[0] != '(' ) /* test that this is a complex keyword */ { sprintf(message, "keyword %s does not have a complex value (ffgkyc):", keyname); ffpmsg(message); ffpmsg(valstring); return(*status = BAD_C2F); } valstring[0] = ' '; /* delete the opening parenthesis */ len = strcspn(valstring, ")" ); valstring[len] = '\0'; /* delete the closing parenthesis */ len = strcspn(valstring, ","); valstring[len] = '\0'; ffc2r(valstring, &value[0], status); /* convert the real part */ ffc2r(&valstring[len + 1], &value[1], status); /* convert imag. part */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkym( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ double *value, /* O - keyword value (real,imag) */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The keyword must have a complex value. No implicit data conversion will be performed. */ { char valstring[FLEN_VALUE], message[81]; int len; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ if (valstring[0] != '(' ) /* test that this is a complex keyword */ { sprintf(message, "keyword %s does not have a complex value (ffgkym):", keyname); ffpmsg(message); ffpmsg(valstring); return(*status = BAD_C2D); } valstring[0] = ' '; /* delete the opening parenthesis */ len = strcspn(valstring, ")" ); valstring[len] = '\0'; /* delete the closing parenthesis */ len = strcspn(valstring, ","); valstring[len] = '\0'; ffc2d(valstring, &value[0], status); /* convert the real part */ ffc2d(&valstring[len + 1], &value[1], status); /* convert the imag. part */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyt( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to read */ long *ivalue, /* O - integer part of keyword value */ double *fraction, /* O - fractional part of keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the named keyword, returning the value and comment. The integer and fractional parts of the value are returned in separate variables, to allow more numerical precision to be passed. This effectively passes a 'triple' precision value, with a 4-byte integer and an 8-byte fraction. The comment may be up to 69 characters long. */ { char valstring[FLEN_VALUE]; char *loc; if (*status > 0) return(*status); ffgkey(fptr, keyname, valstring, comm, status); /* read the keyword */ /* read the entire value string as a double, to get the integer part */ ffc2d(valstring, fraction, status); *ivalue = (long) *fraction; *fraction = *fraction - *ivalue; /* see if we need to read the fractional part again with more precision */ /* look for decimal point, without an exponential E or D character */ loc = strchr(valstring, '.'); if (loc) { if (!strchr(valstring, 'E') && !strchr(valstring, 'D')) ffc2d(loc, fraction, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgkyn( fitsfile *fptr, /* I - FITS file pointer */ int nkey, /* I - number of the keyword to read */ char *keyname, /* O - name of the keyword */ char *value, /* O - keyword value */ char *comm, /* O - keyword comment */ int *status) /* IO - error status */ /* Read (get) the nkey-th keyword returning the keyword name, value and comment. The value is just the literal string of characters in the value field of the keyword. In the case of a string valued keyword, the returned value includes the leading and closing quote characters. The value may be up to 70 characters long, and the comment may be up to 72 characters long. If the keyword has no value (no equal sign in column 9) then a null value is returned. If comm = NULL, then do not return the comment string. */ { char card[FLEN_CARD], sbuff[FLEN_CARD]; int namelen; keyname[0] = '\0'; value[0] = '\0'; if (comm) comm[0] = '\0'; if (*status > 0) return(*status); if (ffgrec(fptr, nkey, card, status) > 0 ) /* get the 80-byte card */ return(*status); ffgknm(card, keyname, &namelen, status); /* get the keyword name */ if (ffpsvc(card, value, comm, status) > 0) /* parse value and comment */ return(*status); if (fftrec(keyname, status) > 0) /* test keyword name; catches no END */ { sprintf(sbuff,"Name of keyword no. %d contains illegal character(s): %s", nkey, keyname); ffpmsg(sbuff); if (nkey % 36 == 0) /* test if at beginning of 36-card FITS record */ ffpmsg(" (This may indicate a missing END keyword)."); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgkns( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ char *value[], /* O - array of pointers to keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. This routine does NOT support the HEASARC long string convention. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, 8); lenroot = strlen(keyroot); if (lenroot == 0 || lenroot > 7) /* root must be 1 - 7 chars long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgrec(fptr, ii, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; strncat(keyindex, &card[lenroot], 8-lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2s(svalue, value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgknl( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ int *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. The returned value = 1 if the keyword is true, else = 0 if false. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, 8); lenroot = strlen(keyroot); if (lenroot == 0 || lenroot > 7) /* root must be 1 - 7 chars long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; strncat(keyindex, &card[lenroot], 8-lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2l(svalue, &value[ival-nstart], status); /* convert*/ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgknj( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ long *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, 8); lenroot = strlen(keyroot); if (lenroot == 0 || lenroot > 7) /* root must be 1 - 7 chars long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; strncat(keyindex, &card[lenroot], 8-lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2i(svalue, &value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgknjj( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ LONGLONG *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, 8); lenroot = strlen(keyroot); if (lenroot == 0 || lenroot > 7) /* root must be 1 - 7 chars long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; strncat(keyindex, &card[lenroot], 8-lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2j(svalue, &value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgkne( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ float *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, 8); lenroot = strlen(keyroot); if (lenroot == 0 || lenroot > 7) /* root must be 1 - 7 chars long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; strncat(keyindex, &card[lenroot], 8-lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2r(svalue, &value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgknd( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - root name of keywords to read */ int nstart, /* I - starting index number */ int nmax, /* I - maximum number of keywords to return */ double *value, /* O - array of keyword values */ int *nfound, /* O - number of values that were returned */ int *status) /* IO - error status */ /* Read (get) an indexed array of keywords with index numbers between NSTART and (NSTART + NMAX -1) inclusive. */ { int nend, lenroot, ii, nkeys, mkeys, tstatus, undefinedval; long ival; char keyroot[FLEN_KEYWORD], keyindex[8], card[FLEN_CARD]; char svalue[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) return(*status); *nfound = 0; nend = nstart + nmax - 1; keyroot[0] = '\0'; strncat(keyroot, keyname, 8); lenroot = strlen(keyroot); if (lenroot == 0 || lenroot > 7) /* root must be 1 - 7 chars long */ return(*status); for (ii=0; ii < lenroot; ii++) /* make sure upper case */ keyroot[ii] = toupper(keyroot[ii]); ffghps(fptr, &nkeys, &mkeys, status); /* get the number of keywords */ ffmaky(fptr, 3, status); /* move to 3rd keyword (skip 1st 2 keywords) */ undefinedval = FALSE; for (ii=3; ii <= nkeys; ii++) { if (ffgnky(fptr, card, status) > 0) /* get next keyword */ return(*status); if (strncmp(keyroot, card, lenroot) == 0) /* see if keyword matches */ { keyindex[0] = '\0'; strncat(keyindex, &card[lenroot], 8-lenroot); /* copy suffix */ tstatus = 0; if (ffc2ii(keyindex, &ival, &tstatus) <= 0) /* test suffix */ { if (ival <= nend && ival >= nstart) /* is index within range? */ { ffpsvc(card, svalue, comm, status); /* parse the value */ ffc2d(svalue, &value[ival-nstart], status); /* convert */ if (ival - nstart + 1 > *nfound) *nfound = ival - nstart + 1; /* max found */ if (*status == VALUE_UNDEFINED) { undefinedval = TRUE; *status = 0; /* reset status to read remaining values */ } } } } } if (undefinedval && (*status <= 0) ) *status = VALUE_UNDEFINED; /* report at least 1 value undefined */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgtdm(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read */ int maxdim, /* I - maximum no. of dimensions to read; */ int *naxis, /* O - number of axes in the data array */ long naxes[], /* O - length of each data axis */ int *status) /* IO - error status */ /* read and parse the TDIMnnn keyword to get the dimensionality of a column */ { int tstatus = 0; char keyname[FLEN_KEYWORD], tdimstr[FLEN_VALUE]; if (*status > 0) return(*status); ffkeyn("TDIM", colnum, keyname, status); /* construct keyword name */ ffgkys(fptr, keyname, tdimstr, NULL, &tstatus); /* try reading keyword */ ffdtdm(fptr, tdimstr, colnum, maxdim,naxis, naxes, status); /* decode it */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgtdmll(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read */ int maxdim, /* I - maximum no. of dimensions to read; */ int *naxis, /* O - number of axes in the data array */ LONGLONG naxes[], /* O - length of each data axis */ int *status) /* IO - error status */ /* read and parse the TDIMnnn keyword to get the dimensionality of a column */ { int tstatus = 0; char keyname[FLEN_KEYWORD], tdimstr[FLEN_VALUE]; if (*status > 0) return(*status); ffkeyn("TDIM", colnum, keyname, status); /* construct keyword name */ ffgkys(fptr, keyname, tdimstr, NULL, &tstatus); /* try reading keyword */ ffdtdmll(fptr, tdimstr, colnum, maxdim,naxis, naxes, status); /* decode it */ return(*status); } /*--------------------------------------------------------------------------*/ int ffdtdm(fitsfile *fptr, /* I - FITS file pointer */ char *tdimstr, /* I - TDIMn keyword value string. e.g. (10,10) */ int colnum, /* I - number of the column */ int maxdim, /* I - maximum no. of dimensions to read; */ int *naxis, /* O - number of axes in the data array */ long naxes[], /* O - length of each data axis */ int *status) /* IO - error status */ /* decode the TDIMnnn keyword to get the dimensionality of a column. Check that the value is legal and consistent with the TFORM value. */ { long dimsize, totalpix = 1; char *loc, *lastloc, message[81]; tcolumn *colptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ if (!tdimstr[0]) /* TDIMn keyword doesn't exist? */ { *naxis = 1; /* default = 1 dimensional */ if (maxdim > 0) naxes[0] = (long) colptr->trepeat; /* default length = repeat */ } else { *naxis = 0; loc = strchr(tdimstr, '(' ); /* find the opening quote */ if (!loc) { sprintf(message, "Illegal TDIM keyword value: %s", tdimstr); return(*status = BAD_TDIM); } while (loc) { loc++; dimsize = strtol(loc, &loc, 10); /* read size of next dimension */ if (*naxis < maxdim) naxes[*naxis] = dimsize; if (dimsize < 0) { ffpmsg("one or more TDIM values are less than 0 (ffdtdm)"); ffpmsg(tdimstr); return(*status = BAD_TDIM); } totalpix *= dimsize; (*naxis)++; lastloc = loc; loc = strchr(loc, ','); /* look for comma before next dimension */ } loc = strchr(lastloc, ')' ); /* check for the closing quote */ if (!loc) { sprintf(message, "Illegal TDIM keyword value: %s", tdimstr); return(*status = BAD_TDIM); } if ((colptr->tdatatype > 0) && ((long) colptr->trepeat != totalpix)) { sprintf(message, "column vector length, %ld, does not equal TDIMn array size, %ld", (long) colptr->trepeat, totalpix); ffpmsg(message); ffpmsg(tdimstr); return(*status = BAD_TDIM); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffdtdmll(fitsfile *fptr, /* I - FITS file pointer */ char *tdimstr, /* I - TDIMn keyword value string. e.g. (10,10) */ int colnum, /* I - number of the column */ int maxdim, /* I - maximum no. of dimensions to read; */ int *naxis, /* O - number of axes in the data array */ LONGLONG naxes[], /* O - length of each data axis */ int *status) /* IO - error status */ /* decode the TDIMnnn keyword to get the dimensionality of a column. Check that the value is legal and consistent with the TFORM value. */ { LONGLONG dimsize; LONGLONG totalpix = 1; char *loc, *lastloc, message[81]; tcolumn *colptr; double doublesize; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ if (!tdimstr[0]) /* TDIMn keyword doesn't exist? */ { *naxis = 1; /* default = 1 dimensional */ if (maxdim > 0) naxes[0] = colptr->trepeat; /* default length = repeat */ } else { *naxis = 0; loc = strchr(tdimstr, '(' ); /* find the opening quote */ if (!loc) { sprintf(message, "Illegal TDIM keyword value: %s", tdimstr); return(*status = BAD_TDIM); } while (loc) { loc++; /* Read value as a double because the string to 64-bit int function is */ /* platform dependent (strtoll, strtol, _atoI64). This still gives */ /* about 48 bits of precision, which is plenty for this purpose. */ doublesize = strtod(loc, &loc); dimsize = (LONGLONG) (doublesize + 0.1); if (*naxis < maxdim) naxes[*naxis] = dimsize; if (dimsize < 0) { ffpmsg("one or more TDIM values are less than 0 (ffdtdm)"); ffpmsg(tdimstr); return(*status = BAD_TDIM); } totalpix *= dimsize; (*naxis)++; lastloc = loc; loc = strchr(loc, ','); /* look for comma before next dimension */ } loc = strchr(lastloc, ')' ); /* check for the closing quote */ if (!loc) { sprintf(message, "Illegal TDIM keyword value: %s", tdimstr); return(*status = BAD_TDIM); } if ((colptr->tdatatype > 0) && (colptr->trepeat != totalpix)) { sprintf(message, "column vector length, %.0f, does not equal TDIMn array size, %.0f", (double) (colptr->trepeat), (double) totalpix); ffpmsg(message); ffpmsg(tdimstr); return(*status = BAD_TDIM); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffghpr(fitsfile *fptr, /* I - FITS file pointer */ int maxdim, /* I - maximum no. of dimensions to read; */ int *simple, /* O - does file conform to FITS standard? 1/0 */ int *bitpix, /* O - number of bits per data value pixel */ int *naxis, /* O - number of axes in the data array */ long naxes[], /* O - length of each data axis */ long *pcount, /* O - number of group parameters (usually 0) */ long *gcount, /* O - number of random groups (usually 1 or 0) */ int *extend, /* O - may FITS file haave extensions? */ int *status) /* IO - error status */ /* Get keywords from the Header of the PRimary array: Check that the keywords conform to the FITS standard and return the parameters which determine the size and structure of the primary array or IMAGE extension. */ { int idummy, ii; LONGLONG lldummy; double ddummy; LONGLONG tnaxes[99]; ffgphd(fptr, maxdim, simple, bitpix, naxis, tnaxes, pcount, gcount, extend, &ddummy, &ddummy, &lldummy, &idummy, status); if (naxis && naxes) { for (ii = 0; (ii < *naxis) && (ii < maxdim); ii++) naxes[ii] = (long) tnaxes[ii]; } else if (naxes) { for (ii = 0; ii < maxdim; ii++) naxes[ii] = (long) tnaxes[ii]; } return(*status); } /*--------------------------------------------------------------------------*/ int ffghprll(fitsfile *fptr, /* I - FITS file pointer */ int maxdim, /* I - maximum no. of dimensions to read; */ int *simple, /* O - does file conform to FITS standard? 1/0 */ int *bitpix, /* O - number of bits per data value pixel */ int *naxis, /* O - number of axes in the data array */ LONGLONG naxes[], /* O - length of each data axis */ long *pcount, /* O - number of group parameters (usually 0) */ long *gcount, /* O - number of random groups (usually 1 or 0) */ int *extend, /* O - may FITS file haave extensions? */ int *status) /* IO - error status */ /* Get keywords from the Header of the PRimary array: Check that the keywords conform to the FITS standard and return the parameters which determine the size and structure of the primary array or IMAGE extension. */ { int idummy; LONGLONG lldummy; double ddummy; ffgphd(fptr, maxdim, simple, bitpix, naxis, naxes, pcount, gcount, extend, &ddummy, &ddummy, &lldummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffghtb(fitsfile *fptr, /* I - FITS file pointer */ int maxfield, /* I - maximum no. of columns to read; */ long *naxis1, /* O - length of table row in bytes */ long *naxis2, /* O - number of rows in the table */ int *tfields, /* O - number of columns in the table */ char **ttype, /* O - name of each column */ long *tbcol, /* O - byte offset in row to each column */ char **tform, /* O - value of TFORMn keyword for each column */ char **tunit, /* O - value of TUNITn keyword for each column */ char *extnm, /* O - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* Get keywords from the Header of the ASCII TaBle: Check that the keywords conform to the FITS standard and return the parameters which describe the table. */ { int ii, maxf, nfound, tstatus; long fields; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE], message[81]; LONGLONG llnaxis1, llnaxis2, pcount; if (*status > 0) return(*status); /* read the first keyword of the extension */ ffgkyn(fptr, 1, name, value, comm, status); if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "TABLE") ) ) { sprintf(message, "This is not a TABLE extension: %s", value); ffpmsg(message); return(*status = NOT_ATABLE); } } else /* error: 1st keyword of extension != XTENSION */ { sprintf(message, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } if (ffgttb(fptr, &llnaxis1, &llnaxis2, &pcount, &fields, status) > 0) return(*status); if (naxis1) *naxis1 = (long) llnaxis1; if (naxis2) *naxis2 = (long) llnaxis2; if (pcount != 0) { sprintf(message, "PCOUNT = %.0f is illegal in ASCII table; must = 0", (double) pcount); ffpmsg(message); return(*status = BAD_PCOUNT); } if (tfields) *tfields = fields; if (maxfield < 0) maxf = fields; else maxf = minvalue(maxfield, fields); if (maxf > 0) { for (ii = 0; ii < maxf; ii++) { /* initialize optional keyword values */ if (ttype) *ttype[ii] = '\0'; if (tunit) *tunit[ii] = '\0'; } if (ttype) ffgkns(fptr, "TTYPE", 1, maxf, ttype, &nfound, status); if (tunit) ffgkns(fptr, "TUNIT", 1, maxf, tunit, &nfound, status); if (*status > 0) return(*status); if (tbcol) { ffgknj(fptr, "TBCOL", 1, maxf, tbcol, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TBCOL keyword(s) not found in ASCII table header (ffghtb)."); return(*status = NO_TBCOL); } } if (tform) { ffgkns(fptr, "TFORM", 1, maxf, tform, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TFORM keyword(s) not found in ASCII table header (ffghtb)."); return(*status = NO_TFORM); } } } if (extnm) { extnm[0] = '\0'; tstatus = *status; ffgkys(fptr, "EXTNAME", extnm, comm, status); if (*status == KEY_NO_EXIST) *status = tstatus; /* keyword not required, so ignore error */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffghtbll(fitsfile *fptr, /* I - FITS file pointer */ int maxfield, /* I - maximum no. of columns to read; */ LONGLONG *naxis1, /* O - length of table row in bytes */ LONGLONG *naxis2, /* O - number of rows in the table */ int *tfields, /* O - number of columns in the table */ char **ttype, /* O - name of each column */ LONGLONG *tbcol, /* O - byte offset in row to each column */ char **tform, /* O - value of TFORMn keyword for each column */ char **tunit, /* O - value of TUNITn keyword for each column */ char *extnm, /* O - value of EXTNAME keyword, if any */ int *status) /* IO - error status */ /* Get keywords from the Header of the ASCII TaBle: Check that the keywords conform to the FITS standard and return the parameters which describe the table. */ { int ii, maxf, nfound, tstatus; long fields; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE], message[81]; LONGLONG llnaxis1, llnaxis2, pcount; if (*status > 0) return(*status); /* read the first keyword of the extension */ ffgkyn(fptr, 1, name, value, comm, status); if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "TABLE") ) ) { sprintf(message, "This is not a TABLE extension: %s", value); ffpmsg(message); return(*status = NOT_ATABLE); } } else /* error: 1st keyword of extension != XTENSION */ { sprintf(message, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } if (ffgttb(fptr, &llnaxis1, &llnaxis2, &pcount, &fields, status) > 0) return(*status); if (naxis1) *naxis1 = llnaxis1; if (naxis2) *naxis2 = llnaxis2; if (pcount != 0) { sprintf(message, "PCOUNT = %.0f is illegal in ASCII table; must = 0", (double) pcount); ffpmsg(message); return(*status = BAD_PCOUNT); } if (tfields) *tfields = fields; if (maxfield < 0) maxf = fields; else maxf = minvalue(maxfield, fields); if (maxf > 0) { for (ii = 0; ii < maxf; ii++) { /* initialize optional keyword values */ if (ttype) *ttype[ii] = '\0'; if (tunit) *tunit[ii] = '\0'; } if (ttype) ffgkns(fptr, "TTYPE", 1, maxf, ttype, &nfound, status); if (tunit) ffgkns(fptr, "TUNIT", 1, maxf, tunit, &nfound, status); if (*status > 0) return(*status); if (tbcol) { ffgknjj(fptr, "TBCOL", 1, maxf, tbcol, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TBCOL keyword(s) not found in ASCII table header (ffghtbll)."); return(*status = NO_TBCOL); } } if (tform) { ffgkns(fptr, "TFORM", 1, maxf, tform, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TFORM keyword(s) not found in ASCII table header (ffghtbll)."); return(*status = NO_TFORM); } } } if (extnm) { extnm[0] = '\0'; tstatus = *status; ffgkys(fptr, "EXTNAME", extnm, comm, status); if (*status == KEY_NO_EXIST) *status = tstatus; /* keyword not required, so ignore error */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffghbn(fitsfile *fptr, /* I - FITS file pointer */ int maxfield, /* I - maximum no. of columns to read; */ long *naxis2, /* O - number of rows in the table */ int *tfields, /* O - number of columns in the table */ char **ttype, /* O - name of each column */ char **tform, /* O - TFORMn value for each column */ char **tunit, /* O - TUNITn value for each column */ char *extnm, /* O - value of EXTNAME keyword, if any */ long *pcount, /* O - value of PCOUNT keyword */ int *status) /* IO - error status */ /* Get keywords from the Header of the BiNary table: Check that the keywords conform to the FITS standard and return the parameters which describe the table. */ { int ii, maxf, nfound, tstatus; long fields; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE], message[81]; LONGLONG naxis1ll, naxis2ll, pcountll; if (*status > 0) return(*status); /* read the first keyword of the extension */ ffgkyn(fptr, 1, name, value, comm, status); if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "BINTABLE") && strcmp(xtension, "A3DTABLE") && strcmp(xtension, "3DTABLE") ) ) { sprintf(message, "This is not a BINTABLE extension: %s", value); ffpmsg(message); return(*status = NOT_BTABLE); } } else /* error: 1st keyword of extension != XTENSION */ { sprintf(message, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } if (ffgttb(fptr, &naxis1ll, &naxis2ll, &pcountll, &fields, status) > 0) return(*status); if (naxis2) *naxis2 = (long) naxis2ll; if (pcount) *pcount = (long) pcountll; if (tfields) *tfields = fields; if (maxfield < 0) maxf = fields; else maxf = minvalue(maxfield, fields); if (maxf > 0) { for (ii = 0; ii < maxf; ii++) { /* initialize optional keyword values */ if (ttype) *ttype[ii] = '\0'; if (tunit) *tunit[ii] = '\0'; } if (ttype) ffgkns(fptr, "TTYPE", 1, maxf, ttype, &nfound, status); if (tunit) ffgkns(fptr, "TUNIT", 1, maxf, tunit, &nfound, status); if (*status > 0) return(*status); if (tform) { ffgkns(fptr, "TFORM", 1, maxf, tform, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TFORM keyword(s) not found in binary table header (ffghbn)."); return(*status = NO_TFORM); } } } if (extnm) { extnm[0] = '\0'; tstatus = *status; ffgkys(fptr, "EXTNAME", extnm, comm, status); if (*status == KEY_NO_EXIST) *status = tstatus; /* keyword not required, so ignore error */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffghbnll(fitsfile *fptr, /* I - FITS file pointer */ int maxfield, /* I - maximum no. of columns to read; */ LONGLONG *naxis2, /* O - number of rows in the table */ int *tfields, /* O - number of columns in the table */ char **ttype, /* O - name of each column */ char **tform, /* O - TFORMn value for each column */ char **tunit, /* O - TUNITn value for each column */ char *extnm, /* O - value of EXTNAME keyword, if any */ LONGLONG *pcount, /* O - value of PCOUNT keyword */ int *status) /* IO - error status */ /* Get keywords from the Header of the BiNary table: Check that the keywords conform to the FITS standard and return the parameters which describe the table. */ { int ii, maxf, nfound, tstatus; long fields; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE], message[81]; LONGLONG naxis1ll, naxis2ll, pcountll; if (*status > 0) return(*status); /* read the first keyword of the extension */ ffgkyn(fptr, 1, name, value, comm, status); if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "BINTABLE") && strcmp(xtension, "A3DTABLE") && strcmp(xtension, "3DTABLE") ) ) { sprintf(message, "This is not a BINTABLE extension: %s", value); ffpmsg(message); return(*status = NOT_BTABLE); } } else /* error: 1st keyword of extension != XTENSION */ { sprintf(message, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } if (ffgttb(fptr, &naxis1ll, &naxis2ll, &pcountll, &fields, status) > 0) return(*status); if (naxis2) *naxis2 = naxis2ll; if (pcount) *pcount = pcountll; if (tfields) *tfields = fields; if (maxfield < 0) maxf = fields; else maxf = minvalue(maxfield, fields); if (maxf > 0) { for (ii = 0; ii < maxf; ii++) { /* initialize optional keyword values */ if (ttype) *ttype[ii] = '\0'; if (tunit) *tunit[ii] = '\0'; } if (ttype) ffgkns(fptr, "TTYPE", 1, maxf, ttype, &nfound, status); if (tunit) ffgkns(fptr, "TUNIT", 1, maxf, tunit, &nfound, status); if (*status > 0) return(*status); if (tform) { ffgkns(fptr, "TFORM", 1, maxf, tform, &nfound, status); if (*status > 0 || nfound != maxf) { ffpmsg( "Required TFORM keyword(s) not found in binary table header (ffghbn)."); return(*status = NO_TFORM); } } } if (extnm) { extnm[0] = '\0'; tstatus = *status; ffgkys(fptr, "EXTNAME", extnm, comm, status); if (*status == KEY_NO_EXIST) *status = tstatus; /* keyword not required, so ignore error */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffgphd(fitsfile *fptr, /* I - FITS file pointer */ int maxdim, /* I - maximum no. of dimensions to read; */ int *simple, /* O - does file conform to FITS standard? 1/0 */ int *bitpix, /* O - number of bits per data value pixel */ int *naxis, /* O - number of axes in the data array */ LONGLONG naxes[], /* O - length of each data axis */ long *pcount, /* O - number of group parameters (usually 0) */ long *gcount, /* O - number of random groups (usually 1 or 0) */ int *extend, /* O - may FITS file haave extensions? */ double *bscale, /* O - array pixel linear scaling factor */ double *bzero, /* O - array pixel linear scaling zero point */ LONGLONG *blank, /* O - value used to represent undefined pixels */ int *nspace, /* O - number of blank keywords prior to END */ int *status) /* IO - error status */ { /* Get the Primary HeaDer parameters. Check that the keywords conform to the FITS standard and return the parameters which determine the size and structure of the primary array or IMAGE extension. */ int unknown, found_end, tstatus, ii, nextkey, namelen; long longbitpix, longnaxis; LONGLONG axislen; char message[FLEN_ERRMSG], keyword[FLEN_KEYWORD]; char card[FLEN_CARD]; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xtension[FLEN_VALUE]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (simple) *simple = 1; unknown = 0; /*--------------------------------------------------------------------*/ /* Get 1st keyword of HDU and test whether it is SIMPLE or XTENSION */ /*--------------------------------------------------------------------*/ ffgkyn(fptr, 1, name, value, comm, status); if ((fptr->Fptr)->curhdu == 0) /* Is this the beginning of the FITS file? */ { if (!strcmp(name, "SIMPLE")) { if (value[0] == 'F') { if (simple) *simple=0; /* not a simple FITS file */ } else if (value[0] != 'T') return(*status = BAD_SIMPLE); } else { sprintf(message, "First keyword of the file is not SIMPLE: %s", name); ffpmsg(message); return(*status = NO_SIMPLE); } } else /* not beginning of the file, so presumably an IMAGE extension */ { /* or it could be a compressed image in a binary table */ if (!strcmp(name, "XTENSION")) { if (ffc2s(value, xtension, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } /* allow the quoted string value to begin in any column and */ /* allow any number of trailing blanks before the closing quote */ if ( (value[0] != '\'') || /* first char must be a quote */ ( strcmp(xtension, "IMAGE") && strcmp(xtension, "IUEIMAGE") ) ) { unknown = 1; /* unknown type of extension; press on anyway */ sprintf(message, "This is not an IMAGE extension: %s", value); ffpmsg(message); } } else /* error: 1st keyword of extension != XTENSION */ { sprintf(message, "First keyword of the extension is not XTENSION: %s", name); ffpmsg(message); return(*status = NO_XTENSION); } } if (unknown && (fptr->Fptr)->compressimg) { /* this is a compressed image, so read ZBITPIX, ZNAXIS keywords */ unknown = 0; /* reset flag */ ffxmsg(3, message); /* clear previous spurious error message */ if (bitpix) { ffgidt(fptr, bitpix, status); /* get bitpix value */ if (*status > 0) { ffpmsg("Error reading BITPIX value of compressed image"); return(*status); } } if (naxis) { ffgidm(fptr, naxis, status); /* get NAXIS value */ if (*status > 0) { ffpmsg("Error reading NAXIS value of compressed image"); return(*status); } } if (naxes) { ffgiszll(fptr, maxdim, naxes, status); /* get NAXISn value */ if (*status > 0) { ffpmsg("Error reading NAXISn values of compressed image"); return(*status); } } nextkey = 9; /* skip required table keywords in the following search */ } else { /*----------------------------------------------------------------*/ /* Get 2nd keyword; test whether it is BITPIX with legal value */ /*----------------------------------------------------------------*/ ffgkyn(fptr, 2, name, value, comm, status); /* BITPIX = 2nd keyword */ if (strcmp(name, "BITPIX")) { sprintf(message, "Second keyword of the extension is not BITPIX: %s", name); ffpmsg(message); return(*status = NO_BITPIX); } if (ffc2ii(value, &longbitpix, status) > 0) { sprintf(message, "Value of BITPIX keyword is not an integer: %s", value); ffpmsg(message); return(*status = BAD_BITPIX); } else if (longbitpix != BYTE_IMG && longbitpix != SHORT_IMG && longbitpix != LONG_IMG && longbitpix != LONGLONG_IMG && longbitpix != FLOAT_IMG && longbitpix != DOUBLE_IMG) { sprintf(message, "Illegal value for BITPIX keyword: %s", value); ffpmsg(message); return(*status = BAD_BITPIX); } if (bitpix) *bitpix = longbitpix; /* do explicit type conversion */ /*---------------------------------------------------------------*/ /* Get 3rd keyword; test whether it is NAXIS with legal value */ /*---------------------------------------------------------------*/ ffgtkn(fptr, 3, "NAXIS", &longnaxis, status); if (*status == BAD_ORDER) return(*status = NO_NAXIS); else if (*status == NOT_POS_INT || longnaxis > 999) { sprintf(message,"NAXIS = %ld is illegal", longnaxis); ffpmsg(message); return(*status = BAD_NAXIS); } else if (naxis) *naxis = longnaxis; /* do explicit type conversion */ /*---------------------------------------------------------*/ /* Get the next NAXISn keywords and test for legal values */ /*---------------------------------------------------------*/ for (ii=0, nextkey=4; ii < longnaxis; ii++, nextkey++) { ffkeyn("NAXIS", ii+1, keyword, status); ffgtknjj(fptr, 4+ii, keyword, &axislen, status); if (*status == BAD_ORDER) return(*status = NO_NAXES); else if (*status == NOT_POS_INT) return(*status = BAD_NAXES); else if (ii < maxdim) if (naxes) naxes[ii] = axislen; } } /*---------------------------------------------------------*/ /* now look for other keywords of interest: */ /* BSCALE, BZERO, BLANK, PCOUNT, GCOUNT, EXTEND, and END */ /*---------------------------------------------------------*/ /* initialize default values in case keyword is not present */ if (bscale) *bscale = 1.0; if (bzero) *bzero = 0.0; if (pcount) *pcount = 0; if (gcount) *gcount = 1; if (extend) *extend = 0; if (blank) *blank = NULL_UNDEFINED; /* no default null value for BITPIX=8,16,32 */ *nspace = 0; found_end = 0; tstatus = *status; for (; !found_end; nextkey++) { /* get next keyword */ /* don't use ffgkyn here because it trys to parse the card to read */ /* the value string, thus failing to read the file just because of */ /* minor syntax errors in optional keywords. */ if (ffgrec(fptr, nextkey, card, status) > 0 ) /* get the 80-byte card */ { if (*status == KEY_OUT_BOUNDS) { found_end = 1; /* simply hit the end of the header */ *status = tstatus; /* reset error status */ } else { ffpmsg("Failed to find the END keyword in header (ffgphd)."); } } else /* got the next keyword without error */ { ffgknm(card, name, &namelen, status); /* get the keyword name */ if (fftrec(name, status) > 0) /* test keyword name; catches no END */ { sprintf(message, "Name of keyword no. %d contains illegal character(s): %s", nextkey, name); ffpmsg(message); if (nextkey % 36 == 0) /* test if at beginning of 36-card record */ ffpmsg(" (This may indicate a missing END keyword)."); } if (!strcmp(name, "BSCALE") && bscale) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2dd(value, bscale, status) > 0) /* convert to double */ { /* reset error status and continue, but still issue warning */ *status = tstatus; *bscale = 1.0; sprintf(message, "Error reading BSCALE keyword value as a double: %s", value); ffpmsg(message); } } else if (!strcmp(name, "BZERO") && bzero) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2dd(value, bzero, status) > 0) /* convert to double */ { /* reset error status and continue, but still issue warning */ *status = tstatus; *bzero = 0.0; sprintf(message, "Error reading BZERO keyword value as a double: %s", value); ffpmsg(message); } } else if (!strcmp(name, "BLANK") && blank) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2jj(value, blank, status) > 0) /* convert to LONGLONG */ { /* reset error status and continue, but still issue warning */ *status = tstatus; *blank = NULL_UNDEFINED; sprintf(message, "Error reading BLANK keyword value as an integer: %s", value); ffpmsg(message); } } else if (!strcmp(name, "PCOUNT") && pcount) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2ii(value, pcount, status) > 0) /* convert to long */ { sprintf(message, "Error reading PCOUNT keyword value as an integer: %s", value); ffpmsg(message); } } else if (!strcmp(name, "GCOUNT") && gcount) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2ii(value, gcount, status) > 0) /* convert to long */ { sprintf(message, "Error reading GCOUNT keyword value as an integer: %s", value); ffpmsg(message); } } else if (!strcmp(name, "EXTEND") && extend) { *nspace = 0; /* reset count of blank keywords */ ffpsvc(card, value, comm, status); /* parse value and comment */ if (ffc2ll(value, extend, status) > 0) /* convert to logical */ { /* reset error status and continue, but still issue warning */ *status = tstatus; *extend = 0; sprintf(message, "Error reading EXTEND keyword value as a logical: %s", value); ffpmsg(message); } } else if (!strcmp(name, "END")) found_end = 1; else if (!card[0] ) *nspace = *nspace + 1; /* this is a blank card in the header */ else *nspace = 0; /* reset count of blank keywords immediately before the END keyword to zero */ } if (*status > 0) /* exit on error after writing error message */ { if ((fptr->Fptr)->curhdu == 0) ffpmsg( "Failed to read the required primary array header keywords."); else ffpmsg( "Failed to read the required image extension header keywords."); return(*status); } } if (unknown) *status = NOT_IMAGE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgttb(fitsfile *fptr, /* I - FITS file pointer*/ LONGLONG *rowlen, /* O - length of a table row, in bytes */ LONGLONG *nrows, /* O - number of rows in the table */ LONGLONG *pcount, /* O - value of PCOUNT keyword */ long *tfields, /* O - number of fields in the table */ int *status) /* IO - error status */ { /* Get and Test TaBle; Test that this is a legal ASCII or binary table and get some keyword values. We assume that the calling routine has already tested the 1st keyword of the extension to ensure that this is really a table extension. */ if (*status > 0) return(*status); if (fftkyn(fptr, 2, "BITPIX", "8", status) == BAD_ORDER) /* 2nd keyword */ return(*status = NO_BITPIX); /* keyword not BITPIX */ else if (*status == NOT_POS_INT) return(*status = BAD_BITPIX); /* value != 8 */ if (fftkyn(fptr, 3, "NAXIS", "2", status) == BAD_ORDER) /* 3rd keyword */ return(*status = NO_NAXIS); /* keyword not NAXIS */ else if (*status == NOT_POS_INT) return(*status = BAD_NAXIS); /* value != 2 */ if (ffgtknjj(fptr, 4, "NAXIS1", rowlen, status) == BAD_ORDER) /* 4th key */ return(*status = NO_NAXES); /* keyword not NAXIS1 */ else if (*status == NOT_POS_INT) return(*status == BAD_NAXES); /* bad NAXIS1 value */ if (ffgtknjj(fptr, 5, "NAXIS2", nrows, status) == BAD_ORDER) /* 5th key */ return(*status = NO_NAXES); /* keyword not NAXIS2 */ else if (*status == NOT_POS_INT) return(*status == BAD_NAXES); /* bad NAXIS2 value */ if (ffgtknjj(fptr, 6, "PCOUNT", pcount, status) == BAD_ORDER) /* 6th key */ return(*status = NO_PCOUNT); /* keyword not PCOUNT */ else if (*status == NOT_POS_INT) return(*status = BAD_PCOUNT); /* bad PCOUNT value */ if (fftkyn(fptr, 7, "GCOUNT", "1", status) == BAD_ORDER) /* 7th keyword */ return(*status = NO_GCOUNT); /* keyword not GCOUNT */ else if (*status == NOT_POS_INT) return(*status = BAD_GCOUNT); /* value != 1 */ if (ffgtkn(fptr, 8, "TFIELDS", tfields, status) == BAD_ORDER) /* 8th key*/ return(*status = NO_TFIELDS); /* keyword not TFIELDS */ else if (*status == NOT_POS_INT || *tfields > 999) return(*status == BAD_TFIELDS); /* bad TFIELDS value */ if (*status > 0) ffpmsg( "Error reading required keywords in the table header (FTGTTB)."); return(*status); } /*--------------------------------------------------------------------------*/ int ffgtkn(fitsfile *fptr, /* I - FITS file pointer */ int numkey, /* I - number of the keyword to read */ char *name, /* I - expected name of the keyword */ long *value, /* O - integer value of the keyword */ int *status) /* IO - error status */ { /* test that keyword number NUMKEY has the expected name and get the integer value of the keyword. Return an error if the keyword name does not match the input name, or if the value of the keyword is not a positive integer. */ char keyname[FLEN_KEYWORD], valuestring[FLEN_VALUE]; char comm[FLEN_COMMENT], message[FLEN_ERRMSG]; if (*status > 0) return(*status); keyname[0] = '\0'; valuestring[0] = '\0'; if (ffgkyn(fptr, numkey, keyname, valuestring, comm, status) <= 0) { if (strcmp(keyname, name) ) *status = BAD_ORDER; /* incorrect keyword name */ else { ffc2ii(valuestring, value, status); /* convert to integer */ if (*status > 0 || *value < 0 ) *status = NOT_POS_INT; } if (*status > 0) { sprintf(message, "ffgtkn found unexpected keyword or value for keyword no. %d.", numkey); ffpmsg(message); sprintf(message, " Expected positive integer keyword %s, but instead", name); ffpmsg(message); sprintf(message, " found keyword %s with value %s", keyname, valuestring); ffpmsg(message); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgtknjj(fitsfile *fptr, /* I - FITS file pointer */ int numkey, /* I - number of the keyword to read */ char *name, /* I - expected name of the keyword */ LONGLONG *value, /* O - integer value of the keyword */ int *status) /* IO - error status */ { /* test that keyword number NUMKEY has the expected name and get the integer value of the keyword. Return an error if the keyword name does not match the input name, or if the value of the keyword is not a positive integer. */ char keyname[FLEN_KEYWORD], valuestring[FLEN_VALUE]; char comm[FLEN_COMMENT], message[FLEN_ERRMSG]; if (*status > 0) return(*status); keyname[0] = '\0'; valuestring[0] = '\0'; if (ffgkyn(fptr, numkey, keyname, valuestring, comm, status) <= 0) { if (strcmp(keyname, name) ) *status = BAD_ORDER; /* incorrect keyword name */ else { ffc2jj(valuestring, value, status); /* convert to integer */ if (*status > 0 || *value < 0 ) *status = NOT_POS_INT; } if (*status > 0) { sprintf(message, "ffgtknjj found unexpected keyword or value for keyword no. %d.", numkey); ffpmsg(message); sprintf(message, " Expected positive integer keyword %s, but instead", name); ffpmsg(message); sprintf(message, " found keyword %s with value %s", keyname, valuestring); ffpmsg(message); } } return(*status); } /*--------------------------------------------------------------------------*/ int fftkyn(fitsfile *fptr, /* I - FITS file pointer */ int numkey, /* I - number of the keyword to read */ char *name, /* I - expected name of the keyword */ char *value, /* I - expected value of the keyword */ int *status) /* IO - error status */ { /* test that keyword number NUMKEY has the expected name and the expected value string. */ char keyname[FLEN_KEYWORD], valuestring[FLEN_VALUE]; char comm[FLEN_COMMENT], message[FLEN_ERRMSG]; if (*status > 0) return(*status); keyname[0] = '\0'; valuestring[0] = '\0'; if (ffgkyn(fptr, numkey, keyname, valuestring, comm, status) <= 0) { if (strcmp(keyname, name) ) *status = BAD_ORDER; /* incorrect keyword name */ if (strcmp(value, valuestring) ) *status = NOT_POS_INT; /* incorrect keyword value */ } if (*status > 0) { sprintf(message, "fftkyn found unexpected keyword or value for keyword no. %d.", numkey); ffpmsg(message); sprintf(message, " Expected keyword %s with value %s, but", name, value); ffpmsg(message); sprintf(message, " found keyword %s with value %s", keyname, valuestring); ffpmsg(message); } return(*status); } /*--------------------------------------------------------------------------*/ int ffh2st(fitsfile *fptr, /* I - FITS file pointer */ char **header, /* O - returned header string */ int *status) /* IO - error status */ /* read header keywords into a long string of chars. This routine allocates memory for the string, so the calling routine must eventually free the memory when it is not needed any more. */ { int nkeys; long nrec; LONGLONG headstart; if (*status > 0) return(*status); /* get number of keywords in the header (doesn't include END) */ if (ffghsp(fptr, &nkeys, NULL, status) > 0) return(*status); nrec = (nkeys / 36 + 1); /* allocate memory for all the keywords (multiple of 2880 bytes) */ *header = (char *) calloc ( nrec * 2880 + 1, 1); if (!(*header)) { *status = MEMORY_ALLOCATION; ffpmsg("failed to allocate memory to hold all the header keywords"); return(*status); } ffghadll(fptr, &headstart, NULL, NULL, status); /* get header address */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* move to header */ ffgbyt(fptr, nrec * 2880, *header, status); /* copy header */ *(*header + (nrec * 2880)) = '\0'; return(*status); } /*--------------------------------------------------------------------------*/ int ffhdr2str( fitsfile *fptr, /* I - FITS file pointer */ int exclude_comm, /* I - if TRUE, exclude commentary keywords */ char **exclist, /* I - list of excluded keyword names */ int nexc, /* I - number of names in exclist */ char **header, /* O - returned header string */ int *nkeys, /* O - returned number of 80-char keywords */ int *status) /* IO - error status */ /* read header keywords into a long string of chars. This routine allocates memory for the string, so the calling routine must eventually free the memory when it is not needed any more. If exclude_comm is TRUE, then all the COMMENT, HISTORY, and keywords will be excluded from the output string of keywords. Any other list of keywords to be excluded may be specified with the exclist parameter. */ { int casesn, match, exact, totkeys; long ii, jj; char keybuf[162], keyname[FLEN_KEYWORD], *headptr; *nkeys = 0; if (*status > 0) return(*status); /* get number of keywords in the header (doesn't include END) */ if (ffghsp(fptr, &totkeys, NULL, status) > 0) return(*status); /* allocate memory for all the keywords (multiple of 2880 bytes) */ *header = (char *) calloc ( (totkeys + 1) * 80 + 1, 1); if (!(*header)) { *status = MEMORY_ALLOCATION; ffpmsg("failed to allocate memory to hold all the header keywords"); return(*status); } headptr = *header; casesn = FALSE; /* read every keyword */ for (ii = 1; ii <= totkeys; ii++) { ffgrec(fptr, ii, keybuf, status); /* pad record with blanks so that it is at least 80 chars long */ strcat(keybuf, " "); keyname[0] = '\0'; strncat(keyname, keybuf, 8); /* copy the keyword name */ if (exclude_comm) { if (!FSTRCMP("COMMENT ", keyname) || !FSTRCMP("HISTORY ", keyname) || !FSTRCMP(" ", keyname) ) continue; /* skip this commentary keyword */ } /* does keyword match any names in the exclusion list? */ for (jj = 0; jj < nexc; jj++ ) { ffcmps(exclist[jj], keyname, casesn, &match, &exact); if (match) break; } if (jj == nexc) { /* not in exclusion list, add this keyword to the string */ strcpy(headptr, keybuf); headptr += 80; (*nkeys)++; } } /* add the END keyword */ strcpy(headptr, "END "); headptr += 80; (*nkeys)++; *headptr = '\0'; /* terminate the header string */ /* minimize the allocated memory */ *header = (char *) realloc(*header, (*nkeys *80) + 1); return(*status); } indi-0.5/src/cfitsio/wcssub.c0000644000175000017500000006130110610474375014022 0ustar jrjr#include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int fits_read_wcstab( fitsfile *fptr, /* I - FITS file pointer */ int nwtb, /* Number of arrays to be read from the binary table(s) */ wtbarr *wtb, /* Address of the first element of an array of wtbarr typedefs. This wtbarr typedef is defined below to match the wtbarr struct defined in WCSLIB. An array of such structs returned by the WCSLIB function wcstab(). */ int *status) /* * Author: Mark Calabretta, Australia Telescope National Facility * http://www.atnf.csiro.au/~mcalabre/index.html * * fits_read_wcstab() extracts arrays from a binary table required in * constructing -TAB coordinates. This helper routine is intended for * use by routines in the WCSLIB library when dealing with the -TAB table * look up WCS convention. */ { int anynul, colnum, hdunum, iwtb, m, naxis, nostat; long *naxes = 0, nelem; wtbarr *wtbp; if (*status) return *status; if (fptr == 0) { return (*status = NULL_INPUT_PTR); } if (nwtb == 0) return 0; /* Zero the array pointers. */ wtbp = wtb; for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) { *wtbp->arrayp = 0x0; } /* Save HDU number so that we can move back to it later. */ fits_get_hdu_num(fptr, &hdunum); wtbp = wtb; for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) { /* Move to the required binary table extension. */ if (fits_movnam_hdu(fptr, BINARY_TBL, (char *)(wtbp->extnam), wtbp->extver, status)) { goto cleanup; } /* Locate the table column. */ if (fits_get_colnum(fptr, CASEINSEN, (char *)(wtbp->ttype), &colnum, status)) { goto cleanup; } /* Get the array dimensions and check for consistency. */ if (wtbp->ndim < 1) { *status = NEG_AXIS; goto cleanup; } if (!(naxes = calloc(wtbp->ndim, sizeof(long)))) { *status = MEMORY_ALLOCATION; goto cleanup; } if (fits_read_tdim(fptr, colnum, wtbp->ndim, &naxis, naxes, status)) { goto cleanup; } if (naxis != wtbp->ndim) { if (wtbp->kind == 'c' && wtbp->ndim == 2) { /* Allow TDIMn to be omitted for degenerate coordinate arrays. */ naxis = 2; naxes[1] = naxes[0]; naxes[0] = 1; } else { *status = BAD_TDIM; goto cleanup; } } if (wtbp->kind == 'c') { /* Coordinate array; calculate the array size. */ nelem = naxes[0]; for (m = 0; m < naxis-1; m++) { *(wtbp->dimlen + m) = naxes[m+1]; nelem *= naxes[m+1]; } } else { /* Index vector; check length. */ if ((nelem = naxes[0]) != *(wtbp->dimlen)) { /* N.B. coordinate array precedes the index vectors. */ *status = BAD_TDIM; goto cleanup; } } free(naxes); naxes = 0; /* Allocate memory for the array. */ if (!(*wtbp->arrayp = calloc((size_t)nelem, sizeof(double)))) { *status = MEMORY_ALLOCATION; goto cleanup; } /* Read the array from the table. */ if (fits_read_col_dbl(fptr, colnum, wtbp->row, 1L, nelem, 0.0, *wtbp->arrayp, &anynul, status)) { goto cleanup; } } cleanup: /* Move back to the starting HDU. */ nostat = 0; fits_movabs_hdu(fptr, hdunum, 0, &nostat); /* Release allocated memory. */ if (naxes) free(naxes); if (*status) { wtbp = wtb; for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) { if (*wtbp->arrayp) free(*wtbp->arrayp); } } return *status; } /*--------------------------------------------------------------------------*/ int ffgiwcs(fitsfile *fptr, /* I - FITS file pointer */ char **header, /* O - pointer to the WCS related keywords */ int *status) /* IO - error status */ /* int fits_get_image_wcs_keys return a string containing all the image WCS header keywords. This string is then used as input to the wcsinit WCSlib routine. THIS ROUTINE IS DEPRECATED. USE fits_hdr2str INSTEAD */ { int hdutype; if (*status > 0) return(*status); fits_get_hdu_type(fptr, &hdutype, status); if (hdutype != IMAGE_HDU) { ffpmsg( "Error in ffgiwcs. This HDU is not an image. Can't read WCS keywords"); return(*status = NOT_IMAGE); } /* read header keywords into a long string of chars */ if (ffh2st(fptr, header, status) > 0) { ffpmsg("error creating string of image WCS keywords (ffgiwcs)"); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgics(fitsfile *fptr, /* I - FITS file pointer */ double *xrval, /* O - X reference value */ double *yrval, /* O - Y reference value */ double *xrpix, /* O - X reference pixel */ double *yrpix, /* O - Y reference pixel */ double *xinc, /* O - X increment per pixel */ double *yinc, /* O - Y increment per pixel */ double *rot, /* O - rotation angle (degrees) */ char *type, /* O - type of projection ('-tan') */ int *status) /* IO - error status */ /* read the values of the celestial coordinate system keywords. These values may be used as input to the subroutines that calculate celestial coordinates. (ffxypx, ffwldp) Modified in Nov 1999 to convert the CD matrix keywords back to the old CDELTn form, and to swap the axes if the dec-like axis is given first, and to assume default values if any of the keywords are not present. */ { int tstat = 0, cd_exists = 0, pc_exists = 0; char ctype[FLEN_VALUE]; double cd11 = 0.0, cd21 = 0.0, cd22 = 0.0, cd12 = 0.0; double pc11 = 1.0, pc21 = 0.0, pc22 = 1.0, pc12 = 0.0; double pi = 3.1415926535897932; double phia, phib, temp; double toler = .0002; /* tolerance for angles to agree (radians) */ /* (= approximately 0.01 degrees) */ if (*status > 0) return(*status); tstat = 0; if (ffgkyd(fptr, "CRVAL1", xrval, NULL, &tstat)) *xrval = 0.; tstat = 0; if (ffgkyd(fptr, "CRVAL2", yrval, NULL, &tstat)) *yrval = 0.; tstat = 0; if (ffgkyd(fptr, "CRPIX1", xrpix, NULL, &tstat)) *xrpix = 0.; tstat = 0; if (ffgkyd(fptr, "CRPIX2", yrpix, NULL, &tstat)) *yrpix = 0.; /* look for CDELTn first, then CDi_j keywords */ tstat = 0; if (ffgkyd(fptr, "CDELT1", xinc, NULL, &tstat)) { /* CASE 1: no CDELTn keyword, so look for the CD matrix */ tstat = 0; if (ffgkyd(fptr, "CD1_1", &cd11, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ if (ffgkyd(fptr, "CD2_1", &cd21, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ if (ffgkyd(fptr, "CD1_2", &cd12, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ if (ffgkyd(fptr, "CD2_2", &cd22, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else cd_exists = 1; /* found at least 1 CD_ keyword */ if (cd_exists) /* convert CDi_j back to CDELTn */ { /* there are 2 ways to compute the angle: */ phia = atan2( cd21, cd11); phib = atan2(-cd12, cd22); /* ensure that phia <= phib */ temp = minvalue(phia, phib); phib = maxvalue(phia, phib); phia = temp; /* there is a possible 180 degree ambiguity in the angles */ /* so add 180 degress to the smaller value if the values */ /* differ by more than 90 degrees = pi/2 radians. */ /* (Later, we may decide to take the other solution by */ /* subtracting 180 degrees from the larger value). */ if ((phib - phia) > (pi / 2.)) phia += pi; if (fabs(phia - phib) > toler) { /* angles don't agree, so looks like there is some skewness */ /* between the axes. Return with an error to be safe. */ *status = APPROX_WCS_KEY; } phia = (phia + phib) /2.; /* use the average of the 2 values */ *xinc = cd11 / cos(phia); *yinc = cd22 / cos(phia); *rot = phia * 180. / pi; /* common usage is to have a positive yinc value. If it is */ /* negative, then subtract 180 degrees from rot and negate */ /* both xinc and yinc. */ if (*yinc < 0) { *xinc = -(*xinc); *yinc = -(*yinc); *rot = *rot - 180.; } } else /* no CD matrix keywords either */ { *xinc = 1.; /* there was no CDELT1 keyword, but check for CDELT2 just in case */ tstat = 0; if (ffgkyd(fptr, "CDELT2", yinc, NULL, &tstat)) *yinc = 1.; tstat = 0; if (ffgkyd(fptr, "CROTA2", rot, NULL, &tstat)) *rot=0.; } } else /* Case 2: CDELTn + optional PC matrix */ { if (ffgkyd(fptr, "CDELT2", yinc, NULL, &tstat)) *yinc = 1.; tstat = 0; if (ffgkyd(fptr, "CROTA2", rot, NULL, &tstat)) { *rot=0.; /* no CROTA2 keyword, so look for the PC matrix */ tstat = 0; if (ffgkyd(fptr, "PC1_1", &pc11, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ if (ffgkyd(fptr, "PC2_1", &pc21, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ if (ffgkyd(fptr, "PC1_2", &pc12, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ if (ffgkyd(fptr, "PC2_2", &pc22, NULL, &tstat)) tstat = 0; /* reset keyword not found error */ else pc_exists = 1; /* found at least 1 PC_ keyword */ if (pc_exists) /* convert PCi_j back to CDELTn */ { /* there are 2 ways to compute the angle: */ phia = atan2( pc21, pc11); phib = atan2(-pc12, pc22); /* ensure that phia <= phib */ temp = minvalue(phia, phib); phib = maxvalue(phia, phib); phia = temp; /* there is a possible 180 degree ambiguity in the angles */ /* so add 180 degress to the smaller value if the values */ /* differ by more than 90 degrees = pi/2 radians. */ /* (Later, we may decide to take the other solution by */ /* subtracting 180 degrees from the larger value). */ if ((phib - phia) > (pi / 2.)) phia += pi; if (fabs(phia - phib) > toler) { /* angles don't agree, so looks like there is some skewness */ /* between the axes. Return with an error to be safe. */ *status = APPROX_WCS_KEY; } phia = (phia + phib) /2.; /* use the average of the 2 values */ *rot = phia * 180. / pi; } } } /* get the type of projection, if any */ tstat = 0; if (ffgkys(fptr, "CTYPE1", ctype, NULL, &tstat)) type[0] = '\0'; else { /* copy the projection type string */ strncpy(type, &ctype[4], 4); type[4] = '\0'; /* check if RA and DEC are inverted */ if (!strncmp(ctype, "DEC-", 4) || !strncmp(ctype+1, "LAT", 3)) { /* the latitudinal axis is given first, so swap them */ /* this case was removed on 12/9. Apparently not correct. if ((*xinc / *yinc) < 0. ) *rot = -90. - (*rot); else */ *rot = 90. - (*rot); /* Empirical tests with ds9 show the y-axis sign must be negated */ /* and the xinc and yinc values must NOT be swapped. */ *yinc = -(*yinc); temp = *xrval; *xrval = *yrval; *yrval = temp; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgtcs(fitsfile *fptr, /* I - FITS file pointer */ int xcol, /* I - column containing the RA coordinate */ int ycol, /* I - column containing the DEC coordinate */ double *xrval, /* O - X reference value */ double *yrval, /* O - Y reference value */ double *xrpix, /* O - X reference pixel */ double *yrpix, /* O - Y reference pixel */ double *xinc, /* O - X increment per pixel */ double *yinc, /* O - Y increment per pixel */ double *rot, /* O - rotation angle (degrees) */ char *type, /* O - type of projection ('-sin') */ int *status) /* IO - error status */ /* read the values of the celestial coordinate system keywords from a FITS table where the X and Y or RA and DEC coordinates are stored in separate column. These values may be used as input to the subroutines that calculate celestial coordinates. (ffxypx, ffwldp) */ { char comm[FLEN_COMMENT],ctype[FLEN_VALUE],keynam[FLEN_KEYWORD]; int tstatus = 0; if (*status > 0) return(*status); ffkeyn("TCRVL",xcol,keynam,status); ffgkyd(fptr,keynam,xrval,comm,status); ffkeyn("TCRVL",ycol,keynam,status); ffgkyd(fptr,keynam,yrval,comm,status); ffkeyn("TCRPX",xcol,keynam,status); ffgkyd(fptr,keynam,xrpix,comm,status); ffkeyn("TCRPX",ycol,keynam,status); ffgkyd(fptr,keynam,yrpix,comm,status); ffkeyn("TCDLT",xcol,keynam,status); ffgkyd(fptr,keynam,xinc,comm,status); ffkeyn("TCDLT",ycol,keynam,status); ffgkyd(fptr,keynam,yinc,comm,status); ffkeyn("TCTYP",xcol,keynam,status); ffgkys(fptr,keynam,ctype,comm,status); if (*status > 0) { ffpmsg ("ffgtcs could not find all the celestial coordinate keywords"); return(*status = NO_WCS_KEY); } /* copy the projection type string */ strncpy(type, &ctype[4], 4); type[4] = '\0'; *rot=0.; /* default rotation is 0 */ ffkeyn("TCROT",ycol,keynam,status); ffgkyd(fptr,keynam,rot,comm,&tstatus); /* keyword may not exist */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgtwcs(fitsfile *fptr, /* I - FITS file pointer */ int xcol, /* I - column number for the X column */ int ycol, /* I - column number for the Y column */ char **header, /* O - string of all the WCS keywords */ int *status) /* IO - error status */ /* int fits_get_table_wcs_keys Return string containing all the WCS keywords appropriate for the pair of X and Y columns containing the coordinate of each event in an event list table. This string may then be passed to Doug Mink's WCS library wcsinit routine, to create and initialize the WCS structure. The calling routine must free the header character string when it is no longer needed. THIS ROUTINE IS DEPRECATED. USE fits_hdr2str INSTEAD */ { int hdutype, ncols, tstatus, length; int naxis1 = 1, naxis2 = 1; long tlmin, tlmax; char keyname[FLEN_KEYWORD]; char valstring[FLEN_VALUE]; char comm[2]; char *cptr; /* construct a string of 80 blanks, for adding fill to the keywords */ /* 12345678901234567890123456789012345678901234567890123456789012345678901234567890 */ char blanks[] = " "; if (*status > 0) return(*status); fits_get_hdu_type(fptr, &hdutype, status); if (hdutype == IMAGE_HDU) { ffpmsg("Can't read table WSC keywords. This HDU is not a table"); return(*status = NOT_TABLE); } fits_get_num_cols(fptr, &ncols, status); if (xcol < 1 || xcol > ncols) { ffpmsg("illegal X axis column number in fftwcs"); return(*status = BAD_COL_NUM); } if (ycol < 1 || ycol > ncols) { ffpmsg("illegal Y axis column number in fftwcs"); return(*status = BAD_COL_NUM); } /* allocate character string for all the WCS keywords */ *header = calloc(1, 2401); /* room for up to 30 keywords */ if (*header == 0) { ffpmsg("error allocating memory for WCS header keywords (fftwcs)"); return(*status = MEMORY_ALLOCATION); } cptr = *header; comm[0] = '\0'; tstatus = 0; ffkeyn("TLMIN",xcol,keyname,status); ffgkyj(fptr,keyname, &tlmin,NULL,&tstatus); if (!tstatus) { ffkeyn("TLMAX",xcol,keyname,status); ffgkyj(fptr,keyname, &tlmax,NULL,&tstatus); } if (!tstatus) { naxis1 = tlmax - tlmin + 1; } tstatus = 0; ffkeyn("TLMIN",ycol,keyname,status); ffgkyj(fptr,keyname, &tlmin,NULL,&tstatus); if (!tstatus) { ffkeyn("TLMAX",ycol,keyname,status); ffgkyj(fptr,keyname, &tlmax,NULL,&tstatus); } if (!tstatus) { naxis2 = tlmax - tlmin + 1; } /* 123456789012345678901234567890 */ strcat(cptr, "NAXIS = 2"); strncat(cptr, blanks, 50); cptr += 80; ffi2c(naxis1, valstring, status); /* convert to formatted string */ ffmkky("NAXIS1", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; strcpy(keyname, "NAXIS2"); ffi2c(naxis2, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* read the required header keywords (use defaults if not found) */ /* CTYPE1 keyword */ tstatus = 0; ffkeyn("TCTYP",xcol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) valstring[0] = '\0'; ffmkky("CTYPE1", valstring, comm, cptr, status); /* construct the keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; /* CTYPE2 keyword */ tstatus = 0; ffkeyn("TCTYP",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) valstring[0] = '\0'; ffmkky("CTYPE2", valstring, comm, cptr, status); /* construct the keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; /* CRPIX1 keyword */ tstatus = 0; ffkeyn("TCRPX",xcol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CRPIX1", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CRPIX2 keyword */ tstatus = 0; ffkeyn("TCRPX",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CRPIX2", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CRVAL1 keyword */ tstatus = 0; ffkeyn("TCRVL",xcol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CRVAL1", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CRVAL2 keyword */ tstatus = 0; ffkeyn("TCRVL",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CRVAL2", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CDELT1 keyword */ tstatus = 0; ffkeyn("TCDLT",xcol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CDELT1", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* CDELT2 keyword */ tstatus = 0; ffkeyn("TCDLT",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) ) strcpy(valstring, "1"); ffmkky("CDELT2", valstring, comm, cptr, status); /* construct the keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; /* the following keywords may not exist */ /* CROTA2 keyword */ tstatus = 0; ffkeyn("TCROT",ycol,keyname,status); if (ffgkey(fptr, keyname, valstring, NULL, &tstatus) == 0 ) { ffmkky("CROTA2", valstring, comm, cptr, status); /* construct keyword*/ strncat(cptr, blanks, 50); /* pad with blanks */ cptr += 80; } /* EPOCH keyword */ tstatus = 0; if (ffgkey(fptr, "EPOCH", valstring, NULL, &tstatus) == 0 ) { ffmkky("EPOCH", valstring, comm, cptr, status); /* construct keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* EQUINOX keyword */ tstatus = 0; if (ffgkey(fptr, "EQUINOX", valstring, NULL, &tstatus) == 0 ) { ffmkky("EQUINOX", valstring, comm, cptr, status); /* construct keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* RADECSYS keyword */ tstatus = 0; if (ffgkey(fptr, "RADECSYS", valstring, NULL, &tstatus) == 0 ) { ffmkky("RADECSYS", valstring, comm, cptr, status); /*construct keyword*/ length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* TELESCOPE keyword */ tstatus = 0; if (ffgkey(fptr, "TELESCOP", valstring, NULL, &tstatus) == 0 ) { ffmkky("TELESCOP", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* INSTRUME keyword */ tstatus = 0; if (ffgkey(fptr, "INSTRUME", valstring, NULL, &tstatus) == 0 ) { ffmkky("INSTRUME", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* DETECTOR keyword */ tstatus = 0; if (ffgkey(fptr, "DETECTOR", valstring, NULL, &tstatus) == 0 ) { ffmkky("DETECTOR", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* MJD-OBS keyword */ tstatus = 0; if (ffgkey(fptr, "MJD-OBS", valstring, NULL, &tstatus) == 0 ) { ffmkky("MJD-OBS", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* DATE-OBS keyword */ tstatus = 0; if (ffgkey(fptr, "DATE-OBS", valstring, NULL, &tstatus) == 0 ) { ffmkky("DATE-OBS", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } /* DATE keyword */ tstatus = 0; if (ffgkey(fptr, "DATE", valstring, NULL, &tstatus) == 0 ) { ffmkky("DATE", valstring, comm, cptr, status); length = strlen(cptr); strncat(cptr, blanks, 80 - length); /* pad with blanks */ cptr += 80; } strcat(cptr, "END"); strncat(cptr, blanks, 77); return(*status); } indi-0.5/src/cfitsio/putcolu.c0000644000175000017500000005177110610474375014221 0ustar jrjr/* This file, putcolu.c, contains routines that write data elements to */ /* a FITS image or table. Writes null values. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppru( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *status) /* IO - error status */ /* Write null values to the primary array. */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } row=maxvalue(1,group); ffpclu(fptr, 2, row, firstelem, nelem, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpprn( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *status) /* IO - error status */ /* Write null values to the primary array. (Doesn't support groups). */ { long row = 1; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } ffpclu(fptr, 2, row, firstelem, nelem, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclu( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelempar, /* I - number of values to write */ int *status) /* IO - error status */ /* Set elements of a table column to the appropriate null value for the column The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. This routine support COMPLEX and DOUBLE COMPLEX binary table columns, and sets both the real and imaginary components of the element to a NaN. */ { int tcode, maxelem, hdutype, writemode = 2, leng; short i2null; INT32BIT i4null; long twidth, incre; long ii; LONGLONG largeelem, nelem, tnull, i8null; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, ntodo; double scale, zero; unsigned char i1null, lognul = 0; char tform[20], *cstring = 0; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ long jbuff[2] = { -1, -1}; /* all bits set is equivalent to a NaN */ size_t buffsize; if (*status > 0) /* inherit input status value if > 0 */ return(*status); nelem = nelempar; largeelem = firstelem; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ /* note that writemode = 2 by default (not 1), so that the returned */ /* repeat and incre values will be the actual values for this column. */ /* If writing nulls to a variable length column then dummy data values */ /* must have already been written to the heap. */ /* We just have to overwrite the previous values with null values. */ /* Set writemode = 0 in this case, to test that values have been written */ fits_get_coltype(fptr, colnum, &tcode, NULL, NULL, status); if (tcode < 0) writemode = 0; /* this is a variable length column */ if (abs(tcode) >= TCOMPLEX) { /* treat complex columns as pairs of numbers */ largeelem = (largeelem - 1) * 2 + 1; nelem *= 2; } if (ffgcprll( fptr, colnum, firstrow, largeelem, nelem, writemode, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) { if (snull[0] == ASCII_NULL_UNDEFINED) { ffpmsg( "Null value string for ASCII table column is not defined (FTPCLU)."); return(*status = NO_NULL); } /* allocate buffer to hold the null string. Must write the entire */ /* width of the column (twidth bytes) to avoid possible problems */ /* with uninitialized FITS blocks, in case the field spans blocks */ buffsize = maxvalue(20, twidth); cstring = (char *) malloc(buffsize); if (!cstring) return(*status = MEMORY_ALLOCATION); memset(cstring, ' ', buffsize); /* initialize with blanks */ leng = strlen(snull); if (hdutype == BINARY_TBL) leng++; /* copy the terminator too in binary tables */ strncpy(cstring, snull, leng); /* copy null string to temp buffer */ } else if ( tcode == TBYTE || tcode == TSHORT || tcode == TLONG || tcode == TLONGLONG) { if (tnull == NULL_UNDEFINED) { ffpmsg( "Null value for integer table column is not defined (FTPCLU)."); return(*status = NO_NULL); } if (tcode == TBYTE) i1null = (unsigned char) tnull; else if (tcode == TSHORT) { i2null = (short) tnull; #if BYTESWAPPED ffswap2(&i2null, 1); /* reverse order of bytes */ #endif } else if (tcode == TLONG) { i4null = (INT32BIT) tnull; #if BYTESWAPPED ffswap4(&i4null, 1); /* reverse order of bytes */ #endif } else { i8null = tnull; #if BYTESWAPPED ffswap4( (INT32BIT*) (&i8null), 2); /* reverse order of bytes */ #endif } } /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ ntodo = remain; /* number of elements to write at one time */ while (ntodo) { /* limit the number of pixels to process at one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TBYTE): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 1, &i1null, status); break; case (TSHORT): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 2, &i2null, status); break; case (TLONG): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 4, &i4null, status); break; case (TLONGLONG): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 8, &i8null, status); break; case (TFLOAT): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 4, jbuff, status); break; case (TDOUBLE): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 8, jbuff, status); break; case (TLOGICAL): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 1, &lognul, status); break; case (TSTRING): /* an ASCII table column */ /* repeat always = 1, so ntodo is also guaranteed to = 1 */ ffpbyt(fptr, twidth, cstring, status); break; default: /* error trap */ sprintf(message, "Cannot write null value to column %d which has format %s", colnum,tform); ffpmsg(message); return(*status); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing %.0f thru %.0f of null values (ffpclu).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); if (cstring) free(cstring); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } ntodo = remain; /* this is the maximum number to do in next loop */ } /* End of main while Loop */ if (cstring) free(cstring); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcluc( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ int *status) /* IO - error status */ /* Set elements of a table column to the appropriate null value for the column The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. This routine does not do anything special in the case of COMPLEX table columns (unlike the similar ffpclu routine). This routine is mainly for use by ffpcne which already compensates for the effective doubling of the number of elements in a complex column. */ { int tcode, maxelem, hdutype, writemode = 2, leng; short i2null; INT32BIT i4null; long twidth, incre; long ii; LONGLONG tnull, i8null; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, ntodo; double scale, zero; unsigned char i1null, lognul = 0; char tform[20], *cstring = 0; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ long jbuff[2] = { -1, -1}; /* all bits set is equivalent to a NaN */ size_t buffsize; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ /* note that writemode = 2 by default (not 1), so that the returned */ /* repeat and incre values will be the actual values for this column. */ /* If writing nulls to a variable length column then dummy data values */ /* must have already been written to the heap. */ /* We just have to overwrite the previous values with null values. */ /* Set writemode = 0 in this case, to test that values have been written */ fits_get_coltype(fptr, colnum, &tcode, NULL, NULL, status); if (tcode < 0) writemode = 0; /* this is a variable length column */ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, writemode, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) { if (snull[0] == ASCII_NULL_UNDEFINED) { ffpmsg( "Null value string for ASCII table column is not defined (FTPCLU)."); return(*status = NO_NULL); } /* allocate buffer to hold the null string. Must write the entire */ /* width of the column (twidth bytes) to avoid possible problems */ /* with uninitialized FITS blocks, in case the field spans blocks */ buffsize = maxvalue(20, twidth); cstring = (char *) malloc(buffsize); if (!cstring) return(*status = MEMORY_ALLOCATION); memset(cstring, ' ', buffsize); /* initialize with blanks */ leng = strlen(snull); if (hdutype == BINARY_TBL) leng++; /* copy the terminator too in binary tables */ strncpy(cstring, snull, leng); /* copy null string to temp buffer */ } else if ( tcode == TBYTE || tcode == TSHORT || tcode == TLONG || tcode == TLONGLONG) { if (tnull == NULL_UNDEFINED) { ffpmsg( "Null value for integer table column is not defined (FTPCLU)."); return(*status = NO_NULL); } if (tcode == TBYTE) i1null = (unsigned char) tnull; else if (tcode == TSHORT) { i2null = (short) tnull; #if BYTESWAPPED ffswap2(&i2null, 1); /* reverse order of bytes */ #endif } else if (tcode == TLONG) { i4null = (INT32BIT) tnull; #if BYTESWAPPED ffswap4(&i4null, 1); /* reverse order of bytes */ #endif } else { i8null = tnull; #if BYTESWAPPED ffswap4( (INT32BIT*) &i8null, 2); /* reverse order of bytes */ #endif } } /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ ntodo = remain; /* number of elements to write at one time */ while (ntodo) { /* limit the number of pixels to process at one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TBYTE): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 1, &i1null, status); break; case (TSHORT): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 2, &i2null, status); break; case (TLONG): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 4, &i4null, status); break; case (TLONGLONG): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 8, &i8null, status); break; case (TFLOAT): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 4, jbuff, status); break; case (TDOUBLE): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 8, jbuff, status); break; case (TLOGICAL): for (ii = 0; ii < ntodo; ii++) ffpbyt(fptr, 1, &lognul, status); break; case (TSTRING): /* an ASCII table column */ /* repeat always = 1, so ntodo is also guaranteed to = 1 */ ffpbyt(fptr, twidth, cstring, status); break; default: /* error trap */ sprintf(message, "Cannot write null value to column %d which has format %s", colnum,tform); ffpmsg(message); return(*status); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing %.0f thru %.0f of null values (ffpclu).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); if (cstring) free(cstring); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } ntodo = remain; /* this is the maximum number to do in next loop */ } /* End of main while Loop */ if (cstring) free(cstring); return(*status); } /*--------------------------------------------------------------------------*/ int ffprwu(fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, int *status) /* * fits_write_nullrows / ffprwu - write TNULLs to all columns in one or more rows * * fitsfile *fptr - pointer to FITS HDU opened for read/write * long int firstrow - first table row to set to null. (firstrow >= 1) * long int nrows - total number or rows to set to null. (nrows >= 1) * int *status - upon return, *status contains CFITSIO status code * * RETURNS: CFITSIO status code * * written by Craig Markwardt, GSFC */ { LONGLONG ntotrows; int ncols, i; int typecode = 0; LONGLONG repeat = 0, width = 0; int nullstatus; if (*status > 0) return *status; if ((firstrow <= 0) || (nrows <= 0)) return (*status = BAD_ROW_NUM); fits_get_num_rowsll(fptr, &ntotrows, status); if (firstrow + nrows - 1 > ntotrows) return (*status = BAD_ROW_NUM); fits_get_num_cols(fptr, &ncols, status); if (*status) return *status; /* Loop through each column and write nulls */ for (i=1; i <= ncols; i++) { repeat = 0; typecode = 0; width = 0; fits_get_coltypell(fptr, i, &typecode, &repeat, &width, status); if (*status) break; /* NOTE: data of TSTRING type must not write the total repeat count, since the repeat count is the *character* count, not the nstring count. Divide by string width to get number of strings. */ if (typecode == TSTRING) repeat /= width; /* Write NULLs */ nullstatus = 0; fits_write_col_null(fptr, i, firstrow, 1, repeat*nrows, &nullstatus); /* ignore error if no null value is defined for the column */ if (nullstatus && nullstatus != NO_NULL) return (*status = nullstatus); } return *status; } indi-0.5/src/cfitsio/getcol.c0000644000175000017500000011256210610474374013776 0ustar jrjr /* This file, getcol.c, contains routines that read data elements from */ /* a FITS image or table. There are generic datatype routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpxv( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *firstpix, /* I - coord of first pixel to read (1s based) */ LONGLONG nelem, /* I - number of values to read */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { LONGLONG tfirstpix[99]; int naxis, ii; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); for (ii=0; ii < naxis; ii++) tfirstpix[ii] = firstpix[ii]; ffgpxvll(fptr, datatype, tfirstpix, nelem, nulval, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpxvll( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG *firstpix, /* I - coord of first pixel to read (1s based) */ LONGLONG nelem, /* I - number of values to read */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { int naxis, ii; char cdummy; int nullcheck = 1; LONGLONG naxes[9]; LONGLONG dimsize = 1, firstelem; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); /* calculate the position of the first element in the array */ firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, datatype, firstelem, nelem, nullcheck, nulval, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (datatype == TBYTE) { if (nulval == 0) ffgclb(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (unsigned char *) array, &cdummy, anynul, status); else ffgclb(fptr, 2, 1, firstelem, nelem, 1, 1, *(unsigned char *) nulval, (unsigned char *) array, &cdummy, anynul, status); } else if (datatype == TSBYTE) { if (nulval == 0) ffgclsb(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (signed char *) array, &cdummy, anynul, status); else ffgclsb(fptr, 2, 1, firstelem, nelem, 1, 1, *(signed char *) nulval, (signed char *) array, &cdummy, anynul, status); } else if (datatype == TUSHORT) { if (nulval == 0) ffgclui(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (unsigned short *) array, &cdummy, anynul, status); else ffgclui(fptr, 2, 1, firstelem, nelem, 1, 1, *(unsigned short *) nulval, (unsigned short *) array, &cdummy, anynul, status); } else if (datatype == TSHORT) { if (nulval == 0) ffgcli(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (short *) array, &cdummy, anynul, status); else ffgcli(fptr, 2, 1, firstelem, nelem, 1, 1, *(short *) nulval, (short *) array, &cdummy, anynul, status); } else if (datatype == TUINT) { if (nulval == 0) ffgcluk(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (unsigned int *) array, &cdummy, anynul, status); else ffgcluk(fptr, 2, 1, firstelem, nelem, 1, 1, *(unsigned int *) nulval, (unsigned int *) array, &cdummy, anynul, status); } else if (datatype == TINT) { if (nulval == 0) ffgclk(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (int *) array, &cdummy, anynul, status); else ffgclk(fptr, 2, 1, firstelem, nelem, 1, 1, *(int *) nulval, (int *) array, &cdummy, anynul, status); } else if (datatype == TULONG) { if (nulval == 0) ffgcluj(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (unsigned long *) array, &cdummy, anynul, status); else ffgcluj(fptr, 2, 1, firstelem, nelem, 1, 1, *(unsigned long *) nulval, (unsigned long *) array, &cdummy, anynul, status); } else if (datatype == TLONG) { if (nulval == 0) ffgclj(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (long *) array, &cdummy, anynul, status); else ffgclj(fptr, 2, 1, firstelem, nelem, 1, 1, *(long *) nulval, (long *) array, &cdummy, anynul, status); } else if (datatype == TLONGLONG) { if (nulval == 0) ffgcljj(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (LONGLONG *) array, &cdummy, anynul, status); else ffgcljj(fptr, 2, 1, firstelem, nelem, 1, 1, *(LONGLONG *) nulval, (LONGLONG *) array, &cdummy, anynul, status); } else if (datatype == TFLOAT) { if (nulval == 0) ffgcle(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (float *) array, &cdummy, anynul, status); else ffgcle(fptr, 2, 1, firstelem, nelem, 1, 1, *(float *) nulval, (float *) array, &cdummy, anynul, status); } else if (datatype == TDOUBLE) { if (nulval == 0) ffgcld(fptr, 2, 1, firstelem, nelem, 1, 1, 0, (double *) array, &cdummy, anynul, status); else ffgcld(fptr, 2, 1, firstelem, nelem, 1, 1, *(double *) nulval, (double *) array, &cdummy, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgpxf( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *firstpix, /* I - coord of first pixel to read (1s based) */ LONGLONG nelem, /* I - number of values to read */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - returned array of null value flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). The nullarray values will = 1 if the corresponding array value is null. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { LONGLONG tfirstpix[99]; int naxis, ii; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); for (ii=0; ii < naxis; ii++) tfirstpix[ii] = firstpix[ii]; ffgpxfll(fptr, datatype, tfirstpix, nelem, array, nullarray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpxfll( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG *firstpix, /* I - coord of first pixel to read (1s based) */ LONGLONG nelem, /* I - number of values to read */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - returned array of null value flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). The nullarray values will = 1 if the corresponding array value is null. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { int naxis, ii; int nullcheck = 2; LONGLONG naxes[9]; LONGLONG dimsize = 1, firstelem; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); /* calculate the position of the first element in the array */ firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, datatype, firstelem, nelem, nullcheck, NULL, array, nullarray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (datatype == TBYTE) { ffgclb(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (unsigned char *) array, nullarray, anynul, status); } else if (datatype == TSBYTE) { ffgclsb(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (signed char *) array, nullarray, anynul, status); } else if (datatype == TUSHORT) { ffgclui(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (unsigned short *) array, nullarray, anynul, status); } else if (datatype == TSHORT) { ffgcli(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (short *) array, nullarray, anynul, status); } else if (datatype == TUINT) { ffgcluk(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (unsigned int *) array, nullarray, anynul, status); } else if (datatype == TINT) { ffgclk(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (int *) array, nullarray, anynul, status); } else if (datatype == TULONG) { ffgcluj(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (unsigned long *) array, nullarray, anynul, status); } else if (datatype == TLONG) { ffgclj(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (long *) array, nullarray, anynul, status); } else if (datatype == TLONGLONG) { ffgcljj(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (LONGLONG *) array, nullarray, anynul, status); } else if (datatype == TFLOAT) { ffgcle(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (float *) array, nullarray, anynul, status); } else if (datatype == TDOUBLE) { ffgcld(fptr, 2, 1, firstelem, nelem, 1, 2, 0, (double *) array, nullarray, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgsv( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc , /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dim. */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an section of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { int naxis; long naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgisz(fptr, 9, naxes, status); if (datatype == TBYTE) { if (nulval == 0) ffgsvb(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned char *) array, anynul, status); else ffgsvb(fptr, 1, naxis, naxes, blc, trc, inc, *(unsigned char *) nulval, (unsigned char *) array, anynul, status); } else if (datatype == TSBYTE) { if (nulval == 0) ffgsvsb(fptr, 1, naxis, naxes, blc, trc, inc, 0, (signed char *) array, anynul, status); else ffgsvsb(fptr, 1, naxis, naxes, blc, trc, inc, *(signed char *) nulval, (signed char *) array, anynul, status); } else if (datatype == TUSHORT) { if (nulval == 0) ffgsvui(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned short *) array, anynul, status); else ffgsvui(fptr, 1, naxis, naxes,blc, trc, inc, *(unsigned short *) nulval, (unsigned short *) array, anynul, status); } else if (datatype == TSHORT) { if (nulval == 0) ffgsvi(fptr, 1, naxis, naxes, blc, trc, inc, 0, (short *) array, anynul, status); else ffgsvi(fptr, 1, naxis, naxes, blc, trc, inc, *(short *) nulval, (short *) array, anynul, status); } else if (datatype == TUINT) { if (nulval == 0) ffgsvuk(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned int *) array, anynul, status); else ffgsvuk(fptr, 1, naxis, naxes, blc, trc, inc, *(unsigned int *) nulval, (unsigned int *) array, anynul, status); } else if (datatype == TINT) { if (nulval == 0) ffgsvk(fptr, 1, naxis, naxes, blc, trc, inc, 0, (int *) array, anynul, status); else ffgsvk(fptr, 1, naxis, naxes, blc, trc, inc, *(int *) nulval, (int *) array, anynul, status); } else if (datatype == TULONG) { if (nulval == 0) ffgsvuj(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned long *) array, anynul, status); else ffgsvuj(fptr, 1, naxis, naxes, blc, trc, inc, *(unsigned long *) nulval, (unsigned long *) array, anynul, status); } else if (datatype == TLONG) { if (nulval == 0) ffgsvj(fptr, 1, naxis, naxes, blc, trc, inc, 0, (long *) array, anynul, status); else ffgsvj(fptr, 1, naxis, naxes, blc, trc, inc, *(long *) nulval, (long *) array, anynul, status); } else if (datatype == TLONGLONG) { if (nulval == 0) ffgsvjj(fptr, 1, naxis, naxes, blc, trc, inc, 0, (LONGLONG *) array, anynul, status); else ffgsvjj(fptr, 1, naxis, naxes, blc, trc, inc, *(LONGLONG *) nulval, (LONGLONG *) array, anynul, status); } else if (datatype == TFLOAT) { if (nulval == 0) ffgsve(fptr, 1, naxis, naxes, blc, trc, inc, 0, (float *) array, anynul, status); else ffgsve(fptr, 1, naxis, naxes, blc, trc, inc, *(float *) nulval, (float *) array, anynul, status); } else if (datatype == TDOUBLE) { if (nulval == 0) ffgsvd(fptr, 1, naxis, naxes, blc, trc, inc, 0, (double *) array, anynul, status); else ffgsvd(fptr, 1, naxis, naxes, blc, trc, inc, *(double *) nulval, (double *) array, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgpv( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (datatype == TBYTE) { if (nulval == 0) ffgpvb(fptr, 1, firstelem, nelem, 0, (unsigned char *) array, anynul, status); else ffgpvb(fptr, 1, firstelem, nelem, *(unsigned char *) nulval, (unsigned char *) array, anynul, status); } else if (datatype == TSBYTE) { if (nulval == 0) ffgpvsb(fptr, 1, firstelem, nelem, 0, (signed char *) array, anynul, status); else ffgpvsb(fptr, 1, firstelem, nelem, *(signed char *) nulval, (signed char *) array, anynul, status); } else if (datatype == TUSHORT) { if (nulval == 0) ffgpvui(fptr, 1, firstelem, nelem, 0, (unsigned short *) array, anynul, status); else ffgpvui(fptr, 1, firstelem, nelem, *(unsigned short *) nulval, (unsigned short *) array, anynul, status); } else if (datatype == TSHORT) { if (nulval == 0) ffgpvi(fptr, 1, firstelem, nelem, 0, (short *) array, anynul, status); else ffgpvi(fptr, 1, firstelem, nelem, *(short *) nulval, (short *) array, anynul, status); } else if (datatype == TUINT) { if (nulval == 0) ffgpvuk(fptr, 1, firstelem, nelem, 0, (unsigned int *) array, anynul, status); else ffgpvuk(fptr, 1, firstelem, nelem, *(unsigned int *) nulval, (unsigned int *) array, anynul, status); } else if (datatype == TINT) { if (nulval == 0) ffgpvk(fptr, 1, firstelem, nelem, 0, (int *) array, anynul, status); else ffgpvk(fptr, 1, firstelem, nelem, *(int *) nulval, (int *) array, anynul, status); } else if (datatype == TULONG) { if (nulval == 0) ffgpvuj(fptr, 1, firstelem, nelem, 0, (unsigned long *) array, anynul, status); else ffgpvuj(fptr, 1, firstelem, nelem, *(unsigned long *) nulval, (unsigned long *) array, anynul, status); } else if (datatype == TLONG) { if (nulval == 0) ffgpvj(fptr, 1, firstelem, nelem, 0, (long *) array, anynul, status); else ffgpvj(fptr, 1, firstelem, nelem, *(long *) nulval, (long *) array, anynul, status); } else if (datatype == TLONGLONG) { if (nulval == 0) ffgpvjj(fptr, 1, firstelem, nelem, 0, (LONGLONG *) array, anynul, status); else ffgpvjj(fptr, 1, firstelem, nelem, *(LONGLONG *) nulval, (LONGLONG *) array, anynul, status); } else if (datatype == TFLOAT) { if (nulval == 0) ffgpve(fptr, 1, firstelem, nelem, 0, (float *) array, anynul, status); else ffgpve(fptr, 1, firstelem, nelem, *(float *) nulval, (float *) array, anynul, status); } else if (datatype == TDOUBLE) { if (nulval == 0) ffgpvd(fptr, 1, firstelem, nelem, 0, (double *) array, anynul, status); else { ffgpvd(fptr, 1, firstelem, nelem, *(double *) nulval, (double *) array, anynul, status); } } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgpf( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of null value flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). The nullarray values will = 1 if the corresponding array value is null. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (datatype == TBYTE) { ffgpfb(fptr, 1, firstelem, nelem, (unsigned char *) array, nullarray, anynul, status); } else if (datatype == TSBYTE) { ffgpfsb(fptr, 1, firstelem, nelem, (signed char *) array, nullarray, anynul, status); } else if (datatype == TUSHORT) { ffgpfui(fptr, 1, firstelem, nelem, (unsigned short *) array, nullarray, anynul, status); } else if (datatype == TSHORT) { ffgpfi(fptr, 1, firstelem, nelem, (short *) array, nullarray, anynul, status); } else if (datatype == TUINT) { ffgpfuk(fptr, 1, firstelem, nelem, (unsigned int *) array, nullarray, anynul, status); } else if (datatype == TINT) { ffgpfk(fptr, 1, firstelem, nelem, (int *) array, nullarray, anynul, status); } else if (datatype == TULONG) { ffgpfuj(fptr, 1, firstelem, nelem, (unsigned long *) array, nullarray, anynul, status); } else if (datatype == TLONG) { ffgpfj(fptr, 1, firstelem, nelem, (long *) array, nullarray, anynul, status); } else if (datatype == TLONGLONG) { ffgpfjj(fptr, 1, firstelem, nelem, (LONGLONG *) array, nullarray, anynul, status); } else if (datatype == TFLOAT) { ffgpfe(fptr, 1, firstelem, nelem, (float *) array, nullarray, anynul, status); } else if (datatype == TDOUBLE) { ffgpfd(fptr, 1, firstelem, nelem, (double *) array, nullarray, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgcv( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a table column. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of true if any pixels are undefined. */ { char cdummy[2]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TBIT) { ffgcx(fptr, colnum, firstrow, firstelem, nelem, (char *) array, status); } else if (datatype == TBYTE) { if (nulval == 0) ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (unsigned char *) array, cdummy, anynul, status); else ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(unsigned char *) nulval, (unsigned char *) array, cdummy, anynul, status); } else if (datatype == TSBYTE) { if (nulval == 0) ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (signed char *) array, cdummy, anynul, status); else ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(signed char *) nulval, (signed char *) array, cdummy, anynul, status); } else if (datatype == TUSHORT) { if (nulval == 0) ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (unsigned short *) array, cdummy, anynul, status); else ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(unsigned short *) nulval, (unsigned short *) array, cdummy, anynul, status); } else if (datatype == TSHORT) { if (nulval == 0) ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (short *) array, cdummy, anynul, status); else ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(short *) nulval, (short *) array, cdummy, anynul, status); } else if (datatype == TUINT) { if (nulval == 0) ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (unsigned int *) array, cdummy, anynul, status); else ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(unsigned int *) nulval, (unsigned int *) array, cdummy, anynul, status); } else if (datatype == TINT) { if (nulval == 0) ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (int *) array, cdummy, anynul, status); else ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(int *) nulval, (int *) array, cdummy, anynul, status); } else if (datatype == TULONG) { if (nulval == 0) ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (unsigned long *) array, cdummy, anynul, status); else ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(unsigned long *) nulval, (unsigned long *) array, cdummy, anynul, status); } else if (datatype == TLONG) { if (nulval == 0) ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (long *) array, cdummy, anynul, status); else ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(long *) nulval, (long *) array, cdummy, anynul, status); } else if (datatype == TLONGLONG) { if (nulval == 0) ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0, (LONGLONG *) array, cdummy, anynul, status); else ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(LONGLONG *) nulval, (LONGLONG *) array, cdummy, anynul, status); } else if (datatype == TFLOAT) { if (nulval == 0) ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0., (float *) array, cdummy, anynul, status); else ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(float *) nulval,(float *) array, cdummy, anynul, status); } else if (datatype == TDOUBLE) { if (nulval == 0) ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 1, 0., (double *) array, cdummy, anynul, status); else ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 1, *(double *) nulval, (double *) array, cdummy, anynul, status); } else if (datatype == TCOMPLEX) { if (nulval == 0) ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, 0., (float *) array, cdummy, anynul, status); else ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, *(float *) nulval, (float *) array, cdummy, anynul, status); } else if (datatype == TDBLCOMPLEX) { if (nulval == 0) ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, 0., (double *) array, cdummy, anynul, status); else ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, *(double *) nulval, (double *) array, cdummy, anynul, status); } else if (datatype == TLOGICAL) { if (nulval == 0) ffgcll(fptr, colnum, firstrow, firstelem, nelem, 1, 0, (char *) array, cdummy, anynul, status); else ffgcll(fptr, colnum, firstrow, firstelem, nelem, 1, *(char *) nulval, (char *) array, cdummy, anynul, status); } else if (datatype == TSTRING) { if (nulval == 0) { cdummy[0] = '\0'; ffgcls(fptr, colnum, firstrow, firstelem, nelem, 1, cdummy, (char **) array, cdummy, anynul, status); } else ffgcls(fptr, colnum, firstrow, firstelem, nelem, 1, (char *) nulval, (char **) array, cdummy, anynul, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffgcf( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of null value flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a table column. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). ANYNUL is returned with a value of true if any pixels are undefined. */ { void *nulval; /* dummy argument */ double dnulval = 0.; if (*status > 0) /* inherit input status value if > 0 */ return(*status); nulval = &dnulval; /* set to a harmless value; this is never used */ if (datatype == TBIT) { ffgcx(fptr, colnum, firstrow, firstelem, nelem, (char *) array, status); } else if (datatype == TBYTE) { ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(unsigned char *) nulval, (unsigned char *) array, nullarray, anynul, status); } else if (datatype == TSBYTE) { ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(signed char *) nulval, (signed char *) array, nullarray, anynul, status); } else if (datatype == TUSHORT) { ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(unsigned short *) nulval, (unsigned short *) array, nullarray, anynul, status); } else if (datatype == TSHORT) { ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(short *) nulval, (short *) array, nullarray, anynul, status); } else if (datatype == TUINT) { ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(unsigned int *) nulval, (unsigned int *) array, nullarray, anynul, status); } else if (datatype == TINT) { ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(int *) nulval, (int *) array, nullarray, anynul, status); } else if (datatype == TULONG) { ffgcluj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(unsigned long *) nulval, (unsigned long *) array, nullarray, anynul, status); } else if (datatype == TLONG) { ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(long *) nulval, (long *) array, nullarray, anynul, status); } else if (datatype == TLONGLONG) { ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(LONGLONG *) nulval, (LONGLONG *) array, nullarray, anynul, status); } else if (datatype == TFLOAT) { ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(float *) nulval,(float *) array, nullarray, anynul, status); } else if (datatype == TDOUBLE) { ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 2, *(double *) nulval, (double *) array, nullarray, anynul, status); } else if (datatype == TCOMPLEX) { ffgcfc(fptr, colnum, firstrow, firstelem, nelem, (float *) array, nullarray, anynul, status); } else if (datatype == TDBLCOMPLEX) { ffgcfm(fptr, colnum, firstrow, firstelem, nelem, (double *) array, nullarray, anynul, status); } else if (datatype == TLOGICAL) { ffgcll(fptr, colnum, firstrow, firstelem, nelem, 2, *(char *) nulval, (char *) array, nullarray, anynul, status); } else if (datatype == TSTRING) { ffgcls(fptr, colnum, firstrow, firstelem, nelem, 2, (char *) nulval, (char **) array, nullarray, anynul, status); } else *status = BAD_DATATYPE; return(*status); } indi-0.5/src/cfitsio/eval_y.c0000644000175000017500000070632110610474374014002 0ustar jrjr /* A Bison parser, made from eval.y by GNU Bison version 1.25 */ #define FFBISON 1 /* Identify Bison output. */ #define BOOLEAN 258 #define LONG 259 #define DOUBLE 260 #define STRING 261 #define BITSTR 262 #define FUNCTION 263 #define BFUNCTION 264 #define GTIFILTER 265 #define REGFILTER 266 #define COLUMN 267 #define BCOLUMN 268 #define SCOLUMN 269 #define BITCOL 270 #define ROWREF 271 #define NULLREF 272 #define SNULLREF 273 #define OR 274 #define AND 275 #define EQ 276 #define NE 277 #define GT 278 #define LT 279 #define LTE 280 #define GTE 281 #define POWER 282 #define NOT 283 #define INTCAST 284 #define FLTCAST 285 #define UMINUS 286 #define ACCUM 287 #define DIFF 288 #line 1 "eval.y" /************************************************************************/ /* */ /* CFITSIO Lexical Parser */ /* */ /* This file is one of 3 files containing code which parses an */ /* arithmetic expression and evaluates it in the context of an input */ /* FITS file table extension. The CFITSIO lexical parser is divided */ /* into the following 3 parts/files: the CFITSIO "front-end", */ /* eval_f.c, contains the interface between the user/CFITSIO and the */ /* real core of the parser; the FLEX interpreter, eval_l.c, takes the */ /* input string and parses it into tokens and identifies the FITS */ /* information required to evaluate the expression (ie, keywords and */ /* columns); and, the BISON grammar and evaluation routines, eval_y.c, */ /* receives the FLEX output and determines and performs the actual */ /* operations. The files eval_l.c and eval_y.c are produced from */ /* running flex and bison on the files eval.l and eval.y, respectively. */ /* (flex and bison are available from any GNU archive: see www.gnu.org) */ /* */ /* The grammar rules, rather than evaluating the expression in situ, */ /* builds a tree, or Nodal, structure mapping out the order of */ /* operations and expression dependencies. This "compilation" process */ /* allows for much faster processing of multiple rows. This technique */ /* was developed by Uwe Lammers of the XMM Science Analysis System, */ /* although the CFITSIO implementation is entirely code original. */ /* */ /* */ /* Modification History: */ /* */ /* Kent Blackburn c1992 Original parser code developed for the */ /* FTOOLS software package, in particular, */ /* the fselect task. */ /* Kent Blackburn c1995 BIT column support added */ /* Peter D Wilson Feb 1998 Vector column support added */ /* Peter D Wilson May 1998 Ported to CFITSIO library. User */ /* interface routines written, in essence */ /* making fselect, fcalc, and maketime */ /* capabilities available to all tools */ /* via single function calls. */ /* Peter D Wilson Jun 1998 Major rewrite of parser core, so as to */ /* create a run-time evaluation tree, */ /* inspired by the work of Uwe Lammers, */ /* resulting in a speed increase of */ /* 10-100 times. */ /* Peter D Wilson Jul 1998 gtifilter(a,b,c,d) function added */ /* Peter D Wilson Aug 1998 regfilter(a,b,c,d) function added */ /* Peter D Wilson Jul 1999 Make parser fitsfile-independent, */ /* allowing a purely vector-based usage */ /* Craig B Markwardt Jun 2004 Add MEDIAN() function */ /* Craig B Markwardt Jun 2004 Add SUM(), and MIN/MAX() for bit arrays */ /* Craig B Markwardt Jun 2004 Allow subscripting of nX bit arrays */ /* Craig B Markwardt Jun 2004 Implement statistical functions */ /* NVALID(), AVERAGE(), and STDDEV() */ /* for integer and floating point vectors */ /* Craig B Markwardt Jun 2004 Use NULL values for range errors instead*/ /* of throwing a parse error */ /* Craig B Markwardt Oct 2004 Add ACCUM() and SEQDIFF() functions */ /* Craig B Markwardt Feb 2005 Add ANGSEP() function */ /* Craig B Markwardt Aug 2005 CIRCLE, BOX, ELLIPSE, NEAR and REGFILTER*/ /* functions now accept vector arguments */ /* */ /************************************************************************/ #define APPROX 1.0e-7 #include "eval_defs.h" #include "region.h" #include #include #ifndef alloca #define alloca malloc #endif /* Shrink the initial stack depth to keep local data <32K (mac limit) */ /* yacc will allocate more space if needed, though. */ #define FFINITDEPTH 100 /***************************************************************/ /* Replace Bison's BACKUP macro with one that fixes a bug -- */ /* must update state after popping the stack -- and allows */ /* popping multiple terms at one time. */ /***************************************************************/ #define FFNEWBACKUP(token, value) \ do \ if (ffchar == FFEMPTY ) \ { ffchar = (token); \ memcpy( &fflval, &(value), sizeof(value) ); \ ffchar1 = FFTRANSLATE (ffchar); \ while (fflen--) FFPOPSTACK; \ ffstate = *ffssp; \ goto ffbackup; \ } \ else \ { fferror ("syntax error: cannot back up"); FFERROR; } \ while (0) /***************************************************************/ /* Useful macros for accessing/testing Nodes */ /***************************************************************/ #define TEST(a) if( (a)<0 ) FFERROR #define SIZE(a) gParse.Nodes[ a ].value.nelem #define TYPE(a) gParse.Nodes[ a ].type #define PROMOTE(a,b) if( TYPE(a) > TYPE(b) ) \ b = New_Unary( TYPE(a), 0, b ); \ else if( TYPE(a) < TYPE(b) ) \ a = New_Unary( TYPE(b), 0, a ); /***** Internal functions *****/ #ifdef __cplusplus extern "C" { #endif static int Alloc_Node ( void ); static void Free_Last_Node( void ); static void Evaluate_Node ( int thisNode ); static int New_Const ( int returnType, void *value, long len ); static int New_Column( int ColNum ); static int New_Offset( int ColNum, int offset ); static int New_Unary ( int returnType, int Op, int Node1 ); static int New_BinOp ( int returnType, int Node1, int Op, int Node2 ); static int New_Func ( int returnType, funcOp Op, int nNodes, int Node1, int Node2, int Node3, int Node4, int Node5, int Node6, int Node7 ); static int New_Deref ( int Var, int nDim, int Dim1, int Dim2, int Dim3, int Dim4, int Dim5 ); static int New_GTI ( char *fname, int Node1, char *start, char *stop ); static int New_REG ( char *fname, int NodeX, int NodeY, char *colNames ); static int New_Vector( int subNode ); static int Close_Vec ( int vecNode ); static int Locate_Col( Node *this ); static int Test_Dims ( int Node1, int Node2 ); static void Copy_Dims ( int Node1, int Node2 ); static void Allocate_Ptrs( Node *this ); static void Do_Unary ( Node *this ); static void Do_Offset ( Node *this ); static void Do_BinOp_bit ( Node *this ); static void Do_BinOp_str ( Node *this ); static void Do_BinOp_log ( Node *this ); static void Do_BinOp_lng ( Node *this ); static void Do_BinOp_dbl ( Node *this ); static void Do_Func ( Node *this ); static void Do_Deref ( Node *this ); static void Do_GTI ( Node *this ); static void Do_REG ( Node *this ); static void Do_Vector ( Node *this ); static long Search_GTI ( double evtTime, long nGTI, double *start, double *stop, int ordered ); static char saobox (double xcen, double ycen, double xwid, double ywid, double rot, double xcol, double ycol); static char ellipse(double xcen, double ycen, double xrad, double yrad, double rot, double xcol, double ycol); static char circle (double xcen, double ycen, double rad, double xcol, double ycol); static char bnear (double x, double y, double tolerance); static char bitcmp (char *bitstrm1, char *bitstrm2); static char bitlgte(char *bits1, int oper, char *bits2); static void bitand(char *result, char *bitstrm1, char *bitstrm2); static void bitor (char *result, char *bitstrm1, char *bitstrm2); static void bitnot(char *result, char *bits); static void fferror(char *msg); #ifdef __cplusplus } #endif #line 178 "eval.y" typedef union { int Node; /* Index of Node */ double dbl; /* real value */ long lng; /* integer value */ char log; /* logical value */ char str[256]; /* string value */ } FFSTYPE; #include #ifndef __cplusplus #ifndef __STDC__ #define const #endif #endif #define FFFINAL 281 #define FFFLAG -32768 #define FFNTBASE 53 #define FFTRANSLATE(x) ((unsigned)(x) <= 288 ? fftranslate[x] : 61) static const char fftranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 40, 2, 51, 52, 37, 34, 19, 35, 2, 38, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, 2, 2, 20, 2, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 50, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 39, 23, 29, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 25, 26, 27, 28, 30, 31, 32, 33, 41, 42, 43, 44, 45, 47, 48 }; #if FFDEBUG != 0 static const short ffprhs[] = { 0, 0, 1, 4, 6, 9, 12, 15, 18, 21, 24, 28, 31, 35, 39, 43, 46, 49, 51, 53, 58, 62, 66, 70, 75, 82, 91, 102, 115, 118, 122, 124, 126, 128, 133, 135, 137, 141, 145, 149, 153, 157, 161, 164, 167, 171, 175, 179, 185, 191, 197, 200, 204, 208, 212, 216, 222, 232, 237, 244, 253, 264, 277, 280, 283, 286, 289, 291, 293, 298, 302, 306, 310, 314, 318, 322, 326, 330, 334, 338, 342, 346, 350, 354, 358, 362, 366, 370, 374, 378, 382, 386, 390, 396, 402, 406, 410, 414, 420, 428, 440, 456, 459, 463, 469, 479, 483, 491, 501, 506, 513, 522, 533, 546, 549, 553, 555, 557, 562, 564, 568, 572, 578 }; static const short ffrhs[] = { -1, 53, 54, 0, 49, 0, 57, 49, 0, 58, 49, 0, 60, 49, 0, 59, 49, 0, 1, 49, 0, 22, 58, 0, 55, 19, 58, 0, 22, 57, 0, 56, 19, 57, 0, 56, 19, 58, 0, 55, 19, 57, 0, 56, 23, 0, 55, 23, 0, 7, 0, 15, 0, 15, 22, 57, 23, 0, 59, 40, 59, 0, 59, 39, 59, 0, 59, 34, 59, 0, 59, 46, 57, 50, 0, 59, 46, 57, 19, 57, 50, 0, 59, 46, 57, 19, 57, 19, 57, 50, 0, 59, 46, 57, 19, 57, 19, 57, 19, 57, 50, 0, 59, 46, 57, 19, 57, 19, 57, 19, 57, 19, 57, 50, 0, 42, 59, 0, 51, 59, 52, 0, 4, 0, 5, 0, 12, 0, 12, 22, 57, 23, 0, 16, 0, 17, 0, 57, 36, 57, 0, 57, 34, 57, 0, 57, 35, 57, 0, 57, 37, 57, 0, 57, 38, 57, 0, 57, 41, 57, 0, 34, 57, 0, 35, 57, 0, 51, 57, 52, 0, 57, 37, 58, 0, 58, 37, 57, 0, 58, 24, 57, 21, 57, 0, 58, 24, 58, 21, 57, 0, 58, 24, 57, 21, 58, 0, 8, 52, 0, 8, 58, 52, 0, 8, 60, 52, 0, 8, 59, 52, 0, 8, 57, 52, 0, 8, 57, 19, 57, 52, 0, 8, 57, 19, 57, 19, 57, 19, 57, 52, 0, 57, 46, 57, 50, 0, 57, 46, 57, 19, 57, 50, 0, 57, 46, 57, 19, 57, 19, 57, 50, 0, 57, 46, 57, 19, 57, 19, 57, 19, 57, 50, 0, 57, 46, 57, 19, 57, 19, 57, 19, 57, 19, 57, 50, 0, 43, 57, 0, 43, 58, 0, 44, 57, 0, 44, 58, 0, 3, 0, 13, 0, 13, 22, 57, 23, 0, 59, 27, 59, 0, 59, 28, 59, 0, 59, 31, 59, 0, 59, 32, 59, 0, 59, 30, 59, 0, 59, 33, 59, 0, 57, 30, 57, 0, 57, 31, 57, 0, 57, 33, 57, 0, 57, 32, 57, 0, 57, 29, 57, 0, 57, 27, 57, 0, 57, 28, 57, 0, 60, 27, 60, 0, 60, 28, 60, 0, 60, 30, 60, 0, 60, 33, 60, 0, 60, 31, 60, 0, 60, 32, 60, 0, 58, 26, 58, 0, 58, 25, 58, 0, 58, 27, 58, 0, 58, 28, 58, 0, 57, 20, 57, 21, 57, 0, 58, 24, 58, 21, 58, 0, 9, 57, 52, 0, 9, 58, 52, 0, 9, 60, 52, 0, 8, 58, 19, 58, 52, 0, 9, 57, 19, 57, 19, 57, 52, 0, 9, 57, 19, 57, 19, 57, 19, 57, 19, 57, 52, 0, 9, 57, 19, 57, 19, 57, 19, 57, 19, 57, 19, 57, 19, 57, 52, 0, 10, 52, 0, 10, 6, 52, 0, 10, 6, 19, 57, 52, 0, 10, 6, 19, 57, 19, 6, 19, 6, 52, 0, 11, 6, 52, 0, 11, 6, 19, 57, 19, 57, 52, 0, 11, 6, 19, 57, 19, 57, 19, 6, 52, 0, 58, 46, 57, 50, 0, 58, 46, 57, 19, 57, 50, 0, 58, 46, 57, 19, 57, 19, 57, 50, 0, 58, 46, 57, 19, 57, 19, 57, 19, 57, 50, 0, 58, 46, 57, 19, 57, 19, 57, 19, 57, 19, 57, 50, 0, 42, 58, 0, 51, 58, 52, 0, 6, 0, 14, 0, 14, 22, 57, 23, 0, 18, 0, 51, 60, 52, 0, 60, 34, 60, 0, 58, 24, 60, 21, 60, 0, 8, 60, 19, 60, 52, 0 }; #endif #if FFDEBUG != 0 static const short ffrline[] = { 0, 229, 230, 233, 234, 240, 246, 252, 258, 261, 263, 276, 278, 291, 302, 316, 320, 324, 329, 331, 340, 343, 346, 349, 351, 353, 355, 357, 359, 362, 366, 368, 370, 372, 381, 383, 385, 388, 391, 394, 397, 400, 403, 405, 407, 409, 413, 417, 436, 455, 474, 487, 501, 513, 538, 625, 677, 701, 703, 705, 707, 709, 711, 713, 715, 717, 721, 723, 725, 734, 737, 740, 743, 746, 749, 752, 755, 758, 761, 764, 767, 770, 773, 776, 779, 782, 785, 788, 791, 793, 795, 797, 800, 807, 824, 837, 850, 861, 877, 901, 929, 966, 970, 974, 977, 981, 985, 988, 992, 994, 996, 998, 1000, 1002, 1004, 1008, 1011, 1013, 1022, 1024, 1026, 1029, 1041 }; #endif #if FFDEBUG != 0 || defined (FFERROR_VERBOSE) static const char * const fftname[] = { "$","error","$undefined.","BOOLEAN", "LONG","DOUBLE","STRING","BITSTR","FUNCTION","BFUNCTION","GTIFILTER","REGFILTER", "COLUMN","BCOLUMN","SCOLUMN","BITCOL","ROWREF","NULLREF","SNULLREF","','","'='", "':'","'{'","'}'","'?'","OR","AND","EQ","NE","'~'","GT","LT","LTE","GTE","'+'", "'-'","'%'","'*'","'/'","'|'","'&'","POWER","NOT","INTCAST","FLTCAST","UMINUS", "'['","ACCUM","DIFF","'\\n'","']'","'('","')'","lines","line","bvector","vector", "expr","bexpr","bits","sexpr", NULL }; #endif static const short ffr1[] = { 0, 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 56, 56, 56, 56, 57, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 60, 60, 60, 60, 60, 60, 60, 60 }; static const short ffr2[] = { 0, 0, 2, 1, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 2, 2, 1, 1, 4, 3, 3, 3, 4, 6, 8, 10, 12, 2, 3, 1, 1, 1, 4, 1, 1, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 5, 5, 5, 2, 3, 3, 3, 3, 5, 9, 4, 6, 8, 10, 12, 2, 2, 2, 2, 1, 1, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 3, 3, 3, 5, 7, 11, 15, 2, 3, 5, 9, 3, 7, 9, 4, 6, 8, 10, 12, 2, 3, 1, 1, 4, 1, 3, 3, 5, 5 }; static const short ffdefact[] = { 1, 0, 0, 66, 30, 31, 115, 17, 0, 0, 0, 0, 32, 67, 116, 18, 34, 35, 118, 0, 0, 0, 0, 0, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 8, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 11, 9, 0, 42, 0, 43, 0, 113, 28, 62, 63, 64, 65, 0, 0, 0, 0, 0, 16, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 6, 0, 54, 0, 51, 53, 0, 52, 0, 94, 95, 96, 0, 102, 0, 105, 0, 0, 0, 0, 44, 114, 29, 119, 14, 10, 12, 13, 0, 80, 81, 79, 75, 76, 78, 77, 37, 38, 36, 39, 45, 40, 41, 0, 0, 0, 0, 89, 88, 90, 91, 46, 0, 0, 0, 69, 70, 73, 71, 72, 74, 22, 21, 20, 0, 82, 83, 84, 86, 87, 85, 120, 0, 0, 0, 0, 0, 0, 33, 68, 117, 19, 0, 0, 57, 0, 0, 0, 0, 108, 28, 0, 0, 23, 0, 55, 97, 122, 0, 0, 103, 0, 92, 0, 47, 49, 48, 93, 121, 0, 0, 0, 0, 0, 0, 0, 58, 0, 109, 0, 24, 0, 0, 98, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 110, 0, 25, 56, 0, 104, 107, 0, 0, 0, 0, 0, 60, 0, 111, 0, 26, 0, 99, 0, 0, 0, 0, 61, 112, 27, 0, 0, 100, 0, 0 }; static const short ffdefgoto[] = { 1, 27, 28, 29, 57, 55, 42, 53 }; static const short ffpact[] = {-32768, 294, -20,-32768,-32768,-32768,-32768,-32768, 343, 393, -2, 24, 2, 33, 41, 43,-32768,-32768,-32768, 393, 393, 393, 393, 393, 393,-32768, 393,-32768, 8, 67, 1056, 213, 1336, -17,-32768,-32768, 419, 16, 287, 122, 447, 72, 1376, 389, -14,-32768, -13, 393, 393, 393, 393, 1303, 218, 1423, 45, 218, 45, 1303, 57, 59, 45, 57, 45, 57, 614, 140, 336, 1320, 393,-32768, 393, -32768, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393,-32768, 393, 393, 393, 393, 393, 393, 393,-32768, -6, -6, -6, -6, -6, -6, -6, -6, -6, 393,-32768, 393, 393, 393, 393, 393, 393, 393,-32768, 393,-32768, 393,-32768,-32768, 393, -32768, 393,-32768,-32768,-32768, 393,-32768, 393,-32768, 1179, 1199, 1219, 1239,-32768,-32768,-32768,-32768, 1303, 218, 1303, 218, 1261, 1393, 1393, 1393, 1406, 1406, 1406, 1406, 134, 134, 134, 15, 57, 15, 15, 696, 1283, 245, 247, 132, -25, -9, -9, 15, 720, -6, -6, 20, 20, 20, 20, 20, 20, 49, 59, 59, 744, 253, 253, 73, 73, 73, 73,-32768, 475, 163, 1328, 1079, 503, 1099,-32768,-32768,-32768,-32768, 393, 393,-32768, 393, 393, 393, 393,-32768, 59, 18, 393,-32768, 393,-32768,-32768, -32768, 393, 100,-32768, 393, 1359, 768, 1359, 218, 1359, 218, 1423, 792, 816, 1119, 531, 89, 559, 393,-32768, 393,-32768, 393,-32768, 393, 393,-32768, 104, 105,-32768, 840, 864, 888, 641, 1139, 68, 71, 393,-32768, 393, -32768, 393,-32768,-32768, 393,-32768,-32768, 912, 936, 960, 587, 393,-32768, 393,-32768, 393,-32768, 393,-32768, 984, 1008, 1032, 1159,-32768,-32768,-32768, 393, 668,-32768, 126, -32768 }; static const short ffpgoto[] = {-32768, -32768,-32768,-32768, -1, 93, 121, 25 }; #define FFLAST 1457 static const short fftable[] = { 30, 7, 91, 92, 44, 126, 128, 36, 40, 15, 107, 108, 93, 109, 110, 111, 112, 113, 51, 54, 56, 94, 60, 62, 47, 64, 33, 68, 93, 34, 46, 69, 114, 39, 43, 117, 167, 94, 127, 129, 88, 89, 90, 91, 92, 168, 130, 131, 132, 133, 45, 67, 102, 93, 102, 48, 85, 103, 104, 103, 104, 86, 94, 49, 105, 50, 105, 138, 118, 140, 136, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 155, 156, 157, 70, 158, 103, 104, 71, 86, 165, 166, 31, 105, 88, 89, 90, 91, 92, 37, 41, 94, 178, 105, 227, 113, 238, 93, 246, 247, 52, 160, 186, 58, 61, 63, 94, 65, 256, 189, 32, 257, 124, 190, 281, 191, 0, 38, 0, 0, 179, 180, 181, 182, 183, 184, 185, 0, 0, 120, 0, 59, 0, 188, 0, 66, 0, 107, 108, 0, 109, 110, 111, 112, 113, 0, 90, 91, 92, 139, 0, 141, 88, 89, 90, 91, 92, 93, 0, 83, 84, 0, 121, 85, 154, 93, 94, 0, 86, 159, 161, 162, 163, 164, 94, 88, 89, 90, 91, 92, 135, 0, 0, 216, 217, 0, 218, 220, 93, 223, 0, 0, 0, 224, 0, 225, 0, 94, 187, 226, 0, 0, 228, 210, 0, 169, 170, 171, 172, 173, 174, 175, 176, 177, 222, 0, 241, 0, 242, 0, 243, 0, 244, 245, 0, 88, 89, 90, 91, 92, 88, 89, 90, 91, 92, 258, 0, 259, 93, 260, 0, 0, 261, 93, 0, 0, 0, 94, 0, 270, 95, 271, 94, 272, 200, 273, 201, 88, 89, 90, 91, 92, 107, 108, 278, 109, 110, 111, 112, 113, 93, 109, 110, 111, 112, 113, 204, 205, 0, 94, 219, 221, 280, 2, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 96, 97, 19, 98, 99, 100, 101, 102, 0, 0, 0, 0, 103, 104, 20, 21, 0, 0, 0, 105, 0, 0, 22, 23, 24, 119, 0, 0, 0, 25, 0, 26, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 96, 97, 19, 98, 99, 100, 101, 102, 0, 0, 0, 0, 103, 104, 20, 21, 0, 0, 0, 105, 0, 0, 22, 23, 24, 136, 0, 0, 0, 0, 0, 26, 35, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 19, 107, 108, 0, 109, 110, 111, 112, 113, 0, 0, 0, 20, 21, 0, 0, 0, 0, 0, 0, 22, 23, 24, 115, 72, 0, 125, 0, 0, 26, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 122, 72, 0, 0, 0, 116, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 208, 72, 0, 0, 0, 123, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 213, 72, 0, 0, 0, 209, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 236, 72, 0, 0, 0, 214, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 239, 72, 0, 0, 0, 237, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 268, 72, 0, 0, 0, 240, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 72, 0, 0, 0, 0, 269, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 72, 0, 0, 0, 0, 134, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 72, 0, 0, 0, 0, 254, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 197, 72, 0, 0, 0, 279, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 202, 72, 0, 86, 0, 0, 0, 198, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 206, 72, 0, 86, 0, 0, 0, 203, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 229, 72, 0, 86, 0, 0, 0, 207, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 231, 72, 0, 86, 0, 0, 0, 230, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 233, 72, 0, 86, 0, 0, 0, 232, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 248, 72, 0, 86, 0, 0, 0, 234, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 250, 72, 0, 86, 0, 0, 0, 249, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 252, 72, 0, 86, 0, 0, 0, 251, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 262, 72, 0, 86, 0, 0, 0, 253, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 264, 72, 0, 86, 0, 0, 0, 263, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 266, 72, 0, 86, 0, 0, 0, 265, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 72, 0, 86, 0, 0, 0, 267, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 72, 0, 86, 0, 0, 0, 274, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 72, 0, 86, 0, 0, 0, 275, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 72, 0, 86, 0, 0, 0, 276, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 212, 72, 0, 0, 86, 0, 0, 87, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 215, 72, 85, 0, 0, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 235, 72, 85, 0, 0, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 255, 72, 85, 0, 0, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 277, 72, 85, 0, 0, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 72, 85, 0, 192, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 72, 85, 0, 193, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 72, 85, 0, 194, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 72, 85, 0, 195, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 72, 196, 0, 0, 86, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 72, 199, 0, 0, 86, 0, 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 72, 85, 0, 0, 0, 0, 86, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 107, 108, 86, 109, 110, 111, 112, 113, 107, 108, 0, 109, 110, 111, 112, 113, 96, 97, 0, 98, 99, 100, 101, 102, 0, 137, 0, 0, 103, 104, 0, 0, 0, 211, 0, 105, 0, 0, 106, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 96, 97, 86, 98, 99, 100, 101, 102, 0, 0, 0, 0, 103, 104, 0, 0, 0, 0, 0, 105, 76, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 0, 0, 86, 80, 81, 82, 83, 84, 0, 0, 85, 0, 0, 107, 108, 86, 109, 110, 111, 112, 113 }; static const short ffcheck[] = { 1, 7, 27, 28, 6, 19, 19, 8, 9, 15, 27, 28, 37, 30, 31, 32, 33, 34, 19, 20, 21, 46, 23, 24, 22, 26, 1, 19, 37, 49, 6, 23, 49, 8, 9, 19, 42, 46, 52, 52, 24, 25, 26, 27, 28, 51, 47, 48, 49, 50, 52, 26, 34, 37, 34, 22, 41, 39, 40, 39, 40, 46, 46, 22, 46, 22, 46, 68, 52, 70, 52, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 19, 88, 39, 40, 23, 46, 93, 94, 1, 46, 24, 25, 26, 27, 28, 8, 9, 46, 105, 46, 6, 34, 19, 37, 6, 6, 19, 88, 115, 22, 23, 24, 46, 26, 52, 122, 1, 52, 52, 126, 0, 128, -1, 8, -1, -1, 107, 108, 109, 110, 111, 112, 113, -1, -1, 19, -1, 22, -1, 120, -1, 26, -1, 27, 28, -1, 30, 31, 32, 33, 34, -1, 26, 27, 28, 68, -1, 70, 24, 25, 26, 27, 28, 37, -1, 37, 38, -1, 52, 41, 83, 37, 46, -1, 46, 88, 89, 90, 91, 92, 46, 24, 25, 26, 27, 28, 52, -1, -1, 196, 197, -1, 199, 200, 37, 202, -1, -1, -1, 206, -1, 208, -1, 46, 117, 212, -1, -1, 215, 52, -1, 96, 97, 98, 99, 100, 101, 102, 103, 104, 201, -1, 229, -1, 231, -1, 233, -1, 235, 236, -1, 24, 25, 26, 27, 28, 24, 25, 26, 27, 28, 248, -1, 250, 37, 252, -1, -1, 255, 37, -1, -1, -1, 46, -1, 262, 49, 264, 46, 266, 21, 268, 21, 24, 25, 26, 27, 28, 27, 28, 277, 30, 31, 32, 33, 34, 37, 30, 31, 32, 33, 34, 167, 168, -1, 46, 199, 200, 0, 1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, 27, 28, 22, 30, 31, 32, 33, 34, -1, -1, -1, -1, 39, 40, 34, 35, -1, -1, -1, 46, -1, -1, 42, 43, 44, 52, -1, -1, -1, 49, -1, 51, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, 27, 28, 22, 30, 31, 32, 33, 34, -1, -1, -1, -1, 39, 40, 34, 35, -1, -1, -1, 46, -1, -1, 42, 43, 44, 52, -1, -1, -1, -1, -1, 51, 52, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, 22, 27, 28, -1, 30, 31, 32, 33, 34, -1, -1, -1, 34, 35, -1, -1, -1, -1, -1, -1, 42, 43, 44, 19, 20, -1, 52, -1, -1, 51, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 20, -1, -1, -1, -1, 52, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 20, -1, -1, -1, -1, 52, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 20, -1, -1, -1, -1, 52, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 19, 20, -1, -1, -1, 52, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, 19, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 20, -1, 46, -1, -1, -1, 50, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, 19, 20, -1, -1, 46, -1, -1, 49, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 19, 20, 41, -1, -1, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 19, 20, 41, -1, -1, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 19, 20, 41, -1, -1, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 19, 20, 41, -1, -1, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, 20, 41, -1, 23, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, 20, 41, -1, 23, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, 20, 41, -1, 23, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, 20, 41, -1, 23, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, 20, 21, -1, -1, 46, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, 20, 21, -1, -1, 46, -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, 20, 41, -1, -1, -1, -1, 46, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 27, 28, 46, 30, 31, 32, 33, 34, 27, 28, -1, 30, 31, 32, 33, 34, 27, 28, -1, 30, 31, 32, 33, 34, -1, 52, -1, -1, 39, 40, -1, -1, -1, 52, -1, 46, -1, -1, 49, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 27, 28, 46, 30, 31, 32, 33, 34, -1, -1, -1, -1, 39, 40, -1, -1, -1, -1, -1, 46, 30, 31, 32, 33, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, -1, -1, 46, 34, 35, 36, 37, 38, -1, -1, 41, -1, -1, 27, 28, 46, 30, 31, 32, 33, 34 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/usr1/local/share/bison.simple" /* Skeleton output parser for bison, Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. This special exception was added by the Free Software Foundation in version 1.24 of Bison. */ #ifndef alloca #ifdef __GNUC__ #define alloca __builtin_alloca #else /* not GNU C. */ #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) #include #else /* not sparc */ #if defined (MSDOS) && !defined (__TURBOC__) #include #else /* not MSDOS, or __TURBOC__ */ #if defined(_AIX) #include #pragma alloca #else /* not MSDOS, __TURBOC__, or _AIX */ #ifdef __hpux #ifdef __cplusplus extern "C" { void *alloca (unsigned int); }; #else /* not __cplusplus */ void *alloca (); #endif /* not __cplusplus */ #endif /* __hpux */ #endif /* not _AIX */ #endif /* not MSDOS, or __TURBOC__ */ #endif /* not sparc. */ #endif /* not GNU C. */ #endif /* alloca not defined. */ /* This is the parser code that is written into each bison parser when the %semantic_parser declaration is not specified in the grammar. It was written by Richard Stallman by simplifying the hairy parser used when %semantic_parser is specified. */ /* Note: there must be only one dollar sign in this file. It is replaced by the list of actions, each action as one case of the switch. */ #define fferrok (fferrstatus = 0) #define ffclearin (ffchar = FFEMPTY) #define FFEMPTY -2 #define FFEOF 0 #define FFACCEPT return(0) #define FFABORT return(1) #define FFERROR goto fferrlab1 /* Like FFERROR except do call fferror. This remains here temporarily to ease the transition to the new meaning of FFERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define FFFAIL goto fferrlab #define FFRECOVERING() (!!fferrstatus) #define FFBACKUP(token, value) \ do \ if (ffchar == FFEMPTY && fflen == 1) \ { ffchar = (token), fflval = (value); \ ffchar1 = FFTRANSLATE (ffchar); \ FFPOPSTACK; \ goto ffbackup; \ } \ else \ { fferror ("syntax error: cannot back up"); FFERROR; } \ while (0) #define FFTERROR 1 #define FFERRCODE 256 #ifndef FFPURE #define FFLEX fflex() #endif #ifdef FFPURE #ifdef FFLSP_NEEDED #ifdef FFLEX_PARAM #define FFLEX fflex(&fflval, &fflloc, FFLEX_PARAM) #else #define FFLEX fflex(&fflval, &fflloc) #endif #else /* not FFLSP_NEEDED */ #ifdef FFLEX_PARAM #define FFLEX fflex(&fflval, FFLEX_PARAM) #else #define FFLEX fflex(&fflval) #endif #endif /* not FFLSP_NEEDED */ #endif /* If nonreentrant, generate the variables here */ #ifndef FFPURE int ffchar; /* the lookahead symbol */ FFSTYPE fflval; /* the semantic value of the */ /* lookahead symbol */ #ifdef FFLSP_NEEDED FFLTYPE fflloc; /* location data for the lookahead */ /* symbol */ #endif int ffnerrs; /* number of parse errors so far */ #endif /* not FFPURE */ #if FFDEBUG != 0 int ffdebug; /* nonzero means print parse trace */ /* Since this is uninitialized, it does not stop multiple parsers from coexisting. */ #endif /* FFINITDEPTH indicates the initial size of the parser's stacks */ #ifndef FFINITDEPTH #define FFINITDEPTH 200 #endif /* FFMAXDEPTH is the maximum size the stacks can grow to (effective only if the built-in stack extension method is used). */ #if FFMAXDEPTH == 0 #undef FFMAXDEPTH #endif #ifndef FFMAXDEPTH #define FFMAXDEPTH 10000 #endif /* Prevent warning if -Wstrict-prototypes. */ #ifdef __GNUC__ int ffparse (void); #endif #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ #define __ff_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) #else /* not GNU C or C++ */ #ifndef __cplusplus /* This is the most reliable way to avoid incompatibilities in available built-in functions on various systems. */ static void __ff_memcpy (to, from, count) char *to; char *from; int count; { register char *f = from; register char *t = to; register int i = count; while (i-- > 0) *t++ = *f++; } #else /* __cplusplus */ /* This is the most reliable way to avoid incompatibilities in available built-in functions on various systems. */ static void __ff_memcpy (char *to, char *from, int count) { register char *f = from; register char *t = to; register int i = count; while (i-- > 0) *t++ = *f++; } #endif #endif #line 196 "/usr1/local/share/bison.simple" /* The user can define FFPARSE_PARAM as the name of an argument to be passed into ffparse. The argument should have type void *. It should actually point to an object. Grammar actions can access the variable by casting it to the proper pointer type. */ #ifdef FFPARSE_PARAM #ifdef __cplusplus #define FFPARSE_PARAM_ARG void *FFPARSE_PARAM #define FFPARSE_PARAM_DECL #else /* not __cplusplus */ #define FFPARSE_PARAM_ARG FFPARSE_PARAM #define FFPARSE_PARAM_DECL void *FFPARSE_PARAM; #endif /* not __cplusplus */ #else /* not FFPARSE_PARAM */ #define FFPARSE_PARAM_ARG #define FFPARSE_PARAM_DECL #endif /* not FFPARSE_PARAM */ int ffparse(FFPARSE_PARAM_ARG) FFPARSE_PARAM_DECL { register int ffstate; register int ffn; register short *ffssp; register FFSTYPE *ffvsp; int fferrstatus; /* number of tokens to shift before error messages enabled */ int ffchar1 = 0; /* lookahead token as an internal (translated) token number */ short ffssa[FFINITDEPTH]; /* the state stack */ FFSTYPE ffvsa[FFINITDEPTH]; /* the semantic value stack */ short *ffss = ffssa; /* refer to the stacks thru separate pointers */ FFSTYPE *ffvs = ffvsa; /* to allow ffoverflow to reallocate them elsewhere */ #ifdef FFLSP_NEEDED FFLTYPE fflsa[FFINITDEPTH]; /* the location stack */ FFLTYPE *ffls = fflsa; FFLTYPE *fflsp; #define FFPOPSTACK (ffvsp--, ffssp--, fflsp--) #else #define FFPOPSTACK (ffvsp--, ffssp--) #endif int ffstacksize = FFINITDEPTH; #ifdef FFPURE int ffchar; FFSTYPE fflval; int ffnerrs; #ifdef FFLSP_NEEDED FFLTYPE fflloc; #endif #endif FFSTYPE ffval; /* the variable used to return */ /* semantic values from the action */ /* routines */ int fflen; #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Starting parse\n"); #endif ffstate = 0; fferrstatus = 0; ffnerrs = 0; ffchar = FFEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ ffssp = ffss - 1; ffvsp = ffvs; #ifdef FFLSP_NEEDED fflsp = ffls; #endif /* Push a new state, which is found in ffstate . */ /* In all cases, when you get here, the value and location stacks have just been pushed. so pushing a state here evens the stacks. */ ffnewstate: *++ffssp = ffstate; if (ffssp >= ffss + ffstacksize - 1) { /* Give user a chance to reallocate the stack */ /* Use copies of these so that the &'s don't force the real ones into memory. */ FFSTYPE *ffvs1 = ffvs; short *ffss1 = ffss; #ifdef FFLSP_NEEDED FFLTYPE *ffls1 = ffls; #endif /* Get the current used size of the three stacks, in elements. */ int size = ffssp - ffss + 1; #ifdef ffoverflow /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. */ #ifdef FFLSP_NEEDED /* This used to be a conditional around just the two extra args, but that might be undefined if ffoverflow is a macro. */ ffoverflow("parser stack overflow", &ffss1, size * sizeof (*ffssp), &ffvs1, size * sizeof (*ffvsp), &ffls1, size * sizeof (*fflsp), &ffstacksize); #else ffoverflow("parser stack overflow", &ffss1, size * sizeof (*ffssp), &ffvs1, size * sizeof (*ffvsp), &ffstacksize); #endif ffss = ffss1; ffvs = ffvs1; #ifdef FFLSP_NEEDED ffls = ffls1; #endif #else /* no ffoverflow */ /* Extend the stack our own way. */ if (ffstacksize >= FFMAXDEPTH) { fferror("parser stack overflow"); return 2; } ffstacksize *= 2; if (ffstacksize > FFMAXDEPTH) ffstacksize = FFMAXDEPTH; ffss = (short *) alloca (ffstacksize * sizeof (*ffssp)); __ff_memcpy ((char *)ffss, (char *)ffss1, size * sizeof (*ffssp)); ffvs = (FFSTYPE *) alloca (ffstacksize * sizeof (*ffvsp)); __ff_memcpy ((char *)ffvs, (char *)ffvs1, size * sizeof (*ffvsp)); #ifdef FFLSP_NEEDED ffls = (FFLTYPE *) alloca (ffstacksize * sizeof (*fflsp)); __ff_memcpy ((char *)ffls, (char *)ffls1, size * sizeof (*fflsp)); #endif #endif /* no ffoverflow */ ffssp = ffss + size - 1; ffvsp = ffvs + size - 1; #ifdef FFLSP_NEEDED fflsp = ffls + size - 1; #endif #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Stack size increased to %d\n", ffstacksize); #endif if (ffssp >= ffss + ffstacksize - 1) FFABORT; } #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Entering state %d\n", ffstate); #endif goto ffbackup; ffbackup: /* Do appropriate processing given the current state. */ /* Read a lookahead token if we need one and don't already have one. */ /* ffresume: */ /* First try to decide what to do without reference to lookahead token. */ ffn = ffpact[ffstate]; if (ffn == FFFLAG) goto ffdefault; /* Not known => get a lookahead token if don't already have one. */ /* ffchar is either FFEMPTY or FFEOF or a valid token in external form. */ if (ffchar == FFEMPTY) { #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Reading a token: "); #endif ffchar = FFLEX; } /* Convert token to internal form (in ffchar1) for indexing tables with */ if (ffchar <= 0) /* This means end of input. */ { ffchar1 = 0; ffchar = FFEOF; /* Don't call FFLEX any more */ #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Now at end of input.\n"); #endif } else { ffchar1 = FFTRANSLATE(ffchar); #if FFDEBUG != 0 if (ffdebug) { fprintf (stderr, "Next token is %d (%s", ffchar, fftname[ffchar1]); /* Give the individual parser a way to print the precise meaning of a token, for further debugging info. */ #ifdef FFPRINT FFPRINT (stderr, ffchar, fflval); #endif fprintf (stderr, ")\n"); } #endif } ffn += ffchar1; if (ffn < 0 || ffn > FFLAST || ffcheck[ffn] != ffchar1) goto ffdefault; ffn = fftable[ffn]; /* ffn is what to do for this token type in this state. Negative => reduce, -ffn is rule number. Positive => shift, ffn is new state. New state is final state => don't bother to shift, just return success. 0, or most negative number => error. */ if (ffn < 0) { if (ffn == FFFLAG) goto fferrlab; ffn = -ffn; goto ffreduce; } else if (ffn == 0) goto fferrlab; if (ffn == FFFINAL) FFACCEPT; /* Shift the lookahead token. */ #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Shifting token %d (%s), ", ffchar, fftname[ffchar1]); #endif /* Discard the token being shifted unless it is eof. */ if (ffchar != FFEOF) ffchar = FFEMPTY; *++ffvsp = fflval; #ifdef FFLSP_NEEDED *++fflsp = fflloc; #endif /* count tokens shifted since error; after three, turn off error status. */ if (fferrstatus) fferrstatus--; ffstate = ffn; goto ffnewstate; /* Do the default action for the current state. */ ffdefault: ffn = ffdefact[ffstate]; if (ffn == 0) goto fferrlab; /* Do a reduction. ffn is the number of a rule to reduce with. */ ffreduce: fflen = ffr2[ffn]; if (fflen > 0) ffval = ffvsp[1-fflen]; /* implement default value of the action */ #if FFDEBUG != 0 if (ffdebug) { int i; fprintf (stderr, "Reducing via rule %d (line %d), ", ffn, ffrline[ffn]); /* Print the symbols being reduced, and their result. */ for (i = ffprhs[ffn]; ffrhs[i] > 0; i++) fprintf (stderr, "%s ", fftname[ffrhs[i]]); fprintf (stderr, " -> %s\n", fftname[ffr1[ffn]]); } #endif switch (ffn) { case 3: #line 233 "eval.y" {; break;} case 4: #line 235 "eval.y" { if( ffvsp[-1].Node<0 ) { fferror("Couldn't build node structure: out of memory?"); FFERROR; } gParse.resultNode = ffvsp[-1].Node; ; break;} case 5: #line 241 "eval.y" { if( ffvsp[-1].Node<0 ) { fferror("Couldn't build node structure: out of memory?"); FFERROR; } gParse.resultNode = ffvsp[-1].Node; ; break;} case 6: #line 247 "eval.y" { if( ffvsp[-1].Node<0 ) { fferror("Couldn't build node structure: out of memory?"); FFERROR; } gParse.resultNode = ffvsp[-1].Node; ; break;} case 7: #line 253 "eval.y" { if( ffvsp[-1].Node<0 ) { fferror("Couldn't build node structure: out of memory?"); FFERROR; } gParse.resultNode = ffvsp[-1].Node; ; break;} case 8: #line 258 "eval.y" { fferrok; ; break;} case 9: #line 262 "eval.y" { ffval.Node = New_Vector( ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 10: #line 264 "eval.y" { if( gParse.Nodes[ffvsp[-2].Node].nSubNodes >= MAXSUBS ) { ffvsp[-2].Node = Close_Vec( ffvsp[-2].Node ); TEST(ffvsp[-2].Node); ffval.Node = New_Vector( ffvsp[-2].Node ); TEST(ffval.Node); } else { ffval.Node = ffvsp[-2].Node; } gParse.Nodes[ffval.Node].SubNodes[ gParse.Nodes[ffval.Node].nSubNodes++ ] = ffvsp[0].Node; ; break;} case 11: #line 277 "eval.y" { ffval.Node = New_Vector( ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 12: #line 279 "eval.y" { if( TYPE(ffvsp[-2].Node) < TYPE(ffvsp[0].Node) ) TYPE(ffvsp[-2].Node) = TYPE(ffvsp[0].Node); if( gParse.Nodes[ffvsp[-2].Node].nSubNodes >= MAXSUBS ) { ffvsp[-2].Node = Close_Vec( ffvsp[-2].Node ); TEST(ffvsp[-2].Node); ffval.Node = New_Vector( ffvsp[-2].Node ); TEST(ffval.Node); } else { ffval.Node = ffvsp[-2].Node; } gParse.Nodes[ffval.Node].SubNodes[ gParse.Nodes[ffval.Node].nSubNodes++ ] = ffvsp[0].Node; ; break;} case 13: #line 292 "eval.y" { if( gParse.Nodes[ffvsp[-2].Node].nSubNodes >= MAXSUBS ) { ffvsp[-2].Node = Close_Vec( ffvsp[-2].Node ); TEST(ffvsp[-2].Node); ffval.Node = New_Vector( ffvsp[-2].Node ); TEST(ffval.Node); } else { ffval.Node = ffvsp[-2].Node; } gParse.Nodes[ffval.Node].SubNodes[ gParse.Nodes[ffval.Node].nSubNodes++ ] = ffvsp[0].Node; ; break;} case 14: #line 303 "eval.y" { TYPE(ffvsp[-2].Node) = TYPE(ffvsp[0].Node); if( gParse.Nodes[ffvsp[-2].Node].nSubNodes >= MAXSUBS ) { ffvsp[-2].Node = Close_Vec( ffvsp[-2].Node ); TEST(ffvsp[-2].Node); ffval.Node = New_Vector( ffvsp[-2].Node ); TEST(ffval.Node); } else { ffval.Node = ffvsp[-2].Node; } gParse.Nodes[ffval.Node].SubNodes[ gParse.Nodes[ffval.Node].nSubNodes++ ] = ffvsp[0].Node; ; break;} case 15: #line 317 "eval.y" { ffval.Node = Close_Vec( ffvsp[-1].Node ); TEST(ffval.Node); ; break;} case 16: #line 321 "eval.y" { ffval.Node = Close_Vec( ffvsp[-1].Node ); TEST(ffval.Node); ; break;} case 17: #line 325 "eval.y" { ffval.Node = New_Const( BITSTR, ffvsp[0].str, strlen(ffvsp[0].str)+1 ); TEST(ffval.Node); SIZE(ffval.Node) = strlen(ffvsp[0].str); ; break;} case 18: #line 330 "eval.y" { ffval.Node = New_Column( ffvsp[0].lng ); TEST(ffval.Node); ; break;} case 19: #line 332 "eval.y" { if( TYPE(ffvsp[-1].Node) != LONG || gParse.Nodes[ffvsp[-1].Node].operation != CONST_OP ) { fferror("Offset argument must be a constant integer"); FFERROR; } ffval.Node = New_Offset( ffvsp[-3].lng, ffvsp[-1].Node ); TEST(ffval.Node); ; break;} case 20: #line 341 "eval.y" { ffval.Node = New_BinOp( BITSTR, ffvsp[-2].Node, '&', ffvsp[0].Node ); TEST(ffval.Node); SIZE(ffval.Node) = ( SIZE(ffvsp[-2].Node)>SIZE(ffvsp[0].Node) ? SIZE(ffvsp[-2].Node) : SIZE(ffvsp[0].Node) ); ; break;} case 21: #line 344 "eval.y" { ffval.Node = New_BinOp( BITSTR, ffvsp[-2].Node, '|', ffvsp[0].Node ); TEST(ffval.Node); SIZE(ffval.Node) = ( SIZE(ffvsp[-2].Node)>SIZE(ffvsp[0].Node) ? SIZE(ffvsp[-2].Node) : SIZE(ffvsp[0].Node) ); ; break;} case 22: #line 347 "eval.y" { ffval.Node = New_BinOp( BITSTR, ffvsp[-2].Node, '+', ffvsp[0].Node ); TEST(ffval.Node); SIZE(ffval.Node) = SIZE(ffvsp[-2].Node) + SIZE(ffvsp[0].Node); ; break;} case 23: #line 350 "eval.y" { ffval.Node = New_Deref( ffvsp[-3].Node, 1, ffvsp[-1].Node, 0, 0, 0, 0 ); TEST(ffval.Node); ; break;} case 24: #line 352 "eval.y" { ffval.Node = New_Deref( ffvsp[-5].Node, 2, ffvsp[-3].Node, ffvsp[-1].Node, 0, 0, 0 ); TEST(ffval.Node); ; break;} case 25: #line 354 "eval.y" { ffval.Node = New_Deref( ffvsp[-7].Node, 3, ffvsp[-5].Node, ffvsp[-3].Node, ffvsp[-1].Node, 0, 0 ); TEST(ffval.Node); ; break;} case 26: #line 356 "eval.y" { ffval.Node = New_Deref( ffvsp[-9].Node, 4, ffvsp[-7].Node, ffvsp[-5].Node, ffvsp[-3].Node, ffvsp[-1].Node, 0 ); TEST(ffval.Node); ; break;} case 27: #line 358 "eval.y" { ffval.Node = New_Deref( ffvsp[-11].Node, 5, ffvsp[-9].Node, ffvsp[-7].Node, ffvsp[-5].Node, ffvsp[-3].Node, ffvsp[-1].Node ); TEST(ffval.Node); ; break;} case 28: #line 360 "eval.y" { ffval.Node = New_Unary( BITSTR, NOT, ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 29: #line 363 "eval.y" { ffval.Node = ffvsp[-1].Node; ; break;} case 30: #line 367 "eval.y" { ffval.Node = New_Const( LONG, &(ffvsp[0].lng), sizeof(long) ); TEST(ffval.Node); ; break;} case 31: #line 369 "eval.y" { ffval.Node = New_Const( DOUBLE, &(ffvsp[0].dbl), sizeof(double) ); TEST(ffval.Node); ; break;} case 32: #line 371 "eval.y" { ffval.Node = New_Column( ffvsp[0].lng ); TEST(ffval.Node); ; break;} case 33: #line 373 "eval.y" { if( TYPE(ffvsp[-1].Node) != LONG || gParse.Nodes[ffvsp[-1].Node].operation != CONST_OP ) { fferror("Offset argument must be a constant integer"); FFERROR; } ffval.Node = New_Offset( ffvsp[-3].lng, ffvsp[-1].Node ); TEST(ffval.Node); ; break;} case 34: #line 382 "eval.y" { ffval.Node = New_Func( LONG, row_fct, 0, 0, 0, 0, 0, 0, 0, 0 ); ; break;} case 35: #line 384 "eval.y" { ffval.Node = New_Func( LONG, null_fct, 0, 0, 0, 0, 0, 0, 0, 0 ); ; break;} case 36: #line 386 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, '%', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 37: #line 389 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, '+', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 38: #line 392 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, '-', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 39: #line 395 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, '*', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 40: #line 398 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, '/', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 41: #line 401 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, POWER, ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 42: #line 404 "eval.y" { ffval.Node = ffvsp[0].Node; ; break;} case 43: #line 406 "eval.y" { ffval.Node = New_Unary( TYPE(ffvsp[0].Node), UMINUS, ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 44: #line 408 "eval.y" { ffval.Node = ffvsp[-1].Node; ; break;} case 45: #line 410 "eval.y" { ffvsp[0].Node = New_Unary( TYPE(ffvsp[-2].Node), 0, ffvsp[0].Node ); ffval.Node = New_BinOp( TYPE(ffvsp[-2].Node), ffvsp[-2].Node, '*', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 46: #line 414 "eval.y" { ffvsp[-2].Node = New_Unary( TYPE(ffvsp[0].Node), 0, ffvsp[-2].Node ); ffval.Node = New_BinOp( TYPE(ffvsp[0].Node), ffvsp[-2].Node, '*', ffvsp[0].Node ); TEST(ffval.Node); ; break;} case 47: #line 418 "eval.y" { PROMOTE(ffvsp[-2].Node,ffvsp[0].Node); if( ! Test_Dims(ffvsp[-2].Node,ffvsp[0].Node) ) { fferror("Incompatible dimensions in '?:' arguments"); FFERROR; } ffval.Node = New_Func( 0, ifthenelse_fct, 3, ffvsp[-2].Node, ffvsp[0].Node, ffvsp[-4].Node, 0, 0, 0, 0 ); TEST(ffval.Node); if( SIZE(ffvsp[-2].Node)=SIZE(ffvsp[-1].Node) && Test_Dims( ffvsp[-3].Node, ffvsp[-1].Node ) ) { PROMOTE(ffvsp[-3].Node,ffvsp[-1].Node); ffval.Node = New_Func( 0, defnull_fct, 2, ffvsp[-3].Node, ffvsp[-1].Node, 0, 0, 0, 0, 0 ); TEST(ffval.Node); } else { fferror("Dimensions of DEFNULL arguments " "are not compatible"); FFERROR; } } else if (FSTRCMP(ffvsp[-4].str,"ARCTAN2(") == 0) { if( TYPE(ffvsp[-3].Node) != DOUBLE ) ffvsp[-3].Node = New_Unary( DOUBLE, 0, ffvsp[-3].Node ); if( TYPE(ffvsp[-1].Node) != DOUBLE ) ffvsp[-1].Node = New_Unary( DOUBLE, 0, ffvsp[-1].Node ); if( Test_Dims( ffvsp[-3].Node, ffvsp[-1].Node ) ) { ffval.Node = New_Func( 0, atan2_fct, 2, ffvsp[-3].Node, ffvsp[-1].Node, 0, 0, 0, 0, 0 ); TEST(ffval.Node); if( SIZE(ffvsp[-3].Node)=SIZE(ffvsp[-1].Node) && Test_Dims( ffvsp[-3].Node, ffvsp[-1].Node ) ) { ffval.Node = New_Func( 0, defnull_fct, 2, ffvsp[-3].Node, ffvsp[-1].Node, 0, 0, 0, 0, 0 ); TEST(ffval.Node); } else { fferror("Dimensions of DEFNULL arguments are not compatible"); FFERROR; } } else { fferror("Boolean Function(expr,expr) not supported"); FFERROR; } ; break;} case 98: #line 878 "eval.y" { if( TYPE(ffvsp[-5].Node) != DOUBLE ) ffvsp[-5].Node = New_Unary( DOUBLE, 0, ffvsp[-5].Node ); if( TYPE(ffvsp[-3].Node) != DOUBLE ) ffvsp[-3].Node = New_Unary( DOUBLE, 0, ffvsp[-3].Node ); if( TYPE(ffvsp[-1].Node) != DOUBLE ) ffvsp[-1].Node = New_Unary( DOUBLE, 0, ffvsp[-1].Node ); if( ! (Test_Dims( ffvsp[-5].Node, ffvsp[-3].Node ) && Test_Dims( ffvsp[-3].Node, ffvsp[-1].Node ) ) ) { fferror("Dimensions of NEAR arguments " "are not compatible"); FFERROR; } else { if (FSTRCMP(ffvsp[-6].str,"NEAR(") == 0) { ffval.Node = New_Func( BOOLEAN, near_fct, 3, ffvsp[-5].Node, ffvsp[-3].Node, ffvsp[-1].Node, 0, 0, 0, 0 ); } else { fferror("Boolean Function not supported"); FFERROR; } TEST(ffval.Node); if( SIZE(ffval.Node)SIZE(ffvsp[-3].Node) ) SIZE(ffval.Node) = SIZE(ffvsp[-1].Node); } ; break;} } /* the action file gets copied in in place of this dollarsign */ #line 498 "/usr1/local/share/bison.simple" ffvsp -= fflen; ffssp -= fflen; #ifdef FFLSP_NEEDED fflsp -= fflen; #endif #if FFDEBUG != 0 if (ffdebug) { short *ssp1 = ffss - 1; fprintf (stderr, "state stack now"); while (ssp1 != ffssp) fprintf (stderr, " %d", *++ssp1); fprintf (stderr, "\n"); } #endif *++ffvsp = ffval; #ifdef FFLSP_NEEDED fflsp++; if (fflen == 0) { fflsp->first_line = fflloc.first_line; fflsp->first_column = fflloc.first_column; fflsp->last_line = (fflsp-1)->last_line; fflsp->last_column = (fflsp-1)->last_column; fflsp->text = 0; } else { fflsp->last_line = (fflsp+fflen-1)->last_line; fflsp->last_column = (fflsp+fflen-1)->last_column; } #endif /* Now "shift" the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ ffn = ffr1[ffn]; ffstate = ffpgoto[ffn - FFNTBASE] + *ffssp; if (ffstate >= 0 && ffstate <= FFLAST && ffcheck[ffstate] == *ffssp) ffstate = fftable[ffstate]; else ffstate = ffdefgoto[ffn - FFNTBASE]; goto ffnewstate; fferrlab: /* here on detecting error */ if (! fferrstatus) /* If not already recovering from an error, report this error. */ { ++ffnerrs; #ifdef FFERROR_VERBOSE ffn = ffpact[ffstate]; if (ffn > FFFLAG && ffn < FFLAST) { int size = 0; char *msg; int x, count; count = 0; /* Start X at -ffn if nec to avoid negative indexes in ffcheck. */ for (x = (ffn < 0 ? -ffn : 0); x < (sizeof(fftname) / sizeof(char *)); x++) if (ffcheck[x + ffn] == x) size += strlen(fftname[x]) + 15, count++; msg = (char *) malloc(size + 15); if (msg != 0) { strcpy(msg, "parse error"); if (count < 5) { count = 0; for (x = (ffn < 0 ? -ffn : 0); x < (sizeof(fftname) / sizeof(char *)); x++) if (ffcheck[x + ffn] == x) { strcat(msg, count == 0 ? ", expecting `" : " or `"); strcat(msg, fftname[x]); strcat(msg, "'"); count++; } } fferror(msg); free(msg); } else fferror ("parse error; also virtual memory exceeded"); } else #endif /* FFERROR_VERBOSE */ fferror("parse error"); } goto fferrlab1; fferrlab1: /* here on error raised explicitly by an action */ if (fferrstatus == 3) { /* if just tried and failed to reuse lookahead token after an error, discard it. */ /* return failure if at end of input */ if (ffchar == FFEOF) FFABORT; #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Discarding token %d (%s).\n", ffchar, fftname[ffchar1]); #endif ffchar = FFEMPTY; } /* Else will try to reuse lookahead token after shifting the error token. */ fferrstatus = 3; /* Each real token shifted decrements this */ goto fferrhandle; fferrdefault: /* current state does not do anything special for the error token. */ #if 0 /* This is wrong; only states that explicitly want error tokens should shift them. */ ffn = ffdefact[ffstate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ if (ffn) goto ffdefault; #endif fferrpop: /* pop the current state because it cannot handle the error token */ if (ffssp == ffss) FFABORT; ffvsp--; ffstate = *--ffssp; #ifdef FFLSP_NEEDED fflsp--; #endif #if FFDEBUG != 0 if (ffdebug) { short *ssp1 = ffss - 1; fprintf (stderr, "Error: state stack now"); while (ssp1 != ffssp) fprintf (stderr, " %d", *++ssp1); fprintf (stderr, "\n"); } #endif fferrhandle: ffn = ffpact[ffstate]; if (ffn == FFFLAG) goto fferrdefault; ffn += FFTERROR; if (ffn < 0 || ffn > FFLAST || ffcheck[ffn] != FFTERROR) goto fferrdefault; ffn = fftable[ffn]; if (ffn < 0) { if (ffn == FFFLAG) goto fferrpop; ffn = -ffn; goto ffreduce; } else if (ffn == 0) goto fferrpop; if (ffn == FFFINAL) FFACCEPT; #if FFDEBUG != 0 if (ffdebug) fprintf(stderr, "Shifting error token, "); #endif *++ffvsp = fflval; #ifdef FFLSP_NEEDED *++fflsp = fflloc; #endif ffstate = ffn; goto ffnewstate; } #line 1052 "eval.y" /*************************************************************************/ /* Start of "New" routines which build the expression Nodal structure */ /*************************************************************************/ static int Alloc_Node( void ) { /* Use this for allocation to guarantee *Nodes */ Node *newNodePtr; /* survives on failure, making it still valid */ /* while working our way out of this error */ if( gParse.nNodes == gParse.nNodesAlloc ) { if( gParse.Nodes ) { gParse.nNodesAlloc += gParse.nNodesAlloc; newNodePtr = (Node *)realloc( gParse.Nodes, sizeof(Node)*gParse.nNodesAlloc ); } else { gParse.nNodesAlloc = 100; newNodePtr = (Node *)malloc ( sizeof(Node)*gParse.nNodesAlloc ); } if( newNodePtr ) { gParse.Nodes = newNodePtr; } else { gParse.status = MEMORY_ALLOCATION; return( -1 ); } } return ( gParse.nNodes++ ); } static void Free_Last_Node( void ) { if( gParse.nNodes ) gParse.nNodes--; } static int New_Const( int returnType, void *value, long len ) { Node *this; int n; n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = CONST_OP; /* Flag a constant */ this->DoOp = NULL; this->nSubNodes = 0; this->type = returnType; memcpy( &(this->value.data), value, len ); this->value.undef = NULL; this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } return(n); } static int New_Column( int ColNum ) { Node *this; int n, i; n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = -ColNum; this->DoOp = NULL; this->nSubNodes = 0; this->type = gParse.varData[ColNum].type; this->value.nelem = gParse.varData[ColNum].nelem; this->value.naxis = gParse.varData[ColNum].naxis; for( i=0; ivalue.naxes[i] = gParse.varData[ColNum].naxes[i]; } return(n); } static int New_Offset( int ColNum, int offsetNode ) { Node *this; int n, i, colNode; colNode = New_Column( ColNum ); if( colNode<0 ) return(-1); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = '{'; this->DoOp = Do_Offset; this->nSubNodes = 2; this->SubNodes[0] = colNode; this->SubNodes[1] = offsetNode; this->type = gParse.varData[ColNum].type; this->value.nelem = gParse.varData[ColNum].nelem; this->value.naxis = gParse.varData[ColNum].naxis; for( i=0; ivalue.naxes[i] = gParse.varData[ColNum].naxes[i]; } return(n); } static int New_Unary( int returnType, int Op, int Node1 ) { Node *this, *that; int i,n; if( Node1<0 ) return(-1); that = gParse.Nodes + Node1; if( !Op ) Op = returnType; if( (Op==DOUBLE || Op==FLTCAST) && that->type==DOUBLE ) return( Node1 ); if( (Op==LONG || Op==INTCAST) && that->type==LONG ) return( Node1 ); if( (Op==BOOLEAN ) && that->type==BOOLEAN ) return( Node1 ); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = Op; this->DoOp = Do_Unary; this->nSubNodes = 1; this->SubNodes[0] = Node1; this->type = returnType; that = gParse.Nodes + Node1; /* Reset in case .Nodes mv'd */ this->value.nelem = that->value.nelem; this->value.naxis = that->value.naxis; for( i=0; ivalue.naxis; i++ ) this->value.naxes[i] = that->value.naxes[i]; if( that->operation==CONST_OP ) this->DoOp( this ); } return( n ); } static int New_BinOp( int returnType, int Node1, int Op, int Node2 ) { Node *this,*that1,*that2; int n,i,constant; if( Node1<0 || Node2<0 ) return(-1); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = Op; this->nSubNodes = 2; this->SubNodes[0]= Node1; this->SubNodes[1]= Node2; this->type = returnType; that1 = gParse.Nodes + Node1; that2 = gParse.Nodes + Node2; constant = (that1->operation==CONST_OP && that2->operation==CONST_OP); if( that1->type!=STRING && that1->type!=BITSTR ) if( !Test_Dims( Node1, Node2 ) ) { Free_Last_Node(); fferror("Array sizes/dims do not match for binary operator"); return(-1); } if( that1->value.nelem == 1 ) that1 = that2; this->value.nelem = that1->value.nelem; this->value.naxis = that1->value.naxis; for( i=0; ivalue.naxis; i++ ) this->value.naxes[i] = that1->value.naxes[i]; if ( Op == ACCUM && that1->type == BITSTR ) { /* ACCUM is rank-reducing on bit strings */ this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } /* Both subnodes should be of same time */ switch( that1->type ) { case BITSTR: this->DoOp = Do_BinOp_bit; break; case STRING: this->DoOp = Do_BinOp_str; break; case BOOLEAN: this->DoOp = Do_BinOp_log; break; case LONG: this->DoOp = Do_BinOp_lng; break; case DOUBLE: this->DoOp = Do_BinOp_dbl; break; } if( constant ) this->DoOp( this ); } return( n ); } static int New_Func( int returnType, funcOp Op, int nNodes, int Node1, int Node2, int Node3, int Node4, int Node5, int Node6, int Node7 ) /* If returnType==0 , use Node1's type and vector sizes as returnType, */ /* else return a single value of type returnType */ { Node *this, *that; int i,n,constant; if( Node1<0 || Node2<0 || Node3<0 || Node4<0 || Node5<0 || Node6<0 || Node7<0 ) return(-1); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = (int)Op; this->DoOp = Do_Func; this->nSubNodes = nNodes; this->SubNodes[0] = Node1; this->SubNodes[1] = Node2; this->SubNodes[2] = Node3; this->SubNodes[3] = Node4; this->SubNodes[4] = Node5; this->SubNodes[5] = Node6; this->SubNodes[6] = Node7; i = constant = nNodes; /* Functions with zero params are not const */ if (Op == poirnd_fct) constant = 0; /* Nor is Poisson deviate */ while( i-- ) constant = ( constant && gParse.Nodes[ this->SubNodes[i] ].operation==CONST_OP ); if( returnType ) { this->type = returnType; this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } else { that = gParse.Nodes + Node1; this->type = that->type; this->value.nelem = that->value.nelem; this->value.naxis = that->value.naxis; for( i=0; ivalue.naxis; i++ ) this->value.naxes[i] = that->value.naxes[i]; } if( constant ) this->DoOp( this ); } return( n ); } static int New_Deref( int Var, int nDim, int Dim1, int Dim2, int Dim3, int Dim4, int Dim5 ) { int n, idx, constant; long elem=0; Node *this, *theVar, *theDim[MAXDIMS]; if( Var<0 || Dim1<0 || Dim2<0 || Dim3<0 || Dim4<0 || Dim5<0 ) return(-1); theVar = gParse.Nodes + Var; if( theVar->operation==CONST_OP || theVar->value.nelem==1 ) { fferror("Cannot index a scalar value"); return(-1); } n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->nSubNodes = nDim+1; theVar = gParse.Nodes + (this->SubNodes[0]=Var); theDim[0] = gParse.Nodes + (this->SubNodes[1]=Dim1); theDim[1] = gParse.Nodes + (this->SubNodes[2]=Dim2); theDim[2] = gParse.Nodes + (this->SubNodes[3]=Dim3); theDim[3] = gParse.Nodes + (this->SubNodes[4]=Dim4); theDim[4] = gParse.Nodes + (this->SubNodes[5]=Dim5); constant = theVar->operation==CONST_OP; for( idx=0; idxoperation==CONST_OP); for( idx=0; idxvalue.nelem>1 ) { Free_Last_Node(); fferror("Cannot use an array as an index value"); return(-1); } else if( theDim[idx]->type!=LONG ) { Free_Last_Node(); fferror("Index value must be an integer type"); return(-1); } this->operation = '['; this->DoOp = Do_Deref; this->type = theVar->type; if( theVar->value.naxis == nDim ) { /* All dimensions specified */ this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } else if( nDim==1 ) { /* Dereference only one dimension */ elem=1; this->value.naxis = theVar->value.naxis-1; for( idx=0; idxvalue.naxis; idx++ ) { elem *= ( this->value.naxes[idx] = theVar->value.naxes[idx] ); } this->value.nelem = elem; } else { Free_Last_Node(); fferror("Must specify just one or all indices for vector"); return(-1); } if( constant ) this->DoOp( this ); } return(n); } extern int ffGetVariable( char *varName, FFSTYPE *varVal ); static int New_GTI( char *fname, int Node1, char *start, char *stop ) { fitsfile *fptr; Node *this, *that0, *that1; int type,i,n, startCol, stopCol, Node0; int hdutype, hdunum, evthdu, samefile, extvers, movetotype, tstat; char extname[100]; long nrows; double timeZeroI[2], timeZeroF[2], dt, timeSpan; char xcol[20], xexpr[20]; FFSTYPE colVal; if( Node1==-99 ) { type = ffGetVariable( "TIME", &colVal ); if( type==COLUMN ) { Node1 = New_Column( (int)colVal.lng ); } else { fferror("Could not build TIME column for GTIFILTER"); return(-1); } } Node1 = New_Unary( DOUBLE, 0, Node1 ); Node0 = Alloc_Node(); /* This will hold the START/STOP times */ if( Node1<0 || Node0<0 ) return(-1); /* Record current HDU number in case we need to move within this file */ fptr = gParse.def_fptr; ffghdn( fptr, &evthdu ); /* Look for TIMEZERO keywords in current extension */ tstat = 0; if( ffgkyd( fptr, "TIMEZERO", timeZeroI, NULL, &tstat ) ) { tstat = 0; if( ffgkyd( fptr, "TIMEZERI", timeZeroI, NULL, &tstat ) ) { timeZeroI[0] = timeZeroF[0] = 0.0; } else if( ffgkyd( fptr, "TIMEZERF", timeZeroF, NULL, &tstat ) ) { timeZeroF[0] = 0.0; } } else { timeZeroF[0] = 0.0; } /* Resolve filename parameter */ switch( fname[0] ) { case '\0': samefile = 1; hdunum = 1; break; case '[': samefile = 1; i = 1; while( fname[i] != '\0' && fname[i] != ']' ) i++; if( fname[i] ) { fname[i] = '\0'; fname++; ffexts( fname, &hdunum, extname, &extvers, &movetotype, xcol, xexpr, &gParse.status ); if( *extname ) { ffmnhd( fptr, movetotype, extname, extvers, &gParse.status ); ffghdn( fptr, &hdunum ); } else if( hdunum ) { ffmahd( fptr, ++hdunum, &hdutype, &gParse.status ); } else if( !gParse.status ) { fferror("Cannot use primary array for GTI filter"); return( -1 ); } } else { fferror("File extension specifier lacks closing ']'"); return( -1 ); } break; case '+': samefile = 1; hdunum = atoi( fname ) + 1; if( hdunum>1 ) ffmahd( fptr, hdunum, &hdutype, &gParse.status ); else { fferror("Cannot use primary array for GTI filter"); return( -1 ); } break; default: samefile = 0; if( ! ffopen( &fptr, fname, READONLY, &gParse.status ) ) ffghdn( fptr, &hdunum ); break; } if( gParse.status ) return(-1); /* If at primary, search for GTI extension */ if( hdunum==1 ) { while( 1 ) { hdunum++; if( ffmahd( fptr, hdunum, &hdutype, &gParse.status ) ) break; if( hdutype==IMAGE_HDU ) continue; tstat = 0; if( ffgkys( fptr, "EXTNAME", extname, NULL, &tstat ) ) continue; ffupch( extname ); if( strstr( extname, "GTI" ) ) break; } if( gParse.status ) { if( gParse.status==END_OF_FILE ) fferror("GTI extension not found in this file"); return(-1); } } /* Locate START/STOP Columns */ ffgcno( fptr, CASEINSEN, start, &startCol, &gParse.status ); ffgcno( fptr, CASEINSEN, stop, &stopCol, &gParse.status ); if( gParse.status ) return(-1); /* Look for TIMEZERO keywords in GTI extension */ tstat = 0; if( ffgkyd( fptr, "TIMEZERO", timeZeroI+1, NULL, &tstat ) ) { tstat = 0; if( ffgkyd( fptr, "TIMEZERI", timeZeroI+1, NULL, &tstat ) ) { timeZeroI[1] = timeZeroF[1] = 0.0; } else if( ffgkyd( fptr, "TIMEZERF", timeZeroF+1, NULL, &tstat ) ) { timeZeroF[1] = 0.0; } } else { timeZeroF[1] = 0.0; } n = Alloc_Node(); if( n >= 0 ) { this = gParse.Nodes + n; this->nSubNodes = 2; this->SubNodes[1] = Node1; this->operation = (int)gtifilt_fct; this->DoOp = Do_GTI; this->type = BOOLEAN; that1 = gParse.Nodes + Node1; this->value.nelem = that1->value.nelem; this->value.naxis = that1->value.naxis; for( i=0; i < that1->value.naxis; i++ ) this->value.naxes[i] = that1->value.naxes[i]; /* Init START/STOP node to be treated as a "constant" */ this->SubNodes[0] = Node0; that0 = gParse.Nodes + Node0; that0->operation = CONST_OP; that0->DoOp = NULL; that0->value.data.ptr= NULL; /* Read in START/STOP times */ if( ffgkyj( fptr, "NAXIS2", &nrows, NULL, &gParse.status ) ) return(-1); that0->value.nelem = nrows; if( nrows ) { that0->value.data.dblptr = (double*)malloc( 2*nrows*sizeof(double) ); if( !that0->value.data.dblptr ) { gParse.status = MEMORY_ALLOCATION; return(-1); } ffgcvd( fptr, startCol, 1L, 1L, nrows, 0.0, that0->value.data.dblptr, &i, &gParse.status ); ffgcvd( fptr, stopCol, 1L, 1L, nrows, 0.0, that0->value.data.dblptr+nrows, &i, &gParse.status ); if( gParse.status ) { free( that0->value.data.dblptr ); return(-1); } /* Test for fully time-ordered GTI... both START && STOP */ that0->type = 1; /* Assume yes */ i = nrows; while( --i ) if( that0->value.data.dblptr[i-1] >= that0->value.data.dblptr[i] || that0->value.data.dblptr[i-1+nrows] >= that0->value.data.dblptr[i+nrows] ) { that0->type = 0; break; } /* Handle TIMEZERO offset, if any */ dt = (timeZeroI[1] - timeZeroI[0]) + (timeZeroF[1] - timeZeroF[0]); timeSpan = that0->value.data.dblptr[nrows+nrows-1] - that0->value.data.dblptr[0]; if( fabs( dt / timeSpan ) > 1e-12 ) { for( i=0; i<(nrows+nrows); i++ ) that0->value.data.dblptr[i] += dt; } } if( gParse.Nodes[Node1].operation==CONST_OP ) this->DoOp( this ); } if( samefile ) ffmahd( fptr, evthdu, &hdutype, &gParse.status ); else ffclos( fptr, &gParse.status ); return( n ); } static int New_REG( char *fname, int NodeX, int NodeY, char *colNames ) { Node *this, *that0; int type, n, Node0; int Xcol, Ycol, tstat; WCSdata wcs; SAORegion *Rgn; char *cX, *cY; FFSTYPE colVal; if( NodeX==-99 ) { type = ffGetVariable( "X", &colVal ); if( type==COLUMN ) { NodeX = New_Column( (int)colVal.lng ); } else { fferror("Could not build X column for REGFILTER"); return(-1); } } if( NodeY==-99 ) { type = ffGetVariable( "Y", &colVal ); if( type==COLUMN ) { NodeY = New_Column( (int)colVal.lng ); } else { fferror("Could not build Y column for REGFILTER"); return(-1); } } NodeX = New_Unary( DOUBLE, 0, NodeX ); NodeY = New_Unary( DOUBLE, 0, NodeY ); Node0 = Alloc_Node(); /* This will hold the Region Data */ if( NodeX<0 || NodeY<0 || Node0<0 ) return(-1); if( ! (Test_Dims( NodeX, NodeY ) ) ) { fferror("Dimensions of REGFILTER arguments are not compatible"); return (-1); } n = Alloc_Node(); if( n >= 0 ) { this = gParse.Nodes + n; this->nSubNodes = 3; this->SubNodes[0] = Node0; this->SubNodes[1] = NodeX; this->SubNodes[2] = NodeY; this->operation = (int)regfilt_fct; this->DoOp = Do_REG; this->type = BOOLEAN; this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; Copy_Dims(n, NodeX); if( SIZE(NodeX)operation = CONST_OP; that0->DoOp = NULL; /* Identify what columns to use for WCS information */ Xcol = Ycol = 0; if( *colNames ) { /* Use the column names in this string for WCS info */ while( *colNames==' ' ) colNames++; cX = cY = colNames; while( *cY && *cY!=' ' && *cY!=',' ) cY++; if( *cY ) *(cY++) = '\0'; while( *cY==' ' ) cY++; if( !*cY ) { fferror("Could not extract valid pair of column names from REGFILTER"); Free_Last_Node(); return( -1 ); } fits_get_colnum( gParse.def_fptr, CASEINSEN, cX, &Xcol, &gParse.status ); fits_get_colnum( gParse.def_fptr, CASEINSEN, cY, &Ycol, &gParse.status ); if( gParse.status ) { fferror("Could not locate columns indicated for WCS info"); Free_Last_Node(); return( -1 ); } } else { /* Try to find columns used in X/Y expressions */ Xcol = Locate_Col( gParse.Nodes + NodeX ); Ycol = Locate_Col( gParse.Nodes + NodeY ); if( Xcol<0 || Ycol<0 ) { fferror("Found multiple X/Y column references in REGFILTER"); Free_Last_Node(); return( -1 ); } } /* Now, get the WCS info, if it exists, from the indicated columns */ wcs.exists = 0; if( Xcol>0 && Ycol>0 ) { tstat = 0; ffgtcs( gParse.def_fptr, Xcol, Ycol, &wcs.xrefval, &wcs.yrefval, &wcs.xrefpix, &wcs.yrefpix, &wcs.xinc, &wcs.yinc, &wcs.rot, wcs.type, &tstat ); if( tstat==NO_WCS_KEY ) { wcs.exists = 0; } else if( tstat ) { gParse.status = tstat; Free_Last_Node(); return( -1 ); } else { wcs.exists = 1; } } /* Read in Region file */ fits_read_rgnfile( fname, &wcs, &Rgn, &gParse.status ); if( gParse.status ) { Free_Last_Node(); return( -1 ); } that0->value.data.ptr = Rgn; if( gParse.Nodes[NodeX].operation==CONST_OP && gParse.Nodes[NodeY].operation==CONST_OP ) this->DoOp( this ); } return( n ); } static int New_Vector( int subNode ) { Node *this, *that; int n; n = Alloc_Node(); if( n >= 0 ) { this = gParse.Nodes + n; that = gParse.Nodes + subNode; this->type = that->type; this->nSubNodes = 1; this->SubNodes[0] = subNode; this->operation = '{'; this->DoOp = Do_Vector; } return( n ); } static int Close_Vec( int vecNode ) { Node *this; int n, nelem=0; this = gParse.Nodes + vecNode; for( n=0; n < this->nSubNodes; n++ ) { if( TYPE( this->SubNodes[n] ) != this->type ) { this->SubNodes[n] = New_Unary( this->type, 0, this->SubNodes[n] ); if( this->SubNodes[n]<0 ) return(-1); } nelem += SIZE(this->SubNodes[n]); } this->value.naxis = 1; this->value.nelem = nelem; this->value.naxes[0] = nelem; return( vecNode ); } static int Locate_Col( Node *this ) /* Locate the TABLE column number of any columns in "this" calculation. */ /* Return ZERO if none found, or negative if more than 1 found. */ { Node *that; int i, col=0, newCol, nfound=0; if( this->nSubNodes==0 && this->operation<=0 && this->operation!=CONST_OP ) return gParse.colData[ - this->operation].colnum; for( i=0; inSubNodes; i++ ) { that = gParse.Nodes + this->SubNodes[i]; if( that->operation>0 ) { newCol = Locate_Col( that ); if( newCol<=0 ) { nfound += -newCol; } else { if( !nfound ) { col = newCol; nfound++; } else if( col != newCol ) { nfound++; } } } else if( that->operation!=CONST_OP ) { /* Found a Column */ newCol = gParse.colData[- that->operation].colnum; if( !nfound ) { col = newCol; nfound++; } else if( col != newCol ) { nfound++; } } } if( nfound!=1 ) return( - nfound ); else return( col ); } static int Test_Dims( int Node1, int Node2 ) { Node *that1, *that2; int valid, i; if( Node1<0 || Node2<0 ) return(0); that1 = gParse.Nodes + Node1; that2 = gParse.Nodes + Node2; if( that1->value.nelem==1 || that2->value.nelem==1 ) valid = 1; else if( that1->type==that2->type && that1->value.nelem==that2->value.nelem && that1->value.naxis==that2->value.naxis ) { valid = 1; for( i=0; ivalue.naxis; i++ ) { if( that1->value.naxes[i]!=that2->value.naxes[i] ) valid = 0; } } else valid = 0; return( valid ); } static void Copy_Dims( int Node1, int Node2 ) { Node *that1, *that2; int i; if( Node1<0 || Node2<0 ) return; that1 = gParse.Nodes + Node1; that2 = gParse.Nodes + Node2; that1->value.nelem = that2->value.nelem; that1->value.naxis = that2->value.naxis; for( i=0; ivalue.naxis; i++ ) that1->value.naxes[i] = that2->value.naxes[i]; } /********************************************************************/ /* Routines for actually evaluating the expression start here */ /********************************************************************/ void Evaluate_Parser( long firstRow, long nRows ) /***********************************************************************/ /* Reset the parser for processing another batch of data... */ /* firstRow: Row number of the first element to evaluate */ /* nRows: Number of rows to be processed */ /* Initialize each COLUMN node so that its UNDEF and DATA pointers */ /* point to the appropriate column arrays. */ /* Finally, call Evaluate_Node for final node. */ /***********************************************************************/ { int i, column; long offset, rowOffset; gParse.firstRow = firstRow; gParse.nRows = nRows; /* Reset Column Nodes' pointers to point to right data and UNDEF arrays */ rowOffset = firstRow - gParse.firstDataRow; for( i=0; i 0 || gParse.Nodes[i].operation == CONST_OP ) continue; column = -gParse.Nodes[i].operation; offset = gParse.varData[column].nelem * rowOffset; gParse.Nodes[i].value.undef = gParse.varData[column].undef + offset; switch( gParse.Nodes[i].type ) { case BITSTR: gParse.Nodes[i].value.data.strptr = (char**)gParse.varData[column].data + rowOffset; gParse.Nodes[i].value.undef = NULL; break; case STRING: gParse.Nodes[i].value.data.strptr = (char**)gParse.varData[column].data + rowOffset; gParse.Nodes[i].value.undef = gParse.varData[column].undef + rowOffset; break; case BOOLEAN: gParse.Nodes[i].value.data.logptr = (char*)gParse.varData[column].data + offset; break; case LONG: gParse.Nodes[i].value.data.lngptr = (long*)gParse.varData[column].data + offset; break; case DOUBLE: gParse.Nodes[i].value.data.dblptr = (double*)gParse.varData[column].data + offset; break; } } Evaluate_Node( gParse.resultNode ); } static void Evaluate_Node( int thisNode ) /**********************************************************************/ /* Recursively evaluate thisNode's subNodes, then call one of the */ /* Do_ functions pointed to by thisNode's DoOp element. */ /**********************************************************************/ { Node *this; int i; if( gParse.status ) return; this = gParse.Nodes + thisNode; if( this->operation>0 ) { /* <=0 indicate constants and columns */ i = this->nSubNodes; while( i-- ) { Evaluate_Node( this->SubNodes[i] ); if( gParse.status ) return; } this->DoOp( this ); } } static void Allocate_Ptrs( Node *this ) { long elem, row, size; if( this->type==BITSTR || this->type==STRING ) { this->value.data.strptr = (char**)malloc( gParse.nRows * sizeof(char*) ); if( this->value.data.strptr ) { this->value.data.strptr[0] = (char*)malloc( gParse.nRows * (this->value.nelem+2) * sizeof(char) ); if( this->value.data.strptr[0] ) { row = 0; while( (++row)value.data.strptr[row] = this->value.data.strptr[row-1] + this->value.nelem+1; } if( this->type==STRING ) { this->value.undef = this->value.data.strptr[row-1] + this->value.nelem+1; } else { this->value.undef = NULL; /* BITSTRs don't use undef array */ } } else { gParse.status = MEMORY_ALLOCATION; free( this->value.data.strptr ); } } else { gParse.status = MEMORY_ALLOCATION; } } else { elem = this->value.nelem * gParse.nRows; switch( this->type ) { case DOUBLE: size = sizeof( double ); break; case LONG: size = sizeof( long ); break; case BOOLEAN: size = sizeof( char ); break; default: size = 1; break; } this->value.data.ptr = calloc(size+1, elem); if( this->value.data.ptr==NULL ) { gParse.status = MEMORY_ALLOCATION; } else { this->value.undef = (char *)this->value.data.ptr + elem*size; } } } static void Do_Unary( Node *this ) { Node *that; long elem; that = gParse.Nodes + this->SubNodes[0]; if( that->operation==CONST_OP ) { /* Operating on a constant! */ switch( this->operation ) { case DOUBLE: case FLTCAST: if( that->type==LONG ) this->value.data.dbl = (double)that->value.data.lng; else if( that->type==BOOLEAN ) this->value.data.dbl = ( that->value.data.log ? 1.0 : 0.0 ); break; case LONG: case INTCAST: if( that->type==DOUBLE ) this->value.data.lng = (long)that->value.data.dbl; else if( that->type==BOOLEAN ) this->value.data.lng = ( that->value.data.log ? 1L : 0L ); break; case BOOLEAN: if( that->type==DOUBLE ) this->value.data.log = ( that->value.data.dbl != 0.0 ); else if( that->type==LONG ) this->value.data.log = ( that->value.data.lng != 0L ); break; case UMINUS: if( that->type==DOUBLE ) this->value.data.dbl = - that->value.data.dbl; else if( that->type==LONG ) this->value.data.lng = - that->value.data.lng; break; case NOT: if( that->type==BOOLEAN ) this->value.data.log = ( ! that->value.data.log ); else if( that->type==BITSTR ) bitnot( this->value.data.str, that->value.data.str ); break; } this->operation = CONST_OP; } else { Allocate_Ptrs( this ); if( !gParse.status ) { if( this->type!=BITSTR ) { elem = gParse.nRows; if( this->type!=STRING ) elem *= this->value.nelem; while( elem-- ) this->value.undef[elem] = that->value.undef[elem]; } elem = gParse.nRows * this->value.nelem; switch( this->operation ) { case BOOLEAN: if( that->type==DOUBLE ) while( elem-- ) this->value.data.logptr[elem] = ( that->value.data.dblptr[elem] != 0.0 ); else if( that->type==LONG ) while( elem-- ) this->value.data.logptr[elem] = ( that->value.data.lngptr[elem] != 0L ); break; case DOUBLE: case FLTCAST: if( that->type==LONG ) while( elem-- ) this->value.data.dblptr[elem] = (double)that->value.data.lngptr[elem]; else if( that->type==BOOLEAN ) while( elem-- ) this->value.data.dblptr[elem] = ( that->value.data.logptr[elem] ? 1.0 : 0.0 ); break; case LONG: case INTCAST: if( that->type==DOUBLE ) while( elem-- ) this->value.data.lngptr[elem] = (long)that->value.data.dblptr[elem]; else if( that->type==BOOLEAN ) while( elem-- ) this->value.data.lngptr[elem] = ( that->value.data.logptr[elem] ? 1L : 0L ); break; case UMINUS: if( that->type==DOUBLE ) { while( elem-- ) this->value.data.dblptr[elem] = - that->value.data.dblptr[elem]; } else if( that->type==LONG ) { while( elem-- ) this->value.data.lngptr[elem] = - that->value.data.lngptr[elem]; } break; case NOT: if( that->type==BOOLEAN ) { while( elem-- ) this->value.data.logptr[elem] = ( ! that->value.data.logptr[elem] ); } else if( that->type==BITSTR ) { elem = gParse.nRows; while( elem-- ) bitnot( this->value.data.strptr[elem], that->value.data.strptr[elem] ); } break; } } } if( that->operation>0 ) { free( that->value.data.ptr ); } } static void Do_Offset( Node *this ) { Node *col; long fRow, nRowOverlap, nRowReload, rowOffset; long nelem, elem, offset, nRealElem; int status; col = gParse.Nodes + this->SubNodes[0]; rowOffset = gParse.Nodes[ this->SubNodes[1] ].value.data.lng; Allocate_Ptrs( this ); fRow = gParse.firstRow + rowOffset; if( this->type==STRING || this->type==BITSTR ) nRealElem = 1; else nRealElem = this->value.nelem; nelem = nRealElem; if( fRow < gParse.firstDataRow ) { /* Must fill in data at start of array */ nRowReload = gParse.firstDataRow - fRow; if( nRowReload > gParse.nRows ) nRowReload = gParse.nRows; nRowOverlap = gParse.nRows - nRowReload; offset = 0; /* NULLify any values falling out of bounds */ while( fRow<1 && nRowReload>0 ) { if( this->type == BITSTR ) { nelem = this->value.nelem; this->value.data.strptr[offset][ nelem ] = '\0'; while( nelem-- ) this->value.data.strptr[offset][nelem] = '0'; offset++; } else { while( nelem-- ) this->value.undef[offset++] = 1; } nelem = nRealElem; fRow++; nRowReload--; } } else if( fRow + gParse.nRows > gParse.firstDataRow + gParse.nDataRows ) { /* Must fill in data at end of array */ nRowReload = (fRow+gParse.nRows) - (gParse.firstDataRow+gParse.nDataRows); if( nRowReload>gParse.nRows ) { nRowReload = gParse.nRows; } else { fRow = gParse.firstDataRow + gParse.nDataRows; } nRowOverlap = gParse.nRows - nRowReload; offset = nRowOverlap * nelem; /* NULLify any values falling out of bounds */ elem = gParse.nRows * nelem; while( fRow+nRowReload>gParse.totalRows && nRowReload>0 ) { if( this->type == BITSTR ) { nelem = this->value.nelem; elem--; this->value.data.strptr[elem][ nelem ] = '\0'; while( nelem-- ) this->value.data.strptr[elem][nelem] = '0'; } else { while( nelem-- ) this->value.undef[--elem] = 1; } nelem = nRealElem; nRowReload--; } } else { nRowReload = 0; nRowOverlap = gParse.nRows; offset = 0; } if( nRowReload>0 ) { switch( this->type ) { case BITSTR: case STRING: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.strptr+offset, this->value.undef+offset ); break; case BOOLEAN: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.logptr+offset, this->value.undef+offset ); break; case LONG: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.lngptr+offset, this->value.undef+offset ); break; case DOUBLE: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.dblptr+offset, this->value.undef+offset ); break; } } /* Now copy over the overlapping region, if any */ if( nRowOverlap <= 0 ) return; if( rowOffset>0 ) elem = nRowOverlap * nelem; else elem = gParse.nRows * nelem; offset = nelem * rowOffset; while( nRowOverlap-- && !gParse.status ) { while( nelem-- && !gParse.status ) { elem--; if( this->type != BITSTR ) this->value.undef[elem] = col->value.undef[elem+offset]; switch( this->type ) { case BITSTR: strcpy( this->value.data.strptr[elem ], col->value.data.strptr[elem+offset] ); break; case STRING: strcpy( this->value.data.strptr[elem ], col->value.data.strptr[elem+offset] ); break; case BOOLEAN: this->value.data.logptr[elem] = col->value.data.logptr[elem+offset]; break; case LONG: this->value.data.lngptr[elem] = col->value.data.lngptr[elem+offset]; break; case DOUBLE: this->value.data.dblptr[elem] = col->value.data.dblptr[elem+offset]; break; } } nelem = nRealElem; } } static void Do_BinOp_bit( Node *this ) { Node *that1, *that2; char *sptr1=NULL, *sptr2=NULL; int const1, const2; long rows; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; const1 = ( that1->operation==CONST_OP ); const2 = ( that2->operation==CONST_OP ); sptr1 = ( const1 ? that1->value.data.str : NULL ); sptr2 = ( const2 ? that2->value.data.str : NULL ); if( const1 && const2 ) { switch( this->operation ) { case NE: this->value.data.log = !bitcmp( sptr1, sptr2 ); break; case EQ: this->value.data.log = bitcmp( sptr1, sptr2 ); break; case GT: case LT: case LTE: case GTE: this->value.data.log = bitlgte( sptr1, this->operation, sptr2 ); break; case '|': bitor( this->value.data.str, sptr1, sptr2 ); break; case '&': bitand( this->value.data.str, sptr1, sptr2 ); break; case '+': strcpy( this->value.data.str, sptr1 ); strcat( this->value.data.str, sptr2 ); break; case ACCUM: this->value.data.lng = 0; while( *sptr1 ) { if ( *sptr1 == '1' ) this->value.data.lng ++; sptr1 ++; } break; } this->operation = CONST_OP; } else { Allocate_Ptrs( this ); if( !gParse.status ) { rows = gParse.nRows; switch( this->operation ) { /* BITSTR comparisons */ case NE: case EQ: case GT: case LT: case LTE: case GTE: while( rows-- ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; switch( this->operation ) { case NE: this->value.data.logptr[rows] = !bitcmp( sptr1, sptr2 ); break; case EQ: this->value.data.logptr[rows] = bitcmp( sptr1, sptr2 ); break; case GT: case LT: case LTE: case GTE: this->value.data.logptr[rows] = bitlgte( sptr1, this->operation, sptr2 ); break; } this->value.undef[rows] = 0; } break; /* BITSTR AND/ORs ... no UNDEFS in or out */ case '|': case '&': case '+': while( rows-- ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; if( this->operation=='|' ) bitor( this->value.data.strptr[rows], sptr1, sptr2 ); else if( this->operation=='&' ) bitand( this->value.data.strptr[rows], sptr1, sptr2 ); else { strcpy( this->value.data.strptr[rows], sptr1 ); strcat( this->value.data.strptr[rows], sptr2 ); } } break; /* Accumulate 1 bits */ case ACCUM: { long i, previous, curr; previous = that2->value.data.lng; /* Cumulative sum of this chunk */ for (i=0; ivalue.data.strptr[i]; for (curr = 0; *sptr1; sptr1 ++) { if ( *sptr1 == '1' ) curr ++; } previous += curr; this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } /* Store final cumulant for next pass */ that2->value.data.lng = previous; } } } } if( that1->operation>0 ) { free( that1->value.data.strptr[0] ); free( that1->value.data.strptr ); } if( that2->operation>0 ) { free( that2->value.data.strptr[0] ); free( that2->value.data.strptr ); } } static void Do_BinOp_str( Node *this ) { Node *that1, *that2; char *sptr1, *sptr2, null1=0, null2=0; int const1, const2, val; long rows; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; const1 = ( that1->operation==CONST_OP ); const2 = ( that2->operation==CONST_OP ); sptr1 = ( const1 ? that1->value.data.str : NULL ); sptr2 = ( const2 ? that2->value.data.str : NULL ); if( const1 && const2 ) { /* Result is a constant */ switch( this->operation ) { /* Compare Strings */ case NE: case EQ: val = ( FSTRCMP( sptr1, sptr2 ) == 0 ); this->value.data.log = ( this->operation==EQ ? val : !val ); break; case GT: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) > 0 ); break; case LT: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) < 0 ); break; case GTE: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) >= 0 ); break; case LTE: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) <= 0 ); break; /* Concat Strings */ case '+': strcpy( this->value.data.str, sptr1 ); strcat( this->value.data.str, sptr2 ); break; } this->operation = CONST_OP; } else { /* Not a constant */ Allocate_Ptrs( this ); if( !gParse.status ) { rows = gParse.nRows; switch( this->operation ) { /* Compare Strings */ case NE: case EQ: while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; val = ( FSTRCMP( sptr1, sptr2 ) == 0 ); this->value.data.logptr[rows] = ( this->operation==EQ ? val : !val ); } } break; case GT: case LT: while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; val = ( FSTRCMP( sptr1, sptr2 ) ); this->value.data.logptr[rows] = ( this->operation==GT ? val>0 : val<0 ); } } break; case GTE: case LTE: while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; val = ( FSTRCMP( sptr1, sptr2 ) ); this->value.data.logptr[rows] = ( this->operation==GTE ? val>=0 : val<=0 ); } } break; /* Concat Strings */ case '+': while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; strcpy( this->value.data.strptr[rows], sptr1 ); strcat( this->value.data.strptr[rows], sptr2 ); } } break; } } } if( that1->operation>0 ) { free( that1->value.data.strptr[0] ); free( that1->value.data.strptr ); } if( that2->operation>0 ) { free( that2->value.data.strptr[0] ); free( that2->value.data.strptr ); } } static void Do_BinOp_log( Node *this ) { Node *that1, *that2; int vector1, vector2; char val1=0, val2=0, null1=0, null2=0; long rows, nelem, elem; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; vector1 = ( that1->operation!=CONST_OP ); if( vector1 ) vector1 = that1->value.nelem; else { val1 = that1->value.data.log; } vector2 = ( that2->operation!=CONST_OP ); if( vector2 ) vector2 = that2->value.nelem; else { val2 = that2->value.data.log; } if( !vector1 && !vector2 ) { /* Result is a constant */ switch( this->operation ) { case OR: this->value.data.log = (val1 || val2); break; case AND: this->value.data.log = (val1 && val2); break; case EQ: this->value.data.log = ( (val1 && val2) || (!val1 && !val2) ); break; case NE: this->value.data.log = ( (val1 && !val2) || (!val1 && val2) ); break; case ACCUM: this->value.data.lng = val1; break; } this->operation=CONST_OP; } else if (this->operation == ACCUM) { long i, previous, curr; rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { previous = that2->value.data.lng; /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.logptr[i]; previous += curr; } this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } /* Store final cumulant for next pass */ that2->value.data.lng = previous; } } else { rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { if (this->operation == ACCUM) { long i, previous, curr; previous = that2->value.data.lng; /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.logptr[i]; previous += curr; } this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } /* Store final cumulant for next pass */ that2->value.data.lng = previous; } while( rows-- ) { while( nelem-- ) { elem--; if( vector1>1 ) { val1 = that1->value.data.logptr[elem]; null1 = that1->value.undef[elem]; } else if( vector1 ) { val1 = that1->value.data.logptr[rows]; null1 = that1->value.undef[rows]; } if( vector2>1 ) { val2 = that2->value.data.logptr[elem]; null2 = that2->value.undef[elem]; } else if( vector2 ) { val2 = that2->value.data.logptr[rows]; null2 = that2->value.undef[rows]; } this->value.undef[elem] = (null1 || null2); switch( this->operation ) { case OR: /* This is more complicated than others to suppress UNDEFs */ /* in those cases where the other argument is DEF && TRUE */ if( !null1 && !null2 ) { this->value.data.logptr[elem] = (val1 || val2); } else if( (null1 && !null2 && val2) || ( !null1 && null2 && val1 ) ) { this->value.data.logptr[elem] = 1; this->value.undef[elem] = 0; } break; case AND: /* This is more complicated than others to suppress UNDEFs */ /* in those cases where the other argument is DEF && FALSE */ if( !null1 && !null2 ) { this->value.data.logptr[elem] = (val1 && val2); } else if( (null1 && !null2 && !val2) || ( !null1 && null2 && !val1 ) ) { this->value.data.logptr[elem] = 0; this->value.undef[elem] = 0; } break; case EQ: this->value.data.logptr[elem] = ( (val1 && val2) || (!val1 && !val2) ); break; case NE: this->value.data.logptr[elem] = ( (val1 && !val2) || (!val1 && val2) ); break; } } nelem = this->value.nelem; } } } if( that1->operation>0 ) { free( that1->value.data.ptr ); } if( that2->operation>0 ) { free( that2->value.data.ptr ); } } static void Do_BinOp_lng( Node *this ) { Node *that1, *that2; int vector1, vector2; long val1=0, val2=0; char null1=0, null2=0; long rows, nelem, elem; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; vector1 = ( that1->operation!=CONST_OP ); if( vector1 ) vector1 = that1->value.nelem; else { val1 = that1->value.data.lng; } vector2 = ( that2->operation!=CONST_OP ); if( vector2 ) vector2 = that2->value.nelem; else { val2 = that2->value.data.lng; } if( !vector1 && !vector2 ) { /* Result is a constant */ switch( this->operation ) { case '~': /* Treat as == for LONGS */ case EQ: this->value.data.log = (val1 == val2); break; case NE: this->value.data.log = (val1 != val2); break; case GT: this->value.data.log = (val1 > val2); break; case LT: this->value.data.log = (val1 < val2); break; case LTE: this->value.data.log = (val1 <= val2); break; case GTE: this->value.data.log = (val1 >= val2); break; case '+': this->value.data.lng = (val1 + val2); break; case '-': this->value.data.lng = (val1 - val2); break; case '*': this->value.data.lng = (val1 * val2); break; case '%': if( val2 ) this->value.data.lng = (val1 % val2); else fferror("Divide by Zero"); break; case '/': if( val2 ) this->value.data.lng = (val1 / val2); else fferror("Divide by Zero"); break; case POWER: this->value.data.lng = (long)pow((double)val1,(double)val2); break; case ACCUM: this->value.data.lng = val1; break; case DIFF: this->value.data.lng = 0; break; } this->operation=CONST_OP; } else if ((this->operation == ACCUM) || (this->operation == DIFF)) { long i, previous, curr; long undef; rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { previous = that2->value.data.lng; undef = (long) that2->value.undef; if (this->operation == ACCUM) { /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.lngptr[i]; previous += curr; } this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } } else { /* Sequential difference for this chunk */ for (i=0; ivalue.data.lngptr[i]; if (that1->value.undef[i] || undef) { /* Either this, or previous, value was undefined */ this->value.data.lngptr[i] = 0; this->value.undef[i] = 1; } else { /* Both defined, we are okay! */ this->value.data.lngptr[i] = curr - previous; this->value.undef[i] = 0; } previous = curr; undef = that1->value.undef[i]; } } /* Store final cumulant for next pass */ that2->value.data.lng = previous; that2->value.undef = (char *) undef; /* XXX evil, but no harm here */ } } else { rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); while( rows-- && !gParse.status ) { while( nelem-- && !gParse.status ) { elem--; if( vector1>1 ) { val1 = that1->value.data.lngptr[elem]; null1 = that1->value.undef[elem]; } else if( vector1 ) { val1 = that1->value.data.lngptr[rows]; null1 = that1->value.undef[rows]; } if( vector2>1 ) { val2 = that2->value.data.lngptr[elem]; null2 = that2->value.undef[elem]; } else if( vector2 ) { val2 = that2->value.data.lngptr[rows]; null2 = that2->value.undef[rows]; } this->value.undef[elem] = (null1 || null2); switch( this->operation ) { case '~': /* Treat as == for LONGS */ case EQ: this->value.data.logptr[elem] = (val1 == val2); break; case NE: this->value.data.logptr[elem] = (val1 != val2); break; case GT: this->value.data.logptr[elem] = (val1 > val2); break; case LT: this->value.data.logptr[elem] = (val1 < val2); break; case LTE: this->value.data.logptr[elem] = (val1 <= val2); break; case GTE: this->value.data.logptr[elem] = (val1 >= val2); break; case '+': this->value.data.lngptr[elem] = (val1 + val2); break; case '-': this->value.data.lngptr[elem] = (val1 - val2); break; case '*': this->value.data.lngptr[elem] = (val1 * val2); break; case '%': if( val2 ) this->value.data.lngptr[elem] = (val1 % val2); else { this->value.data.lngptr[elem] = 0; this->value.undef[elem] = 1; } break; case '/': if( val2 ) this->value.data.lngptr[elem] = (val1 / val2); else { this->value.data.lngptr[elem] = 0; this->value.undef[elem] = 1; } break; case POWER: this->value.data.lngptr[elem] = (long)pow((double)val1,(double)val2); break; } } nelem = this->value.nelem; } } if( that1->operation>0 ) { free( that1->value.data.ptr ); } if( that2->operation>0 ) { free( that2->value.data.ptr ); } } static void Do_BinOp_dbl( Node *this ) { Node *that1, *that2; int vector1, vector2; double val1=0.0, val2=0.0; char null1=0, null2=0; long rows, nelem, elem; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; vector1 = ( that1->operation!=CONST_OP ); if( vector1 ) vector1 = that1->value.nelem; else { val1 = that1->value.data.dbl; } vector2 = ( that2->operation!=CONST_OP ); if( vector2 ) vector2 = that2->value.nelem; else { val2 = that2->value.data.dbl; } if( !vector1 && !vector2 ) { /* Result is a constant */ switch( this->operation ) { case '~': this->value.data.log = ( fabs(val1-val2) < APPROX ); break; case EQ: this->value.data.log = (val1 == val2); break; case NE: this->value.data.log = (val1 != val2); break; case GT: this->value.data.log = (val1 > val2); break; case LT: this->value.data.log = (val1 < val2); break; case LTE: this->value.data.log = (val1 <= val2); break; case GTE: this->value.data.log = (val1 >= val2); break; case '+': this->value.data.dbl = (val1 + val2); break; case '-': this->value.data.dbl = (val1 - val2); break; case '*': this->value.data.dbl = (val1 * val2); break; case '%': if( val2 ) this->value.data.dbl = val1 - val2*((int)(val1/val2)); else fferror("Divide by Zero"); break; case '/': if( val2 ) this->value.data.dbl = (val1 / val2); else fferror("Divide by Zero"); break; case POWER: this->value.data.dbl = (double)pow(val1,val2); break; case ACCUM: this->value.data.dbl = val1; break; case DIFF: this->value.data.dbl = 0; break; } this->operation=CONST_OP; } else if ((this->operation == ACCUM) || (this->operation == DIFF)) { long i; long undef; double previous, curr; rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { previous = that2->value.data.dbl; undef = (long) that2->value.undef; if (this->operation == ACCUM) { /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.dblptr[i]; previous += curr; } this->value.data.dblptr[i] = previous; this->value.undef[i] = 0; } } else { /* Sequential difference for this chunk */ for (i=0; ivalue.data.dblptr[i]; if (that1->value.undef[i] || undef) { /* Either this, or previous, value was undefined */ this->value.data.dblptr[i] = 0; this->value.undef[i] = 1; } else { /* Both defined, we are okay! */ this->value.data.dblptr[i] = curr - previous; this->value.undef[i] = 0; } previous = curr; undef = that1->value.undef[i]; } } /* Store final cumulant for next pass */ that2->value.data.dbl = previous; that2->value.undef = (char *) undef; /* XXX evil, but no harm here */ } } else { rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); while( rows-- && !gParse.status ) { while( nelem-- && !gParse.status ) { elem--; if( vector1>1 ) { val1 = that1->value.data.dblptr[elem]; null1 = that1->value.undef[elem]; } else if( vector1 ) { val1 = that1->value.data.dblptr[rows]; null1 = that1->value.undef[rows]; } if( vector2>1 ) { val2 = that2->value.data.dblptr[elem]; null2 = that2->value.undef[elem]; } else if( vector2 ) { val2 = that2->value.data.dblptr[rows]; null2 = that2->value.undef[rows]; } this->value.undef[elem] = (null1 || null2); switch( this->operation ) { case '~': this->value.data.logptr[elem] = ( fabs(val1-val2) < APPROX ); break; case EQ: this->value.data.logptr[elem] = (val1 == val2); break; case NE: this->value.data.logptr[elem] = (val1 != val2); break; case GT: this->value.data.logptr[elem] = (val1 > val2); break; case LT: this->value.data.logptr[elem] = (val1 < val2); break; case LTE: this->value.data.logptr[elem] = (val1 <= val2); break; case GTE: this->value.data.logptr[elem] = (val1 >= val2); break; case '+': this->value.data.dblptr[elem] = (val1 + val2); break; case '-': this->value.data.dblptr[elem] = (val1 - val2); break; case '*': this->value.data.dblptr[elem] = (val1 * val2); break; case '%': if( val2 ) this->value.data.dblptr[elem] = val1 - val2*((int)(val1/val2)); else { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } break; case '/': if( val2 ) this->value.data.dblptr[elem] = (val1 / val2); else { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } break; case POWER: this->value.data.dblptr[elem] = (double)pow(val1,val2); break; } } nelem = this->value.nelem; } } if( that1->operation>0 ) { free( that1->value.data.ptr ); } if( that2->operation>0 ) { free( that2->value.data.ptr ); } } /* * This Quickselect routine is based on the algorithm described in * "Numerical recipes in C", Second Edition, * Cambridge University Press, 1992, Section 8.5, ISBN 0-521-43108-5 * This code by Nicolas Devillard - 1998. Public domain. * http://ndevilla.free.fr/median/median/src/quickselect.c */ #define ELEM_SWAP(a,b) { register long t=(a);(a)=(b);(b)=t; } /* * qselect_median_lng - select the median value of a long array * * This routine selects the median value of the long integer array * arr[]. If there are an even number of elements, the "lower median" * is selected. * * The array arr[] is scrambled, so users must operate on a scratch * array if they wish the values to be preserved. * * long arr[] - array of values * int n - number of elements in arr * * RETURNS: the lower median value of arr[] * */ long qselect_median_lng(long arr[], int n) { int low, high ; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) { /* One element only */ return arr[median]; } if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median]; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP #define ELEM_SWAP(a,b) { register double t=(a);(a)=(b);(b)=t; } /* * qselect_median_dbl - select the median value of a double array * * This routine selects the median value of the double array * arr[]. If there are an even number of elements, the "lower median" * is selected. * * The array arr[] is scrambled, so users must operate on a scratch * array if they wish the values to be preserved. * * double arr[] - array of values * int n - number of elements in arr * * RETURNS: the lower median value of arr[] * */ double qselect_median_dbl(double arr[], int n) { int low, high ; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) { /* One element only */ return arr[median] ; } if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median] ; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP /* * angsep_calc - compute angular separation between celestial coordinates * * This routine computes the angular separation between to coordinates * on the celestial sphere (i.e. RA and Dec). Note that all units are * in DEGREES, unlike the other trig functions in the calculator. * * double ra1, dec1 - RA and Dec of the first position in degrees * double ra2, dec2 - RA and Dec of the second position in degrees * * RETURNS: (double) angular separation in degrees * */ double angsep_calc(double ra1, double dec1, double ra2, double dec2) { double cd; static double deg = 0; if (deg == 0) deg = ((double)4)*atan((double)1)/((double)180); /* deg = 1.0; **** UNCOMMENT IF YOU WANT RADIANS */ cd = sin(dec1*deg)*sin(dec2*deg) + cos(dec1*deg)*cos(dec2*deg)*cos((ra1-ra2)*deg); if (cd < (-1)) cd = -1; if (cd > (+1)) cd = +1; return acos(cd)/deg; } static double ran1() { static double dval = 0.0; double rndVal; if (dval == 0.0) { if( rand()<32768 && rand()<32768 ) dval = 32768.0; else dval = 2147483648.0; } rndVal = (double)rand(); while( rndVal > dval ) dval *= 2.0; return rndVal/dval; } /* Gaussian deviate routine from Numerical Recipes */ static double gasdev() { static int iset = 0; static double gset; double fac, rsq, v1, v2; if (iset == 0) { do { v1 = 2.0*ran1()-1.0; v2 = 2.0*ran1()-1.0; rsq = v1*v1 + v2*v2; } while (rsq >= 1.0 || rsq == 0.0); fac = sqrt(-2.0*log(rsq)/rsq); gset = v1*fac; iset = 1; return v2*fac; } else { iset = 0; return gset; } } /* lgamma function - from Numerical Recipes */ float gammaln(float xx) /* Returns the value ln Gamma[(xx)] for xx > 0. */ { /* Internal arithmetic will be done in double precision, a nicety that you can omit if five-figure accuracy is good enough. */ double x,y,tmp,ser; static double cof[6]={76.18009172947146,-86.50532032941677, 24.01409824083091,-1.231739572450155, 0.1208650973866179e-2,-0.5395239384953e-5}; int j; y=x=xx; tmp=x+5.5; tmp -= (x+0.5)*log(tmp); ser=1.000000000190015; for (j=0;j<=5;j++) ser += cof[j]/++y; return (float) -tmp+log(2.5066282746310005*ser/x); } /* Poisson deviate - derived from Numerical Recipes */ static long poidev(double xm) { static double sq, alxm, g, oldm = -1.0; static double pi = 0; double em, t, y; if (pi == 0) pi = ((double)4)*atan((double)1); if (xm < 20.0) { if (xm != oldm) { oldm = xm; g = exp(-xm); } em = -1; t = 1.0; do { em += 1; t *= ran1(); } while (t > g); } else { if (xm != oldm) { oldm = xm; sq = sqrt(2.0*xm); alxm = log(xm); g = xm*alxm-gammaln( (float) (xm+1.0)); } do { do { y = tan(pi*ran1()); em = sq*y+xm; } while (em < 0.0); em = floor(em); t = 0.9*(1.0+y*y)*exp(em*alxm-gammaln( (float) (em+1.0) )-g); } while (ran1() > t); } /* Return integer version */ return (long int) floor(em+0.5); } static void Do_Func( Node *this ) { Node *theParams[MAXSUBS]; int vector[MAXSUBS], allConst; lval pVals[MAXSUBS]; char pNull[MAXSUBS]; long ival; double dval; int i, valInit; long row, elem, nelem; i = this->nSubNodes; allConst = 1; while( i-- ) { theParams[i] = gParse.Nodes + this->SubNodes[i]; vector[i] = ( theParams[i]->operation!=CONST_OP ); if( vector[i] ) { allConst = 0; vector[i] = theParams[i]->value.nelem; } else { if( theParams[i]->type==DOUBLE ) { pVals[i].data.dbl = theParams[i]->value.data.dbl; } else if( theParams[i]->type==LONG ) { pVals[i].data.lng = theParams[i]->value.data.lng; } else if( theParams[i]->type==BOOLEAN ) { pVals[i].data.log = theParams[i]->value.data.log; } else strcpy(pVals[i].data.str, theParams[i]->value.data.str); pNull[i] = 0; } } if( this->nSubNodes==0 ) allConst = 0; /* These do produce scalars */ if( this->operation == poirnd_fct ) allConst = 0; if( allConst ) { switch( this->operation ) { /* Non-Trig single-argument functions */ case sum_fct: if( theParams[0]->type==BOOLEAN ) this->value.data.lng = ( pVals[0].data.log ? 1 : 0 ); else if( theParams[0]->type==LONG ) this->value.data.lng = pVals[0].data.lng; else if( theParams[0]->type==DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( theParams[0]->type==BITSTR ) strcpy(this->value.data.str, pVals[0].data.str); break; case average_fct: if( theParams[0]->type==LONG ) this->value.data.dbl = pVals[0].data.lng; else if( theParams[0]->type==DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; break; case stddev_fct: this->value.data.dbl = 0; /* Standard deviation of a constant = 0 */ break; case median_fct: if( theParams[0]->type==BOOLEAN ) this->value.data.lng = ( pVals[0].data.log ? 1 : 0 ); else if( theParams[0]->type==LONG ) this->value.data.lng = pVals[0].data.lng; else this->value.data.dbl = pVals[0].data.dbl; break; case poirnd_fct: if( theParams[0]->type==DOUBLE ) this->value.data.lng = poidev(pVals[0].data.dbl); else this->value.data.lng = poidev(pVals[0].data.lng); break; case abs_fct: if( theParams[0]->type==DOUBLE ) { dval = pVals[0].data.dbl; this->value.data.dbl = (dval>0.0 ? dval : -dval); } else { ival = pVals[0].data.lng; this->value.data.lng = (ival> 0 ? ival : -ival); } break; /* Special Null-Handling Functions */ case nonnull_fct: this->value.data.lng = 1; /* Constants are always 1-element and defined */ break; case isnull_fct: /* Constants are always defined */ this->value.data.log = 0; break; case defnull_fct: if( this->type==BOOLEAN ) this->value.data.log = pVals[0].data.log; else if( this->type==LONG ) this->value.data.lng = pVals[0].data.lng; else if( this->type==DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( this->type==STRING ) strcpy(this->value.data.str,pVals[0].data.str); break; /* Math functions with 1 double argument */ case sin_fct: this->value.data.dbl = sin( pVals[0].data.dbl ); break; case cos_fct: this->value.data.dbl = cos( pVals[0].data.dbl ); break; case tan_fct: this->value.data.dbl = tan( pVals[0].data.dbl ); break; case asin_fct: dval = pVals[0].data.dbl; if( dval<-1.0 || dval>1.0 ) fferror("Out of range argument to arcsin"); else this->value.data.dbl = asin( dval ); break; case acos_fct: dval = pVals[0].data.dbl; if( dval<-1.0 || dval>1.0 ) fferror("Out of range argument to arccos"); else this->value.data.dbl = acos( dval ); break; case atan_fct: this->value.data.dbl = atan( pVals[0].data.dbl ); break; case sinh_fct: this->value.data.dbl = sinh( pVals[0].data.dbl ); break; case cosh_fct: this->value.data.dbl = cosh( pVals[0].data.dbl ); break; case tanh_fct: this->value.data.dbl = tanh( pVals[0].data.dbl ); break; case exp_fct: this->value.data.dbl = exp( pVals[0].data.dbl ); break; case log_fct: dval = pVals[0].data.dbl; if( dval<=0.0 ) fferror("Out of range argument to log"); else this->value.data.dbl = log( dval ); break; case log10_fct: dval = pVals[0].data.dbl; if( dval<=0.0 ) fferror("Out of range argument to log10"); else this->value.data.dbl = log10( dval ); break; case sqrt_fct: dval = pVals[0].data.dbl; if( dval<0.0 ) fferror("Out of range argument to sqrt"); else this->value.data.dbl = sqrt( dval ); break; case ceil_fct: this->value.data.dbl = ceil( pVals[0].data.dbl ); break; case floor_fct: this->value.data.dbl = floor( pVals[0].data.dbl ); break; case round_fct: this->value.data.dbl = floor( pVals[0].data.dbl + 0.5 ); break; /* Two-argument Trig Functions */ case atan2_fct: this->value.data.dbl = atan2( pVals[0].data.dbl, pVals[1].data.dbl ); break; /* Four-argument ANGSEP function */ case angsep_fct: this->value.data.dbl = angsep_calc(pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl); /* Min/Max functions taking 1 or 2 arguments */ case min1_fct: /* No constant vectors! */ if( this->type == DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( this->type == LONG ) this->value.data.lng = pVals[0].data.lng; else if( this->type == BITSTR ) strcpy(this->value.data.str, pVals[0].data.str); break; case min2_fct: if( this->type == DOUBLE ) this->value.data.dbl = minvalue( pVals[0].data.dbl, pVals[1].data.dbl ); else if( this->type == LONG ) this->value.data.lng = minvalue( pVals[0].data.lng, pVals[1].data.lng ); break; case max1_fct: /* No constant vectors! */ if( this->type == DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( this->type == LONG ) this->value.data.lng = pVals[0].data.lng; else if( this->type == BITSTR ) strcpy(this->value.data.str, pVals[0].data.str); break; case max2_fct: if( this->type == DOUBLE ) this->value.data.dbl = maxvalue( pVals[0].data.dbl, pVals[1].data.dbl ); else if( this->type == LONG ) this->value.data.lng = maxvalue( pVals[0].data.lng, pVals[1].data.lng ); break; /* Boolean SAO region Functions... scalar or vector dbls */ case near_fct: this->value.data.log = bnear( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl ); break; case circle_fct: this->value.data.log = circle( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl ); break; case box_fct: this->value.data.log = saobox( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); break; case elps_fct: this->value.data.log = ellipse( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); break; /* C Conditional expression: bool ? expr : expr */ case ifthenelse_fct: switch( this->type ) { case BOOLEAN: this->value.data.log = ( pVals[2].data.log ? pVals[0].data.log : pVals[1].data.log ); break; case LONG: this->value.data.lng = ( pVals[2].data.log ? pVals[0].data.lng : pVals[1].data.lng ); break; case DOUBLE: this->value.data.dbl = ( pVals[2].data.log ? pVals[0].data.dbl : pVals[1].data.dbl ); break; case STRING: strcpy(this->value.data.str, ( pVals[2].data.log ? pVals[0].data.str : pVals[1].data.str ) ); break; } break; } this->operation = CONST_OP; } else { Allocate_Ptrs( this ); row = gParse.nRows; elem = row * this->value.nelem; if( !gParse.status ) { switch( this->operation ) { /* Special functions with no arguments */ case row_fct: while( row-- ) { this->value.data.lngptr[row] = gParse.firstRow + row; this->value.undef[row] = 0; } break; case null_fct: if( this->type==LONG ) { while( row-- ) { this->value.data.lngptr[row] = 0; this->value.undef[row] = 1; } } else if( this->type==STRING ) { while( row-- ) { this->value.data.strptr[row][0] = '\0'; this->value.undef[row] = 1; } } break; case rnd_fct: while( row-- ) { this->value.data.dblptr[row] = ran1(); this->value.undef[row] = 0; } break; case gasrnd_fct: while( row-- ) { this->value.data.dblptr[row] = gasdev(); this->value.undef[row] = 0; } break; case poirnd_fct: if( theParams[0]->type==DOUBLE ) { if (theParams[0]->operation == CONST_OP) { while( elem-- ) { this->value.undef[elem] = (pVals[0].data.dbl < 0); if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = poidev(pVals[0].data.dbl); } } } else { while( elem-- ) { this->value.undef[elem] = theParams[0]->value.undef[elem]; if (theParams[0]->value.data.dblptr[elem] < 0) this->value.undef[elem] = 1; if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = poidev(theParams[0]->value.data.dblptr[elem]); } } /* while */ } /* ! CONST_OP */ } else { /* LONG */ if (theParams[0]->operation == CONST_OP) { while( elem-- ) { this->value.undef[elem] = (pVals[0].data.lng < 0); if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = poidev(pVals[0].data.lng); } } } else { while( elem-- ) { this->value.undef[elem] = theParams[0]->value.undef[elem]; if (theParams[0]->value.data.lngptr[elem] < 0) this->value.undef[elem] = 1; if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = poidev(theParams[0]->value.data.lngptr[elem]); } } /* while */ } /* ! CONST_OP */ } /* END LONG */ break; /* Non-Trig single-argument functions */ case sum_fct: elem = row * theParams[0]->value.nelem; if( theParams[0]->type==BOOLEAN ) { while( row-- ) { this->value.data.lngptr[row] = 0; /* Default is UNDEF until a defined value is found */ this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( ! theParams[0]->value.undef[elem] ) { this->value.data.lngptr[row] += ( theParams[0]->value.data.logptr[elem] ? 1 : 0 ); this->value.undef[row] = 0; } } } } else if( theParams[0]->type==LONG ) { while( row-- ) { this->value.data.lngptr[row] = 0; /* Default is UNDEF until a defined value is found */ this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( ! theParams[0]->value.undef[elem] ) { this->value.data.lngptr[row] += theParams[0]->value.data.lngptr[elem]; this->value.undef[row] = 0; } } } } else if( theParams[0]->type==DOUBLE ){ while( row-- ) { this->value.data.dblptr[row] = 0.0; /* Default is UNDEF until a defined value is found */ this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( ! theParams[0]->value.undef[elem] ) { this->value.data.dblptr[row] += theParams[0]->value.data.dblptr[elem]; this->value.undef[row] = 0; } } } } else { /* BITSTR */ nelem = theParams[0]->value.nelem; while( row-- ) { char *sptr1 = theParams[0]->value.data.strptr[row]; this->value.data.lngptr[row] = 0; this->value.undef[row] = 0; while (*sptr1) { if (*sptr1 == '1') this->value.data.lngptr[row] ++; sptr1++; } } } break; case average_fct: elem = row * theParams[0]->value.nelem; if( theParams[0]->type==LONG ) { while( row-- ) { int count = 0; this->value.data.dblptr[row] = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { this->value.data.dblptr[row] += theParams[0]->value.data.lngptr[elem]; count ++; } } if (count == 0) { this->value.undef[row] = 1; } else { this->value.undef[row] = 0; this->value.data.dblptr[row] /= count; } } } else if( theParams[0]->type==DOUBLE ){ while( row-- ) { int count = 0; this->value.data.dblptr[row] = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { this->value.data.dblptr[row] += theParams[0]->value.data.dblptr[elem]; count ++; } } if (count == 0) { this->value.undef[row] = 1; } else { this->value.undef[row] = 0; this->value.data.dblptr[row] /= count; } } } break; case stddev_fct: elem = row * theParams[0]->value.nelem; if( theParams[0]->type==LONG ) { /* Compute the mean value */ while( row-- ) { int count = 0; double sum = 0, sum2 = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { sum += theParams[0]->value.data.lngptr[elem]; count ++; } } if (count > 1) { sum /= count; /* Compute the sum of squared deviations */ nelem = theParams[0]->value.nelem; elem += nelem; /* Reset elem for second pass */ while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { double dx = (theParams[0]->value.data.lngptr[elem] - sum); sum2 += (dx*dx); } } sum2 /= (double)count-1; this->value.undef[row] = 0; this->value.data.dblptr[row] = sqrt(sum2); } else { this->value.undef[row] = 0; /* STDDEV => 0 */ this->value.data.dblptr[row] = 0; } } } else if( theParams[0]->type==DOUBLE ){ /* Compute the mean value */ while( row-- ) { int count = 0; double sum = 0, sum2 = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { sum += theParams[0]->value.data.dblptr[elem]; count ++; } } if (count > 1) { sum /= count; /* Compute the sum of squared deviations */ nelem = theParams[0]->value.nelem; elem += nelem; /* Reset elem for second pass */ while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { double dx = (theParams[0]->value.data.dblptr[elem] - sum); sum2 += (dx*dx); } } sum2 /= (double)count-1; this->value.undef[row] = 0; this->value.data.dblptr[row] = sqrt(sum2); } else { this->value.undef[row] = 0; /* STDDEV => 0 */ this->value.data.dblptr[row] = 0; } } } break; case median_fct: elem = row * theParams[0]->value.nelem; nelem = theParams[0]->value.nelem; if( theParams[0]->type==LONG ) { long *dptr = theParams[0]->value.data.lngptr; char *uptr = theParams[0]->value.undef; long *mptr = (long *) malloc(sizeof(long)*nelem); int irow; /* Allocate temporary storage for this row, since the quickselect function will scramble the contents */ if (mptr == 0) { fferror("Could not allocate temporary memory in median function"); free( this->value.data.ptr ); break; } for (irow=0; irow 0) { this->value.undef[irow] = 0; this->value.data.lngptr[irow] = qselect_median_lng(mptr, nelem1); } else { this->value.undef[irow] = 1; this->value.data.lngptr[irow] = 0; } } free(mptr); } else { double *dptr = theParams[0]->value.data.dblptr; char *uptr = theParams[0]->value.undef; double *mptr = (double *) malloc(sizeof(double)*nelem); int irow; /* Allocate temporary storage for this row, since the quickselect function will scramble the contents */ if (mptr == 0) { fferror("Could not allocate temporary memory in median function"); free( this->value.data.ptr ); break; } for (irow=0; irow 0) { this->value.undef[irow] = 0; this->value.data.dblptr[irow] = qselect_median_dbl(mptr, nelem1); } else { this->value.undef[irow] = 1; this->value.data.dblptr[irow] = 0; } } free(mptr); } break; case abs_fct: if( theParams[0]->type==DOUBLE ) while( elem-- ) { dval = theParams[0]->value.data.dblptr[elem]; this->value.data.dblptr[elem] = (dval>0.0 ? dval : -dval); this->value.undef[elem] = theParams[0]->value.undef[elem]; } else while( elem-- ) { ival = theParams[0]->value.data.lngptr[elem]; this->value.data.lngptr[elem] = (ival> 0 ? ival : -ival); this->value.undef[elem] = theParams[0]->value.undef[elem]; } break; /* Special Null-Handling Functions */ case nonnull_fct: nelem = theParams[0]->value.nelem; if ( theParams[0]->type==STRING ) nelem = 1; elem = row * nelem; while( row-- ) { int nelem1 = nelem; this->value.undef[row] = 0; /* Initialize to 0 (defined) */ this->value.data.lngptr[row] = 0; while( nelem1-- ) { elem --; if ( theParams[0]->value.undef[elem] == 0 ) this->value.data.lngptr[row] ++; } } break; case isnull_fct: if( theParams[0]->type==STRING ) elem = row; while( elem-- ) { this->value.data.logptr[elem] = theParams[0]->value.undef[elem]; this->value.undef[elem] = 0; } break; case defnull_fct: switch( this->type ) { case BOOLEAN: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pNull[i] = theParams[i]->value.undef[elem]; pVals[i].data.log = theParams[i]->value.data.logptr[elem]; } else if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; pVals[i].data.log = theParams[i]->value.data.logptr[row]; } if( pNull[0] ) { this->value.undef[elem] = pNull[1]; this->value.data.logptr[elem] = pVals[1].data.log; } else { this->value.undef[elem] = 0; this->value.data.logptr[elem] = pVals[0].data.log; } } } break; case LONG: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pNull[i] = theParams[i]->value.undef[elem]; pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; } else if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; } if( pNull[0] ) { this->value.undef[elem] = pNull[1]; this->value.data.lngptr[elem] = pVals[1].data.lng; } else { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[0].data.lng; } } } break; case DOUBLE: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pNull[i] = theParams[i]->value.undef[elem]; pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; } else if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; } if( pNull[0] ) { this->value.undef[elem] = pNull[1]; this->value.data.dblptr[elem] = pVals[1].data.dbl; } else { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[0].data.dbl; } } } break; case STRING: while( row-- ) { i=2; while( i-- ) if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; strcpy(pVals[i].data.str, theParams[i]->value.data.strptr[row]); } if( pNull[0] ) { this->value.undef[row] = pNull[1]; strcpy(this->value.data.strptr[row],pVals[1].data.str); } else { this->value.undef[elem] = 0; strcpy(this->value.data.strptr[row],pVals[0].data.str); } } } break; /* Math functions with 1 double argument */ case sin_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = sin( theParams[0]->value.data.dblptr[elem] ); } break; case cos_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = cos( theParams[0]->value.data.dblptr[elem] ); } break; case tan_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = tan( theParams[0]->value.data.dblptr[elem] ); } break; case asin_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<-1.0 || dval>1.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = asin( dval ); } break; case acos_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<-1.0 || dval>1.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = acos( dval ); } break; case atan_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; this->value.data.dblptr[elem] = atan( dval ); } break; case sinh_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = sinh( theParams[0]->value.data.dblptr[elem] ); } break; case cosh_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = cosh( theParams[0]->value.data.dblptr[elem] ); } break; case tanh_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = tanh( theParams[0]->value.data.dblptr[elem] ); } break; case exp_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; this->value.data.dblptr[elem] = exp( dval ); } break; case log_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<=0.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = log( dval ); } break; case log10_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<=0.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = log10( dval ); } break; case sqrt_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<0.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = sqrt( dval ); } break; case ceil_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = ceil( theParams[0]->value.data.dblptr[elem] ); } break; case floor_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = floor( theParams[0]->value.data.dblptr[elem] ); } break; case round_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = floor( theParams[0]->value.data.dblptr[elem] + 0.5); } break; /* Two-argument Trig Functions */ case atan2_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1]) ) ) this->value.data.dblptr[elem] = atan2( pVals[0].data.dbl, pVals[1].data.dbl ); } } break; /* Four-argument ANGSEP Function */ case angsep_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=4; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3]) ) ) this->value.data.dblptr[elem] = angsep_calc(pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl); } } break; /* Min/Max functions taking 1 or 2 arguments */ case min1_fct: elem = row * theParams[0]->value.nelem; if( this->type==LONG ) { long minVal=0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; minVal = theParams[0]->value.data.lngptr[elem]; } else { minVal = minvalue( minVal, theParams[0]->value.data.lngptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.lngptr[row] = minVal; } } else if( this->type==DOUBLE ) { double minVal=0.0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; minVal = theParams[0]->value.data.dblptr[elem]; } else { minVal = minvalue( minVal, theParams[0]->value.data.dblptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.dblptr[row] = minVal; } } else if( this->type==BITSTR ) { char minVal; while( row-- ) { char *sptr1 = theParams[0]->value.data.strptr[row]; minVal = '1'; while (*sptr1) { if (*sptr1 == '0') minVal = '0'; sptr1++; } this->value.data.strptr[row][0] = minVal; this->value.data.strptr[row][1] = 0; /* Null terminate */ } } break; case min2_fct: if( this->type==LONG ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.lngptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[1].data.lng; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[0].data.lng; } else { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = minvalue( pVals[0].data.lng, pVals[1].data.lng ); } } } } else if( this->type==DOUBLE ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.dblptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[1].data.dbl; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[0].data.dbl; } else { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = minvalue( pVals[0].data.dbl, pVals[1].data.dbl ); } } } } break; case max1_fct: elem = row * theParams[0]->value.nelem; if( this->type==LONG ) { long maxVal=0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; maxVal = theParams[0]->value.data.lngptr[elem]; } else { maxVal = maxvalue( maxVal, theParams[0]->value.data.lngptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.lngptr[row] = maxVal; } } else if( this->type==DOUBLE ) { double maxVal=0.0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; maxVal = theParams[0]->value.data.dblptr[elem]; } else { maxVal = maxvalue( maxVal, theParams[0]->value.data.dblptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.dblptr[row] = maxVal; } } else if( this->type==BITSTR ) { char maxVal; while( row-- ) { char *sptr1 = theParams[0]->value.data.strptr[row]; maxVal = '0'; while (*sptr1) { if (*sptr1 == '1') maxVal = '1'; sptr1++; } this->value.data.strptr[row][0] = maxVal; this->value.data.strptr[row][1] = 0; /* Null terminate */ } } break; case max2_fct: if( this->type==LONG ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.lngptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[1].data.lng; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[0].data.lng; } else { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = maxvalue( pVals[0].data.lng, pVals[1].data.lng ); } } } } else if( this->type==DOUBLE ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.dblptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[1].data.dbl; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[0].data.dbl; } else { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = maxvalue( pVals[0].data.dbl, pVals[1].data.dbl ); } } } } break; /* Boolean SAO region Functions... scalar or vector dbls */ case near_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=3; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2]) ) ) this->value.data.logptr[elem] = bnear( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl ); } } break; case circle_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=5; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3] || pNull[4]) ) ) this->value.data.logptr[elem] = circle( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl ); } } break; case box_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=7; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3] || pNull[4] || pNull[5] || pNull[6] ) ) ) this->value.data.logptr[elem] = saobox( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); } } break; case elps_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=7; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3] || pNull[4] || pNull[5] || pNull[6] ) ) ) this->value.data.logptr[elem] = ellipse( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); } } break; /* C Conditional expression: bool ? expr : expr */ case ifthenelse_fct: switch( this->type ) { case BOOLEAN: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; if( vector[2]>1 ) { pVals[2].data.log = theParams[2]->value.data.logptr[elem]; pNull[2] = theParams[2]->value.undef[elem]; } else if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.log = theParams[i]->value.data.logptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.log = theParams[i]->value.data.logptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = pNull[2]) ) { if( pVals[2].data.log ) { this->value.data.logptr[elem] = pVals[0].data.log; this->value.undef[elem] = pNull[0]; } else { this->value.data.logptr[elem] = pVals[1].data.log; this->value.undef[elem] = pNull[1]; } } } } break; case LONG: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; if( vector[2]>1 ) { pVals[2].data.log = theParams[2]->value.data.logptr[elem]; pNull[2] = theParams[2]->value.undef[elem]; } else if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = pNull[2]) ) { if( pVals[2].data.log ) { this->value.data.lngptr[elem] = pVals[0].data.lng; this->value.undef[elem] = pNull[0]; } else { this->value.data.lngptr[elem] = pVals[1].data.lng; this->value.undef[elem] = pNull[1]; } } } } break; case DOUBLE: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; if( vector[2]>1 ) { pVals[2].data.log = theParams[2]->value.data.logptr[elem]; pNull[2] = theParams[2]->value.undef[elem]; } else if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = pNull[2]) ) { if( pVals[2].data.log ) { this->value.data.dblptr[elem] = pVals[0].data.dbl; this->value.undef[elem] = pNull[0]; } else { this->value.data.dblptr[elem] = pVals[1].data.dbl; this->value.undef[elem] = pNull[1]; } } } } break; case STRING: while( row-- ) { if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i] ) { strcpy( pVals[i].data.str, theParams[i]->value.data.strptr[row] ); pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[row] = pNull[2]) ) { if( pVals[2].data.log ) { strcpy( this->value.data.strptr[row], pVals[0].data.str ); this->value.undef[row] = pNull[0]; } else { strcpy( this->value.data.strptr[row], pVals[1].data.str ); this->value.undef[row] = pNull[1]; } } else { this->value.data.strptr[row][0] = '\0'; } } break; } break; } } } i = this->nSubNodes; while( i-- ) { if( theParams[i]->operation>0 ) { /* Currently only numeric params allowed */ free( theParams[i]->value.data.ptr ); } } } static void Do_Deref( Node *this ) { Node *theVar, *theDims[MAXDIMS]; int isConst[MAXDIMS], allConst; long dimVals[MAXDIMS]; int i, nDims; long row, elem, dsize; theVar = gParse.Nodes + this->SubNodes[0]; i = nDims = this->nSubNodes-1; allConst = 1; while( i-- ) { theDims[i] = gParse.Nodes + this->SubNodes[i+1]; isConst[i] = ( theDims[i]->operation==CONST_OP ); if( isConst[i] ) dimVals[i] = theDims[i]->value.data.lng; else allConst = 0; } if( this->type==DOUBLE ) { dsize = sizeof( double ); } else if( this->type==LONG ) { dsize = sizeof( long ); } else if( this->type==BOOLEAN ) { dsize = sizeof( char ); } else dsize = 0; Allocate_Ptrs( this ); if( !gParse.status ) { if( allConst && theVar->value.naxis==nDims ) { /* Dereference completely using constant indices */ elem = 0; i = nDims; while( i-- ) { if( dimVals[i]<1 || dimVals[i]>theVar->value.naxes[i] ) break; elem = theVar->value.naxes[i]*elem + dimVals[i]-1; } if( i<0 ) { for( row=0; rowtype==STRING ) this->value.undef[row] = theVar->value.undef[row]; else if( this->type==BITSTR ) this->value.undef; /* Dummy - BITSTRs do not have undefs */ else this->value.undef[row] = theVar->value.undef[elem]; if( this->type==DOUBLE ) this->value.data.dblptr[row] = theVar->value.data.dblptr[elem]; else if( this->type==LONG ) this->value.data.lngptr[row] = theVar->value.data.lngptr[elem]; else if( this->type==BOOLEAN ) this->value.data.logptr[row] = theVar->value.data.logptr[elem]; else { /* XXX Note, the below expression uses knowledge of the layout of the string format, namely (nelem+1) characters per string, followed by (nelem+1) "undef" values. */ this->value.data.strptr[row][0] = theVar->value.data.strptr[0][elem+row]; this->value.data.strptr[row][1] = 0; /* Null terminate */ } elem += theVar->value.nelem; } } else { fferror("Index out of range"); free( this->value.data.ptr ); } } else if( allConst && nDims==1 ) { /* Reduce dimensions by 1, using a constant index */ if( dimVals[0] < 1 || dimVals[0] > theVar->value.naxes[ theVar->value.naxis-1 ] ) { fferror("Index out of range"); free( this->value.data.ptr ); } else if ( this->type == BITSTR || this->type == STRING ) { elem = this->value.nelem * (dimVals[0]-1); for( row=0; rowvalue.undef) this->value.undef[row] = theVar->value.undef[row]; memcpy( (char*)this->value.data.strptr[0] + row*sizeof(char)*(this->value.nelem+1), (char*)theVar->value.data.strptr[0] + elem*sizeof(char), this->value.nelem * sizeof(char) ); /* Null terminate */ this->value.data.strptr[row][this->value.nelem] = 0; elem += theVar->value.nelem+1; } } else { elem = this->value.nelem * (dimVals[0]-1); for( row=0; rowvalue.undef + row*this->value.nelem, theVar->value.undef + elem, this->value.nelem * sizeof(char) ); memcpy( (char*)this->value.data.ptr + row*dsize*this->value.nelem, (char*)theVar->value.data.ptr + elem*dsize, this->value.nelem * dsize ); elem += theVar->value.nelem; } } } else if( theVar->value.naxis==nDims ) { /* Dereference completely using an expression for the indices */ for( row=0; rowvalue.undef[row] ) { fferror("Null encountered as vector index"); free( this->value.data.ptr ); break; } else dimVals[i] = theDims[i]->value.data.lngptr[row]; } } if( gParse.status ) break; elem = 0; i = nDims; while( i-- ) { if( dimVals[i]<1 || dimVals[i]>theVar->value.naxes[i] ) break; elem = theVar->value.naxes[i]*elem + dimVals[i]-1; } if( i<0 ) { elem += row*theVar->value.nelem; if( this->type==STRING ) this->value.undef[row] = theVar->value.undef[row]; else if( this->type==BITSTR ) this->value.undef; /* Dummy - BITSTRs do not have undefs */ else this->value.undef[row] = theVar->value.undef[elem]; if( this->type==DOUBLE ) this->value.data.dblptr[row] = theVar->value.data.dblptr[elem]; else if( this->type==LONG ) this->value.data.lngptr[row] = theVar->value.data.lngptr[elem]; else if( this->type==BOOLEAN ) this->value.data.logptr[row] = theVar->value.data.logptr[elem]; else { /* XXX Note, the below expression uses knowledge of the layout of the string format, namely (nelem+1) characters per string, followed by (nelem+1) "undef" values. */ this->value.data.strptr[row][0] = theVar->value.data.strptr[0][elem+row]; this->value.data.strptr[row][1] = 0; /* Null terminate */ } } else { fferror("Index out of range"); free( this->value.data.ptr ); } } } else { /* Reduce dimensions by 1, using a nonconstant expression */ for( row=0; rowvalue.undef[row] ) { fferror("Null encountered as vector index"); free( this->value.data.ptr ); break; } else dimVals[0] = theDims[0]->value.data.lngptr[row]; if( dimVals[0] < 1 || dimVals[0] > theVar->value.naxes[ theVar->value.naxis-1 ] ) { fferror("Index out of range"); free( this->value.data.ptr ); } else if ( this->type == BITSTR || this->type == STRING ) { elem = this->value.nelem * (dimVals[0]-1); elem += row*(theVar->value.nelem+1); if (this->value.undef) this->value.undef[row] = theVar->value.undef[row]; memcpy( (char*)this->value.data.strptr[0] + row*sizeof(char)*(this->value.nelem+1), (char*)theVar->value.data.strptr[0] + elem*sizeof(char), this->value.nelem * sizeof(char) ); /* Null terminate */ this->value.data.strptr[row][this->value.nelem] = 0; } else { elem = this->value.nelem * (dimVals[0]-1); elem += row*theVar->value.nelem; memcpy( this->value.undef + row*this->value.nelem, theVar->value.undef + elem, this->value.nelem * sizeof(char) ); memcpy( (char*)this->value.data.ptr + row*dsize*this->value.nelem, (char*)theVar->value.data.ptr + elem*dsize, this->value.nelem * dsize ); } } } } if( theVar->operation>0 ) { if (theVar->type == STRING || theVar->type == BITSTR) free(theVar->value.data.strptr[0] ); else free( theVar->value.data.ptr ); } for( i=0; ioperation>0 ) { free( theDims[i]->value.data.ptr ); } } static void Do_GTI( Node *this ) { Node *theExpr, *theTimes; double *start, *stop, *times; long elem, nGTI, gti; int ordered; theTimes = gParse.Nodes + this->SubNodes[0]; theExpr = gParse.Nodes + this->SubNodes[1]; nGTI = theTimes->value.nelem; start = theTimes->value.data.dblptr; stop = theTimes->value.data.dblptr + nGTI; ordered = theTimes->type; if( theExpr->operation==CONST_OP ) { this->value.data.log = (Search_GTI( theExpr->value.data.dbl, nGTI, start, stop, ordered )>=0); this->operation = CONST_OP; } else { Allocate_Ptrs( this ); times = theExpr->value.data.dblptr; if( !gParse.status ) { elem = gParse.nRows * this->value.nelem; if( nGTI ) { gti = -1; while( elem-- ) { if( (this->value.undef[elem] = theExpr->value.undef[elem]) ) continue; /* Before searching entire GTI, check the GTI found last time */ if( gti<0 || times[elem]stop[gti] ) { gti = Search_GTI( times[elem], nGTI, start, stop, ordered ); } this->value.data.logptr[elem] = ( gti>=0 ); } } else while( elem-- ) { this->value.data.logptr[elem] = 0; this->value.undef[elem] = 0; } } } if( theExpr->operation>0 ) free( theExpr->value.data.ptr ); } static long Search_GTI( double evtTime, long nGTI, double *start, double *stop, int ordered ) { long gti, step; if( ordered && nGTI>15 ) { /* If time-ordered and lots of GTIs, */ /* use "FAST" Binary search algorithm */ if( evtTime>=start[0] && evtTime<=stop[nGTI-1] ) { gti = step = (nGTI >> 1); while(1) { if( step>1L ) step >>= 1; if( evtTime>stop[gti] ) { if( evtTime>=start[gti+1] ) gti += step; else { gti = -1L; break; } } else if( evtTime=start[gti] && evtTime<=stop[gti] ) break; } return( gti ); } static void Do_REG( Node *this ) { Node *theRegion, *theX, *theY; double Xval=0.0, Yval=0.0; char Xnull=0, Ynull=0; int Xvector, Yvector; long nelem, elem, rows; theRegion = gParse.Nodes + this->SubNodes[0]; theX = gParse.Nodes + this->SubNodes[1]; theY = gParse.Nodes + this->SubNodes[2]; Xvector = ( theX->operation!=CONST_OP ); if( Xvector ) Xvector = theX->value.nelem; else { Xval = theX->value.data.dbl; } Yvector = ( theY->operation!=CONST_OP ); if( Yvector ) Yvector = theY->value.nelem; else { Yval = theY->value.data.dbl; } if( !Xvector && !Yvector ) { this->value.data.log = ( fits_in_region( Xval, Yval, (SAORegion *)theRegion->value.data.ptr ) != 0 ); this->operation = CONST_OP; } else { Allocate_Ptrs( this ); if( !gParse.status ) { rows = gParse.nRows; nelem = this->value.nelem; elem = rows*nelem; while( rows-- ) { while( nelem-- ) { elem--; if( Xvector>1 ) { Xval = theX->value.data.dblptr[elem]; Xnull = theX->value.undef[elem]; } else if( Xvector ) { Xval = theX->value.data.dblptr[rows]; Xnull = theX->value.undef[rows]; } if( Yvector>1 ) { Yval = theY->value.data.dblptr[elem]; Ynull = theY->value.undef[elem]; } else if( Yvector ) { Yval = theY->value.data.dblptr[rows]; Ynull = theY->value.undef[rows]; } this->value.undef[elem] = ( Xnull || Ynull ); if( this->value.undef[elem] ) continue; this->value.data.logptr[elem] = ( fits_in_region( Xval, Yval, (SAORegion *)theRegion->value.data.ptr ) != 0 ); } nelem = this->value.nelem; } } } if( theX->operation>0 ) free( theX->value.data.ptr ); if( theY->operation>0 ) free( theY->value.data.ptr ); } static void Do_Vector( Node *this ) { Node *that; long row, elem, idx, jdx, offset=0; int node; Allocate_Ptrs( this ); if( !gParse.status ) { for( node=0; nodenSubNodes; node++ ) { that = gParse.Nodes + this->SubNodes[node]; if( that->operation == CONST_OP ) { idx = gParse.nRows*this->value.nelem + offset; while( (idx-=this->value.nelem)>=0 ) { this->value.undef[idx] = 0; switch( this->type ) { case BOOLEAN: this->value.data.logptr[idx] = that->value.data.log; break; case LONG: this->value.data.lngptr[idx] = that->value.data.lng; break; case DOUBLE: this->value.data.dblptr[idx] = that->value.data.dbl; break; } } } else { row = gParse.nRows; idx = row * that->value.nelem; while( row-- ) { elem = that->value.nelem; jdx = row*this->value.nelem + offset; while( elem-- ) { this->value.undef[jdx+elem] = that->value.undef[--idx]; switch( this->type ) { case BOOLEAN: this->value.data.logptr[jdx+elem] = that->value.data.logptr[idx]; break; case LONG: this->value.data.lngptr[jdx+elem] = that->value.data.lngptr[idx]; break; case DOUBLE: this->value.data.dblptr[jdx+elem] = that->value.data.dblptr[idx]; break; } } } } offset += that->value.nelem; } } for( node=0; node < this->nSubNodes; node++ ) if( gParse.Nodes[this->SubNodes[node]].operation>0 ) free( gParse.Nodes[this->SubNodes[node]].value.data.ptr ); } /*****************************************************************************/ /* Utility routines which perform the calculations on bits and SAO regions */ /*****************************************************************************/ static char bitlgte(char *bits1, int oper, char *bits2) { int val1, val2, nextbit; char result; int i, l1, l2, length, ldiff; char stream[256]; char chr1, chr2; l1 = strlen(bits1); l2 = strlen(bits2); if (l1 < l2) { length = l2; ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bits1++); stream[i] = '\0'; bits1 = stream; } else if (l2 < l1) { length = l1; ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bits2++); stream[i] = '\0'; bits2 = stream; } else length = l1; val1 = val2 = 0; nextbit = 1; while( length-- ) { chr1 = bits1[length]; chr2 = bits2[length]; if ((chr1 != 'x')&&(chr1 != 'X')&&(chr2 != 'x')&&(chr2 != 'X')) { if (chr1 == '1') val1 += nextbit; if (chr2 == '1') val2 += nextbit; nextbit *= 2; } } result = 0; switch (oper) { case LT: if (val1 < val2) result = 1; break; case LTE: if (val1 <= val2) result = 1; break; case GT: if (val1 > val2) result = 1; break; case GTE: if (val1 >= val2) result = 1; break; } return (result); } static void bitand(char *result,char *bitstrm1,char *bitstrm2) { int i, l1, l2, ldiff; char stream[256]; char chr1, chr2; l1 = strlen(bitstrm1); l2 = strlen(bitstrm2); if (l1 < l2) { ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bitstrm1++); stream[i] = '\0'; bitstrm1 = stream; } else if (l2 < l1) { ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bitstrm2++); stream[i] = '\0'; bitstrm2 = stream; } while ( (chr1 = *(bitstrm1++)) ) { chr2 = *(bitstrm2++); if ((chr1 == 'x') || (chr2 == 'x')) *result = 'x'; else if ((chr1 == '1') && (chr2 == '1')) *result = '1'; else *result = '0'; result++; } *result = '\0'; } static void bitor(char *result,char *bitstrm1,char *bitstrm2) { int i, l1, l2, ldiff; char stream[256]; char chr1, chr2; l1 = strlen(bitstrm1); l2 = strlen(bitstrm2); if (l1 < l2) { ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bitstrm1++); stream[i] = '\0'; bitstrm1 = stream; } else if (l2 < l1) { ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bitstrm2++); stream[i] = '\0'; bitstrm2 = stream; } while ( (chr1 = *(bitstrm1++)) ) { chr2 = *(bitstrm2++); if ((chr1 == '1') || (chr2 == '1')) *result = '1'; else if ((chr1 == '0') || (chr2 == '0')) *result = '0'; else *result = 'x'; result++; } *result = '\0'; } static void bitnot(char *result,char *bits) { int length; char chr; length = strlen(bits); while( length-- ) { chr = *(bits++); *(result++) = ( chr=='1' ? '0' : ( chr=='0' ? '1' : chr ) ); } *result = '\0'; } static char bitcmp(char *bitstrm1, char *bitstrm2) { int i, l1, l2, ldiff; char stream[256]; char chr1, chr2; l1 = strlen(bitstrm1); l2 = strlen(bitstrm2); if (l1 < l2) { ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bitstrm1++); stream[i] = '\0'; bitstrm1 = stream; } else if (l2 < l1) { ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bitstrm2++); stream[i] = '\0'; bitstrm2 = stream; } while( (chr1 = *(bitstrm1++)) ) { chr2 = *(bitstrm2++); if ( ((chr1 == '0') && (chr2 == '1')) || ((chr1 == '1') && (chr2 == '0')) ) return( 0 ); } return( 1 ); } static char bnear(double x, double y, double tolerance) { if (fabs(x - y) < tolerance) return ( 1 ); else return ( 0 ); } static char saobox(double xcen, double ycen, double xwid, double ywid, double rot, double xcol, double ycol) { double x,y,xprime,yprime,xmin,xmax,ymin,ymax,theta; theta = (rot / 180.0) * myPI; xprime = xcol - xcen; yprime = ycol - ycen; x = xprime * cos(theta) + yprime * sin(theta); y = -xprime * sin(theta) + yprime * cos(theta); xmin = - 0.5 * xwid; xmax = 0.5 * xwid; ymin = - 0.5 * ywid; ymax = 0.5 * ywid; if ((x >= xmin) && (x <= xmax) && (y >= ymin) && (y <= ymax)) return ( 1 ); else return ( 0 ); } static char circle(double xcen, double ycen, double rad, double xcol, double ycol) { double r2,dx,dy,dlen; dx = xcol - xcen; dy = ycol - ycen; dx *= dx; dy *= dy; dlen = dx + dy; r2 = rad * rad; if (dlen <= r2) return ( 1 ); else return ( 0 ); } static char ellipse(double xcen, double ycen, double xrad, double yrad, double rot, double xcol, double ycol) { double x,y,xprime,yprime,dx,dy,dlen,theta; theta = (rot / 180.0) * myPI; xprime = xcol - xcen; yprime = ycol - ycen; x = xprime * cos(theta) + yprime * sin(theta); y = -xprime * sin(theta) + yprime * cos(theta); dx = x / xrad; dy = y / yrad; dx *= dx; dy *= dy; dlen = dx + dy; if (dlen <= 1.0) return ( 1 ); else return ( 0 ); } static void fferror(char *s) { char msg[80]; if( !gParse.status ) gParse.status = PARSE_SYNTAX_ERR; strncpy(msg, s, 80); msg[79] = '\0'; ffpmsg(msg); } indi-0.5/src/cfitsio/drvrsmem.c0000644000175000017500000011306610610474374014360 0ustar jrjr/* S H A R E D M E M O R Y D R I V E R ======================================= by Jerzy.Borkowski@obs.unige.ch 09-Mar-98 : initial version 1.0 released 23-Mar-98 : shared_malloc now accepts new handle as an argument 23-Mar-98 : shmem://0, shmem://1, etc changed to shmem://h0, etc due to bug in url parser. 10-Apr-98 : code cleanup 13-May-99 : delayed initialization added, global table deleted on exit when no shmem segments remain, and last process terminates */ #ifdef HAVE_SHMEM_SERVICES #include "fitsio2.h" /* drvrsmem.h is included by it */ #include #include #include #include #include #include #include #if defined(unix) || defined(__unix__) || defined(__unix) #include #endif static int shared_kbase = 0; /* base for shared memory handles */ static int shared_maxseg = 0; /* max number of shared memory blocks */ static int shared_range = 0; /* max number of tried entries */ static int shared_fd = SHARED_INVALID; /* handle of global access lock file */ static int shared_gt_h = SHARED_INVALID; /* handle of global table segment */ static SHARED_LTAB *shared_lt = NULL; /* local table pointer */ static SHARED_GTAB *shared_gt = NULL; /* global table pointer */ static int shared_create_mode = 0666; /* permission flags for created objects */ static int shared_debug = 1; /* simple debugging tool, set to 0 to disable messages */ static int shared_init_called = 0; /* flag whether shared_init() has been called, used for delayed init */ /* static support routines prototypes */ static int shared_clear_entry(int idx); /* unconditionally clear entry */ static int shared_destroy_entry(int idx); /* unconditionally destroy sema & shseg and clear entry */ static int shared_mux(int idx, int mode); /* obtain exclusive access to specified segment */ static int shared_demux(int idx, int mode); /* free exclusive access to specified segment */ static int shared_process_count(int sem); /* valid only for time of invocation */ static int shared_delta_process(int sem, int delta); /* change number of processes hanging on segment */ static int shared_attach_process(int sem); static int shared_detach_process(int sem); static int shared_get_free_entry(int newhandle); /* get free entry in shared_key, or -1, entry is set rw locked */ static int shared_get_hash(long size, int idx);/* return hash value for malloc */ static long shared_adjust_size(long size); /* size must be >= 0 !!! */ static int shared_check_locked_index(int idx); /* verify that given idx is valid */ static int shared_map(int idx); /* map all tables for given idx, check for validity */ static int shared_validate(int idx, int mode); /* use intrnally inside crit.sect !!! */ /* support routines - initialization */ static int shared_clear_entry(int idx) /* unconditionally clear entry */ { if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); shared_gt[idx].key = SHARED_INVALID; /* clear entries in global table */ shared_gt[idx].handle = SHARED_INVALID; shared_gt[idx].sem = SHARED_INVALID; shared_gt[idx].semkey = SHARED_INVALID; shared_gt[idx].nprocdebug = 0; shared_gt[idx].size = 0; shared_gt[idx].attr = 0; return(SHARED_OK); } static int shared_destroy_entry(int idx) /* unconditionally destroy sema & shseg and clear entry */ { int r, r2; union semun filler; if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); r2 = r = SHARED_OK; filler.val = 0; /* this is to make cc happy (warning otherwise) */ if (SHARED_INVALID != shared_gt[idx].sem) r = semctl(shared_gt[idx].sem, 0, IPC_RMID, filler); /* destroy semaphore */ if (SHARED_INVALID != shared_gt[idx].handle) r2 = shmctl(shared_gt[idx].handle, IPC_RMID, 0); /* destroy shared memory segment */ if (SHARED_OK == r) r = r2; /* accumulate error code in r, free r2 */ r2 = shared_clear_entry(idx); return((SHARED_OK == r) ? r2 : r); } void shared_cleanup(void) /* this must (should) be called during exit/abort */ { int i, j, r, oktodelete, filelocked, segmentspresent; flock_t flk; struct shmid_ds ds; if (shared_debug) printf("shared_cleanup:"); if (NULL != shared_lt) { if (shared_debug) printf(" deleting segments:"); for (i=0; i>\n"); return; } int shared_init(int debug_msgs) /* initialize shared memory stuff, you have to call this routine once */ { int i; char buf[1000], *p; mode_t oldumask; shared_init_called = 1; /* tell everybody no need to call us for the 2nd time */ shared_debug = debug_msgs; /* set required debug mode */ if (shared_debug) printf("shared_init:"); shared_kbase = 0; /* adapt to current env. settings */ if (NULL != (p = getenv(SHARED_ENV_KEYBASE))) shared_kbase = atoi(p); if (0 == shared_kbase) shared_kbase = SHARED_KEYBASE; if (shared_debug) printf(" keybase=%d", shared_kbase); shared_maxseg = 0; if (NULL != (p = getenv(SHARED_ENV_MAXSEG))) shared_maxseg = atoi(p); if (0 == shared_maxseg) shared_maxseg = SHARED_MAXSEG; if (shared_debug) printf(" maxseg=%d", shared_maxseg); shared_range = 3 * shared_maxseg; if (SHARED_INVALID == shared_fd) /* create rw locking file (this file is never deleted) */ { if (shared_debug) printf(" lockfileinit="); sprintf(buf, "%s.%d.%d", SHARED_FDNAME, shared_kbase, shared_maxseg); oldumask = umask(0); shared_fd = open(buf, O_TRUNC | O_EXCL | O_CREAT | O_RDWR, shared_create_mode); umask(oldumask); if (SHARED_INVALID == shared_fd) /* or just open rw locking file, in case it already exists */ { shared_fd = open(buf, O_TRUNC | O_RDWR, shared_create_mode); if (SHARED_INVALID == shared_fd) return(SHARED_NOFILE); if (shared_debug) printf("slave"); } else { if (shared_debug) printf("master"); } } if (SHARED_INVALID == shared_gt_h) /* global table not attached, try to create it in shared memory */ { if (shared_debug) printf(" globalsharedtableinit="); shared_gt_h = shmget(shared_kbase, shared_maxseg * sizeof(SHARED_GTAB), IPC_CREAT | IPC_EXCL | shared_create_mode); /* try open as a master */ if (SHARED_INVALID == shared_gt_h) /* if failed, try to open as a slave */ { shared_gt_h = shmget(shared_kbase, shared_maxseg * sizeof(SHARED_GTAB), shared_create_mode); if (SHARED_INVALID == shared_gt_h) return(SHARED_IPCERR); /* means deleted ID residing in system, shared mem unusable ... */ shared_gt = (SHARED_GTAB *)shmat(shared_gt_h, 0, 0); /* attach segment */ if (((SHARED_GTAB *)SHARED_INVALID) == shared_gt) return(SHARED_IPCERR); if (shared_debug) printf("slave"); } else { shared_gt = (SHARED_GTAB *)shmat(shared_gt_h, 0, 0); /* attach segment */ if (((SHARED_GTAB *)SHARED_INVALID) == shared_gt) return(SHARED_IPCERR); for (i=0; i>\n"); return(SHARED_OK); } int shared_recover(int id) /* try to recover dormant segments after applic crash */ { int i, r, r2; if (NULL == shared_gt) return(SHARED_NOTINIT); /* not initialized */ if (NULL == shared_lt) return(SHARED_NOTINIT); /* not initialized */ r = SHARED_OK; for (i=0; i r2) || (0 == r2)) { if (shared_debug) printf("Bogus handle=%d nproc=%d sema=%d:", i, shared_gt[i].nprocdebug, r2); r = shared_destroy_entry(i); if (shared_debug) { printf("%s", r ? "error couldn't clear handle" : "handle cleared"); } } shared_demux(i, SHARED_RDWRITE); } return(r); /* table full */ } /* API routines - mutexes and locking */ static int shared_mux(int idx, int mode) /* obtain exclusive access to specified segment */ { flock_t flk; int r; if (0 == shared_init_called) /* delayed initialization */ { if (SHARED_OK != (r = shared_init(0))) return(r); } if (SHARED_INVALID == shared_fd) return(SHARED_NOTINIT); if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); flk.l_type = ((mode & SHARED_RDWRITE) ? F_WRLCK : F_RDLCK); flk.l_whence = 0; flk.l_start = idx; flk.l_len = 1; if (shared_debug) printf(" [mux (%d): ", idx); if (-1 == fcntl(shared_fd, ((mode & SHARED_NOWAIT) ? F_SETLK : F_SETLKW), &flk)) { switch (errno) { case EAGAIN: ; case EACCES: if (shared_debug) printf("again]"); return(SHARED_AGAIN); default: if (shared_debug) printf("err]"); return(SHARED_IPCERR); } } if (shared_debug) printf("ok]"); return(SHARED_OK); } static int shared_demux(int idx, int mode) /* free exclusive access to specified segment */ { flock_t flk; if (SHARED_INVALID == shared_fd) return(SHARED_NOTINIT); if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); flk.l_type = F_UNLCK; flk.l_whence = 0; flk.l_start = idx; flk.l_len = 1; if (shared_debug) printf(" [demux (%d): ", idx); if (-1 == fcntl(shared_fd, F_SETLKW, &flk)) { switch (errno) { case EAGAIN: ; case EACCES: if (shared_debug) printf("again]"); return(SHARED_AGAIN); default: if (shared_debug) printf("err]"); return(SHARED_IPCERR); } } if (shared_debug) printf("mode=%d ok]", mode); return(SHARED_OK); } static int shared_process_count(int sem) /* valid only for time of invocation */ { union semun su; su.val = 0; /* to force compiler not to give warning messages */ return(semctl(sem, 0, GETVAL, su)); /* su is unused here */ } static int shared_delta_process(int sem, int delta) /* change number of processes hanging on segment */ { struct sembuf sb; if (SHARED_INVALID == sem) return(SHARED_BADARG); /* semaphore not attached */ sb.sem_num = 0; sb.sem_op = delta; sb.sem_flg = SEM_UNDO; return((-1 == semop(sem, &sb, 1)) ? SHARED_IPCERR : SHARED_OK); } static int shared_attach_process(int sem) { if (shared_debug) printf(" [attach process]"); return(shared_delta_process(sem, 1)); } static int shared_detach_process(int sem) { if (shared_debug) printf(" [detach process]"); return(shared_delta_process(sem, -1)); } /* API routines - hashing and searching */ static int shared_get_free_entry(int newhandle) /* get newhandle, or -1, entry is set rw locked */ { if (NULL == shared_gt) return(-1); /* not initialized */ if (NULL == shared_lt) return(-1); /* not initialized */ if (newhandle < 0) return(-1); if (newhandle >= shared_maxseg) return(-1); if (shared_lt[newhandle].tcnt) return(-1); /* somebody (we) is using it */ if (shared_mux(newhandle, SHARED_NOWAIT | SHARED_RDWRITE)) return(-1); /* used by others */ if (SHARED_INVALID == shared_gt[newhandle].key) return(newhandle); /* we have found free slot, lock it and return index */ shared_demux(newhandle, SHARED_RDWRITE); if (shared_debug) printf("[free_entry - ERROR - entry unusable]"); return(-1); /* table full */ } static int shared_get_hash(long size, int idx) /* return hash value for malloc */ { static int counter = 0; int hash; hash = (counter + size * idx) % shared_range; counter = (counter + 1) % shared_range; return(hash); } static long shared_adjust_size(long size) /* size must be >= 0 !!! */ { return(((size + sizeof(BLKHEAD) + SHARED_GRANUL - 1) / SHARED_GRANUL) * SHARED_GRANUL); } /* API routines - core : malloc/realloc/free/attach/detach/lock/unlock */ int shared_malloc(long size, int mode, int newhandle) /* return idx or SHARED_INVALID */ { int h, i, r, idx, key; union semun filler; BLKHEAD *bp; if (0 == shared_init_called) /* delayed initialization */ { if (SHARED_OK != (r = shared_init(0))) return(r); } if (shared_debug) printf("malloc (size = %ld, mode = %d):", size, mode); if (size < 0) return(SHARED_INVALID); if (-1 == (idx = shared_get_free_entry(newhandle))) return(SHARED_INVALID); if (shared_debug) printf(" idx=%d", idx); for (i = 0; ; i++) { if (i >= shared_range) /* table full, signal error & exit */ { shared_demux(idx, SHARED_RDWRITE); return(SHARED_INVALID); } key = shared_kbase + ((i + shared_get_hash(size, idx)) % shared_range); if (shared_debug) printf(" key=%d", key); h = shmget(key, shared_adjust_size(size), IPC_CREAT | IPC_EXCL | shared_create_mode); if (shared_debug) printf(" handle=%d", h); if (SHARED_INVALID == h) continue; /* segment already accupied */ bp = (BLKHEAD *)shmat(h, 0, 0); /* try attach */ if (shared_debug) printf(" p=%p", bp); if (((BLKHEAD *)SHARED_INVALID) == bp) /* cannot attach, delete segment, try with another key */ { shmctl(h, IPC_RMID, 0); continue; } /* now create semaphor counting number of processes attached */ if (SHARED_INVALID == (shared_gt[idx].sem = semget(key, 1, IPC_CREAT | IPC_EXCL | shared_create_mode))) { shmdt((void *)bp); /* cannot create segment, delete everything */ shmctl(h, IPC_RMID, 0); continue; /* try with another key */ } if (shared_debug) printf(" sem=%d", shared_gt[idx].sem); if (shared_attach_process(shared_gt[idx].sem)) /* try attach process */ { semctl(shared_gt[idx].sem, 0, IPC_RMID, filler); /* destroy semaphore */ shmdt((char *)bp); /* detach shared mem segment */ shmctl(h, IPC_RMID, 0); /* destroy shared mem segment */ continue; /* try with another key */ } bp->s.tflag = BLOCK_SHARED; /* fill in data in segment's header (this is really not necessary) */ bp->s.ID[0] = SHARED_ID_0; bp->s.ID[1] = SHARED_ID_1; bp->s.handle = idx; /* used in yorick */ if (mode & SHARED_RESIZE) { if (shmdt((char *)bp)) r = SHARED_IPCERR; /* if segment is resizable, then detach segment */ shared_lt[idx].p = NULL; } else { shared_lt[idx].p = bp; } shared_lt[idx].tcnt = 1; /* one thread using segment */ shared_lt[idx].lkcnt = 0; /* no locks at the moment */ shared_lt[idx].seekpos = 0L; /* r/w pointer positioned at beg of block */ shared_gt[idx].handle = h; /* fill in data in global table */ shared_gt[idx].size = size; shared_gt[idx].attr = mode; shared_gt[idx].semkey = key; shared_gt[idx].key = key; shared_gt[idx].nprocdebug = 0; break; } shared_demux(idx, SHARED_RDWRITE); /* hope this will not fail */ return(idx); } int shared_attach(int idx) { int r, r2; if (SHARED_OK != (r = shared_mux(idx, SHARED_RDWRITE | SHARED_WAIT))) return(r); if (SHARED_OK != (r = shared_map(idx))) { shared_demux(idx, SHARED_RDWRITE); return(r); } if (shared_attach_process(shared_gt[idx].sem)) /* try attach process */ { shmdt((char *)(shared_lt[idx].p)); /* cannot attach process, detach everything */ shared_lt[idx].p = NULL; shared_demux(idx, SHARED_RDWRITE); return(SHARED_BADARG); } shared_lt[idx].tcnt++; /* one more thread is using segment */ if (shared_gt[idx].attr & SHARED_RESIZE) /* if resizeable, detach and return special pointer */ { if (shmdt((char *)(shared_lt[idx].p))) r = SHARED_IPCERR; /* if segment is resizable, then detach segment */ shared_lt[idx].p = NULL; } shared_lt[idx].seekpos = 0L; /* r/w pointer positioned at beg of block */ r2 = shared_demux(idx, SHARED_RDWRITE); return(r ? r : r2); } static int shared_check_locked_index(int idx) /* verify that given idx is valid */ { int r; if (0 == shared_init_called) /* delayed initialization */ { if (SHARED_OK != (r = shared_init(0))) return(r); } if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); if (NULL == shared_lt[idx].p) return(SHARED_BADARG); /* NULL pointer, not attached ?? */ if (0 == shared_lt[idx].lkcnt) return(SHARED_BADARG); /* not locked ?? */ if ((SHARED_ID_0 != (shared_lt[idx].p)->s.ID[0]) || (SHARED_ID_1 != (shared_lt[idx].p)->s.ID[1]) || (BLOCK_SHARED != (shared_lt[idx].p)->s.tflag)) /* invalid data in segment */ return(SHARED_BADARG); return(SHARED_OK); } static int shared_map(int idx) /* map all tables for given idx, check for validity */ { int h; /* have to obtain excl. access before calling shared_map */ BLKHEAD *bp; if ((idx < 0) || (idx >= shared_maxseg)) return(SHARED_BADARG); if (SHARED_INVALID == shared_gt[idx].key) return(SHARED_BADARG); if (SHARED_INVALID == (h = shmget(shared_gt[idx].key, 1, shared_create_mode))) return(SHARED_BADARG); if (((BLKHEAD *)SHARED_INVALID) == (bp = (BLKHEAD *)shmat(h, 0, 0))) return(SHARED_BADARG); if ((SHARED_ID_0 != bp->s.ID[0]) || (SHARED_ID_1 != bp->s.ID[1]) || (BLOCK_SHARED != bp->s.tflag) || (h != shared_gt[idx].handle)) { shmdt((char *)bp); /* invalid segment, detach everything */ return(SHARED_BADARG); } if (shared_gt[idx].sem != semget(shared_gt[idx].semkey, 1, shared_create_mode)) /* check if sema is still there */ { shmdt((char *)bp); /* cannot attach semaphore, detach everything */ return(SHARED_BADARG); } shared_lt[idx].p = bp; /* store pointer to shmem data */ return(SHARED_OK); } static int shared_validate(int idx, int mode) /* use intrnally inside crit.sect !!! */ { int r; if (SHARED_OK != (r = shared_mux(idx, mode))) return(r); /* idx checked by shared_mux */ if (NULL == shared_lt[idx].p) if (SHARED_OK != (r = shared_map(idx))) { shared_demux(idx, mode); return(r); } if ((SHARED_ID_0 != (shared_lt[idx].p)->s.ID[0]) || (SHARED_ID_1 != (shared_lt[idx].p)->s.ID[1]) || (BLOCK_SHARED != (shared_lt[idx].p)->s.tflag)) { shared_demux(idx, mode); return(r); } return(SHARED_OK); } SHARED_P shared_realloc(int idx, long newsize) /* realloc shared memory segment */ { int h, key, i, r; BLKHEAD *bp; long transfersize; r = SHARED_OK; if (newsize < 0) return(NULL); if (shared_check_locked_index(idx)) return(NULL); if (0 == (shared_gt[idx].attr & SHARED_RESIZE)) return(NULL); if (-1 != shared_lt[idx].lkcnt) return(NULL); /* check for RW lock */ if (shared_adjust_size(shared_gt[idx].size) == shared_adjust_size(newsize)) { shared_gt[idx].size = newsize; return((SHARED_P)((shared_lt[idx].p) + 1)); } for (i = 0; ; i++) { if (i >= shared_range) return(NULL); /* table full, signal error & exit */ key = shared_kbase + ((i + shared_get_hash(newsize, idx)) % shared_range); h = shmget(key, shared_adjust_size(newsize), IPC_CREAT | IPC_EXCL | shared_create_mode); if (SHARED_INVALID == h) continue; /* segment already accupied */ bp = (BLKHEAD *)shmat(h, 0, 0); /* try attach */ if (((BLKHEAD *)SHARED_INVALID) == bp) /* cannot attach, delete segment, try with another key */ { shmctl(h, IPC_RMID, 0); continue; } *bp = *(shared_lt[idx].p); /* copy header, then data */ transfersize = ((newsize < shared_gt[idx].size) ? newsize : shared_gt[idx].size); if (transfersize > 0) memcpy((void *)(bp + 1), (void *)((shared_lt[idx].p) + 1), transfersize); if (shmdt((char *)(shared_lt[idx].p))) r = SHARED_IPCERR; /* try to detach old segment */ if (shmctl(shared_gt[idx].handle, IPC_RMID, 0)) if (SHARED_OK == r) r = SHARED_IPCERR; /* destroy old shared memory segment */ shared_gt[idx].size = newsize; /* signal new size */ shared_gt[idx].handle = h; /* signal new handle */ shared_gt[idx].key = key; /* signal new key */ shared_lt[idx].p = bp; break; } return((SHARED_P)(bp + 1)); } int shared_free(int idx) /* detach segment, if last process & !PERSIST, destroy segment */ { int cnt, r, r2; if (SHARED_OK != (r = shared_validate(idx, SHARED_RDWRITE | SHARED_WAIT))) return(r); if (SHARED_OK != (r = shared_detach_process(shared_gt[idx].sem))) /* update number of processes using segment */ { shared_demux(idx, SHARED_RDWRITE); return(r); } shared_lt[idx].tcnt--; /* update number of threads using segment */ if (shared_lt[idx].tcnt > 0) return(shared_demux(idx, SHARED_RDWRITE)); /* if more threads are using segment we are done */ if (shmdt((char *)(shared_lt[idx].p))) /* if, we are the last thread, try to detach segment */ { shared_demux(idx, SHARED_RDWRITE); return(SHARED_IPCERR); } shared_lt[idx].p = NULL; /* clear entry in local table */ shared_lt[idx].seekpos = 0L; /* r/w pointer positioned at beg of block */ if (-1 == (cnt = shared_process_count(shared_gt[idx].sem))) /* get number of processes hanging on segment */ { shared_demux(idx, SHARED_RDWRITE); return(SHARED_IPCERR); } if ((0 == cnt) && (0 == (shared_gt[idx].attr & SHARED_PERSIST))) r = shared_destroy_entry(idx); /* no procs on seg, destroy it */ r2 = shared_demux(idx, SHARED_RDWRITE); return(r ? r : r2); } SHARED_P shared_lock(int idx, int mode) /* lock given segment for exclusive access */ { int r; if (shared_mux(idx, mode)) return(NULL); /* idx checked by shared_mux */ if (0 != shared_lt[idx].lkcnt) /* are we already locked ?? */ if (SHARED_OK != (r = shared_map(idx))) { shared_demux(idx, mode); return(NULL); } if (NULL == shared_lt[idx].p) /* stupid pointer ?? */ if (SHARED_OK != (r = shared_map(idx))) { shared_demux(idx, mode); return(NULL); } if ((SHARED_ID_0 != (shared_lt[idx].p)->s.ID[0]) || (SHARED_ID_1 != (shared_lt[idx].p)->s.ID[1]) || (BLOCK_SHARED != (shared_lt[idx].p)->s.tflag)) { shared_demux(idx, mode); return(NULL); } if (mode & SHARED_RDWRITE) { shared_lt[idx].lkcnt = -1; shared_gt[idx].nprocdebug++; } else shared_lt[idx].lkcnt++; shared_lt[idx].seekpos = 0L; /* r/w pointer positioned at beg of block */ return((SHARED_P)((shared_lt[idx].p) + 1)); } int shared_unlock(int idx) /* unlock given segment, assumes seg is locked !! */ { int r, r2, mode; if (SHARED_OK != (r = shared_check_locked_index(idx))) return(r); if (shared_lt[idx].lkcnt > 0) { shared_lt[idx].lkcnt--; /* unlock read lock */ mode = SHARED_RDONLY; } else { shared_lt[idx].lkcnt = 0; /* unlock write lock */ shared_gt[idx].nprocdebug--; mode = SHARED_RDWRITE; } if (0 == shared_lt[idx].lkcnt) if (shared_gt[idx].attr & SHARED_RESIZE) { if (shmdt((char *)(shared_lt[idx].p))) r = SHARED_IPCERR; /* segment is resizable, then detach segment */ shared_lt[idx].p = NULL; /* signal detachment in local table */ } r2 = shared_demux(idx, mode); /* unlock segment, rest is only parameter checking */ return(r ? r : r2); } /* API routines - support and info routines */ int shared_attr(int idx) /* get the attributes of the shared memory segment */ { int r; if (shared_check_locked_index(idx)) return(SHARED_INVALID); r = shared_gt[idx].attr; return(r); } int shared_set_attr(int idx, int newattr) /* get the attributes of the shared memory segment */ { int r; if (shared_check_locked_index(idx)) return(SHARED_INVALID); if (-1 != shared_lt[idx].lkcnt) return(SHARED_INVALID); /* ADDED - check for RW lock */ r = shared_gt[idx].attr; shared_gt[idx].attr = newattr; return(r); } int shared_set_debug(int mode) /* set/reset debug mode */ { int r = shared_debug; shared_debug = mode; return(r); } int shared_set_createmode(int mode) /* set/reset debug mode */ { int r = shared_create_mode; shared_create_mode = mode; return(r); } int shared_list(int id) { int i, r; if (NULL == shared_gt) return(SHARED_NOTINIT); /* not initialized */ if (NULL == shared_lt) return(SHARED_NOTINIT); /* not initialized */ if (shared_debug) printf("shared_list:"); r = SHARED_OK; printf(" Idx Key Nproc Size Flags\n"); printf("==============================================\n"); for (i=0; i= SHARED_ERRBASE) { printf(" cannot clear PERSIST attribute"); } if (shared_free(i)) { printf(" delete failed\n"); } else { printf(" deleted\n"); } } if (shared_debug) printf(" done\n"); return(r); /* table full */ } /************************* CFITSIO DRIVER FUNCTIONS ***************************/ int smem_init(void) { return(0); } int smem_shutdown(void) { if (shared_init_called) shared_cleanup(); return(0); } int smem_setoptions(int option) { option = 0; return(0); } int smem_getoptions(int *options) { if (NULL == options) return(SHARED_NULPTR); *options = 0; return(0); } int smem_getversion(int *version) { if (NULL == version) return(SHARED_NULPTR); *version = 10; return(0); } int smem_open(char *filename, int rwmode, int *driverhandle) { int h, nitems, r; DAL_SHM_SEGHEAD *sp; if (NULL == filename) return(SHARED_NULPTR); if (NULL == driverhandle) return(SHARED_NULPTR); nitems = sscanf(filename, "h%d", &h); if (1 != nitems) return(SHARED_BADARG); if (SHARED_OK != (r = shared_attach(h))) return(r); if (NULL == (sp = (DAL_SHM_SEGHEAD *)shared_lock(h, ((READWRITE == rwmode) ? SHARED_RDWRITE : SHARED_RDONLY)))) { shared_free(h); return(SHARED_BADARG); } if ((h != sp->h) || (DAL_SHM_SEGHEAD_ID != sp->ID)) { shared_unlock(h); shared_free(h); return(SHARED_BADARG); } *driverhandle = h; return(0); } int smem_create(char *filename, int *driverhandle) { DAL_SHM_SEGHEAD *sp; int h, sz, nitems; if (NULL == filename) return(SHARED_NULPTR); /* currently ignored */ if (NULL == driverhandle) return(SHARED_NULPTR); nitems = sscanf(filename, "h%d", &h); if (1 != nitems) return(SHARED_BADARG); if (SHARED_INVALID == (h = shared_malloc(sz = 2880 + sizeof(DAL_SHM_SEGHEAD), SHARED_RESIZE | SHARED_PERSIST, h))) return(SHARED_NOMEM); if (NULL == (sp = (DAL_SHM_SEGHEAD *)shared_lock(h, SHARED_RDWRITE))) { shared_free(h); return(SHARED_BADARG); } sp->ID = DAL_SHM_SEGHEAD_ID; sp->h = h; sp->size = sz; sp->nodeidx = -1; *driverhandle = h; return(0); } int smem_close(int driverhandle) { int r; if (SHARED_OK != (r = shared_unlock(driverhandle))) return(r); return(shared_free(driverhandle)); } int smem_remove(char *filename) { int nitems, h, r; if (NULL == filename) return(SHARED_NULPTR); nitems = sscanf(filename, "h%d", &h); if (1 != nitems) return(SHARED_BADARG); if (0 == shared_check_locked_index(h)) /* are we locked ? */ { if (-1 != shared_lt[h].lkcnt) /* are we locked RO ? */ { if (SHARED_OK != (r = shared_unlock(h))) return(r); /* yes, so relock in RW */ if (NULL == shared_lock(h, SHARED_RDWRITE)) return(SHARED_BADARG); } } else /* not locked */ { if (SHARED_OK != (r = smem_open(filename, READWRITE, &h))) return(r); /* so open in RW mode */ } shared_set_attr(h, SHARED_RESIZE); /* delete PERSIST attribute */ return(smem_close(h)); /* detach segment (this will delete it) */ } int smem_size(int driverhandle, LONGLONG *size) { if (NULL == size) return(SHARED_NULPTR); if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); *size = (LONGLONG) (shared_gt[driverhandle].size - sizeof(DAL_SHM_SEGHEAD)); return(0); } int smem_flush(int driverhandle) { if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); return(0); } int smem_seek(int driverhandle, LONGLONG offset) { if (offset < 0) return(SHARED_BADARG); if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); shared_lt[driverhandle].seekpos = offset; return(0); } int smem_read(int driverhandle, void *buffer, long nbytes) { if (NULL == buffer) return(SHARED_NULPTR); if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); if (nbytes < 0) return(SHARED_BADARG); if ((shared_lt[driverhandle].seekpos + nbytes) > shared_gt[driverhandle].size) return(SHARED_BADARG); /* read beyond EOF */ memcpy(buffer, ((char *)(((DAL_SHM_SEGHEAD *)(shared_lt[driverhandle].p + 1)) + 1)) + shared_lt[driverhandle].seekpos, nbytes); shared_lt[driverhandle].seekpos += nbytes; return(0); } int smem_write(int driverhandle, void *buffer, long nbytes) { if (NULL == buffer) return(SHARED_NULPTR); if (shared_check_locked_index(driverhandle)) return(SHARED_INVALID); if (-1 != shared_lt[driverhandle].lkcnt) return(SHARED_INVALID); /* are we locked RW ? */ if (nbytes < 0) return(SHARED_BADARG); if ((unsigned long)(shared_lt[driverhandle].seekpos + nbytes) > (unsigned long)(shared_gt[driverhandle].size - sizeof(DAL_SHM_SEGHEAD))) { /* need to realloc shmem */ if (NULL == shared_realloc(driverhandle, shared_lt[driverhandle].seekpos + nbytes + sizeof(DAL_SHM_SEGHEAD))) return(SHARED_NOMEM); } memcpy(((char *)(((DAL_SHM_SEGHEAD *)(shared_lt[driverhandle].p + 1)) + 1)) + shared_lt[driverhandle].seekpos, buffer, nbytes); shared_lt[driverhandle].seekpos += nbytes; return(0); } #endif indi-0.5/src/cfitsio/getcoll.c0000644000175000017500000005445210610474375014156 0ustar jrjr/* This file, getcoll.c, contains routines that read data elements from */ /* a FITS image or table, with logical datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgcvl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ char nulval, /* I - value for null pixels */ char *array, /* O - array of values */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of logical values from a column in the current FITS HDU. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcll( fptr, colnum, firstrow, firstelem, nelem, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ char *array, /* O - array of values */ int *status) /* IO - error status */ /* !!!! THIS ROUTINE IS DEPRECATED AND SHOULD NOT BE USED !!!!!! !!!! USE ffgcvl INSTEAD !!!!!! Read an array of logical values from a column in the current FITS HDU. No checking for null values will be performed. */ { char nulval = 0; int anynul; ffgcvl( fptr, colnum, firstrow, firstelem, nelem, nulval, array, &anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ char *array, /* O - array of values */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of logical values from a column in the current FITS HDU. */ { char nulval = 0; ffgcll( fptr, colnum, firstrow, firstelem, nelem, 2, nulval, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ char nulval, /* I - value for null pixels if nultyp = 1 */ char *array, /* O - array of values */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of logical values from a column in the current FITS HDU. */ { double dtemp; int tcode, maxelem, hdutype, ii, nulcheck; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, readptr, tnull, rowlen, rownum, remain, next; double scale, zero; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ unsigned char buffer[DBUFFSIZE], *buffptr; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode != TLOGICAL) return(*status = NOT_LOGICAL_COL); /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default, check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ /*---------------------------------------------------------------------*/ /* Now read the logical values from the FITS column. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ ntodo = (long) remain; /* max number of elements to read at one time */ while (ntodo) { /* limit the number of pixels to read at one time to the number that remain in the current vector. */ ntodo = (long) minvalue(ntodo, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); readptr = startpos + (rowlen * rownum) + (elemnum * incre); ffgi1b(fptr, readptr, ntodo, incre, buffer, status); /* convert from T or F to 1 or 0 */ buffptr = buffer; for (ii = 0; ii < ntodo; ii++, next++, buffptr++) { if (*buffptr == 'T') array[next] = 1; else if (*buffptr =='F') array[next] = 0; else if (*buffptr == 0) { array[next] = nulval; /* set null values to input nulval */ if (anynul) *anynul = 1; if (nulcheck == 2) { nularray[next] = 1; /* set null flags */ } } else /* some other illegal character; return the char value */ { array[next] = (char) *buffptr; } } if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; sprintf(message, "Error reading elements %.0f thruough %.0f of logical array (ffgcl).", dtemp+1., dtemp + ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on later row */ { elemnum = 0; rownum++; } } ntodo = (long) remain; /* this is the maximum number to do in next loop */ } /* End of main while Loop */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgcx( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG frow, /* I - first row to write (1 = 1st row) */ LONGLONG fbit, /* I - first bit to write (1 = 1st) */ LONGLONG nbit, /* I - number of bits to write */ char *larray, /* O - array of logicals corresponding to bits */ int *status) /* IO - error status */ /* read an array of logical values from a specified bit or byte column of the binary table. larray is set = TRUE, if the corresponding bit = 1, otherwise it is set to FALSE. The binary table column being read from must have datatype 'B' or 'X'. */ { LONGLONG bstart; long offset, ndone, ii, repeat, bitloc, fbyte; LONGLONG rstart, estart; int tcode, descrp; unsigned char cbuff; static unsigned char onbit[8] = {128, 64, 32, 16, 8, 4, 2, 1}; tcolumn *colptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check input parameters */ if (nbit < 1) return(*status); else if (frow < 1) return(*status = BAD_ROW_NUM); else if (fbit < 1) return(*status = BAD_ELEM_NUM); /* position to the correct HDU */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); fbyte = (long) ((fbit + 7) / 8); bitloc = (long) (fbit - 1 - ((fbit - 1) / 8 * 8)); ndone = 0; rstart = frow - 1; estart = fbyte - 1; colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (abs(tcode) > TBYTE) return(*status = NOT_LOGICAL_COL); /* not correct datatype column */ if (tcode > 0) { descrp = FALSE; /* not a variable length descriptor column */ /* N.B: REPEAT is the number of bytes, not number of bits */ repeat = (long) colptr->trepeat; if (tcode == TBIT) repeat = (repeat + 7) / 8; /* convert from bits to bytes */ if (fbyte > repeat) return(*status = BAD_ELEM_NUM); /* calc the i/o pointer location to start of sequence of pixels */ bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) + colptr->tbcol + estart; } else { descrp = TRUE; /* a variable length descriptor column */ /* only bit arrays (tform = 'X') are supported for variable */ /* length arrays. REPEAT is the number of BITS in the array. */ ffgdes(fptr, colnum, frow, &repeat, &offset, status); if (tcode == -TBIT) repeat = (repeat + 7) / 8; if ((fbit + nbit + 6) / 8 > repeat) return(*status = BAD_ELEM_NUM); /* calc the i/o pointer location to start of sequence of pixels */ bstart = (fptr->Fptr)->datastart + offset + (fptr->Fptr)->heapstart + estart; } /* move the i/o pointer to the start of the pixel sequence */ if (ffmbyt(fptr, bstart, REPORT_EOF, status) > 0) return(*status); /* read the next byte */ while (1) { if (ffgbyt(fptr, 1, &cbuff, status) > 0) return(*status); for (ii = bitloc; (ii < 8) && (ndone < nbit); ii++, ndone++) { if(cbuff & onbit[ii]) /* test if bit is set */ larray[ndone] = TRUE; else larray[ndone] = FALSE; } if (ndone == nbit) /* finished all the bits */ return(*status); /* not done, so get the next byte */ if (!descrp) { estart++; if (estart == repeat) { /* move the i/o pointer to the next row of pixels */ estart = 0; rstart = rstart + 1; bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) + colptr->tbcol; ffmbyt(fptr, bstart, REPORT_EOF, status); } } bitloc = 0; } } /*--------------------------------------------------------------------------*/ int ffgcxui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG nrows, /* I - no. of rows to read */ long input_first_bit, /* I - first bit to read (1 = 1st) */ int input_nbits, /* I - number of bits to read (<= 32) */ unsigned short *array, /* O - array of integer values */ int *status) /* IO - error status */ /* Read a consecutive string of bits from an 'X' or 'B' column and interprete them as an unsigned integer. The number of bits must be less than or equal to 16 or the total number of bits in the column, which ever is less. */ { int ii, firstbit, nbits, bytenum, startbit, numbits, endbit; int firstbyte, lastbyte, nbytes, rshift, lshift; unsigned short colbyte[5]; tcolumn *colptr; char message[81]; if (*status > 0 || nrows == 0) return(*status); /* check input parameters */ if (firstrow < 1) { sprintf(message, "Starting row number is less than 1: %ld (ffgcxui)", (long) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } else if (input_first_bit < 1) { sprintf(message, "Starting bit number is less than 1: %ld (ffgcxui)", input_first_bit); ffpmsg(message); return(*status = BAD_ELEM_NUM); } else if (input_nbits > 16) { sprintf(message, "Number of bits to read is > 16: %d (ffgcxui)", input_nbits); ffpmsg(message); return(*status = BAD_ELEM_NUM); } /* position to the correct HDU */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg("This is not a binary table extension (ffgcxui)"); return(*status = NOT_BTABLE); } if (colnum > (fptr->Fptr)->tfield) { sprintf(message, "Specified column number is out of range: %d (ffgcxui)", colnum); ffpmsg(message); sprintf(message, " There are %d columns in this table.", (fptr->Fptr)->tfield ); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ if (abs(colptr->tdatatype) > TBYTE) { ffpmsg("Can only read bits from X or B type columns. (ffgcxui)"); return(*status = NOT_LOGICAL_COL); /* not correct datatype column */ } firstbyte = (input_first_bit - 1 ) / 8 + 1; lastbyte = (input_first_bit + input_nbits - 2) / 8 + 1; nbytes = lastbyte - firstbyte + 1; if (colptr->tdatatype == TBIT && input_first_bit + input_nbits - 1 > (long) colptr->trepeat) { ffpmsg("Too many bits. Tried to read past width of column (ffgcxui)"); return(*status = BAD_ELEM_NUM); } else if (colptr->tdatatype == TBYTE && lastbyte > (long) colptr->trepeat) { ffpmsg("Too many bits. Tried to read past width of column (ffgcxui)"); return(*status = BAD_ELEM_NUM); } for (ii = 0; ii < nrows; ii++) { /* read the relevant bytes from the row */ if (ffgcvui(fptr, colnum, firstrow+ii, firstbyte, nbytes, 0, colbyte, NULL, status) > 0) { ffpmsg("Error reading bytes from column (ffgcxui)"); return(*status); } firstbit = (input_first_bit - 1) % 8; /* modulus operator */ nbits = input_nbits; array[ii] = 0; /* select and shift the bits from each byte into the output word */ while(nbits) { bytenum = firstbit / 8; startbit = firstbit % 8; numbits = minvalue(nbits, 8 - startbit); endbit = startbit + numbits - 1; rshift = 7 - endbit; lshift = nbits - numbits; array[ii] = ((colbyte[bytenum] >> rshift) << lshift) | array[ii]; nbits -= numbits; firstbit += numbits; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcxuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG nrows, /* I - no. of rows to read */ long input_first_bit, /* I - first bit to read (1 = 1st) */ int input_nbits, /* I - number of bits to read (<= 32) */ unsigned int *array, /* O - array of integer values */ int *status) /* IO - error status */ /* Read a consecutive string of bits from an 'X' or 'B' column and interprete them as an unsigned integer. The number of bits must be less than or equal to 32 or the total number of bits in the column, which ever is less. */ { int ii, firstbit, nbits, bytenum, startbit, numbits, endbit; int firstbyte, lastbyte, nbytes, rshift, lshift; unsigned int colbyte[5]; tcolumn *colptr; char message[81]; if (*status > 0 || nrows == 0) return(*status); /* check input parameters */ if (firstrow < 1) { sprintf(message, "Starting row number is less than 1: %ld (ffgcxuk)", (long) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } else if (input_first_bit < 1) { sprintf(message, "Starting bit number is less than 1: %ld (ffgcxuk)", input_first_bit); ffpmsg(message); return(*status = BAD_ELEM_NUM); } else if (input_nbits > 32) { sprintf(message, "Number of bits to read is > 32: %d (ffgcxuk)", input_nbits); ffpmsg(message); return(*status = BAD_ELEM_NUM); } /* position to the correct HDU */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg("This is not a binary table extension (ffgcxuk)"); return(*status = NOT_BTABLE); } if (colnum > (fptr->Fptr)->tfield) { sprintf(message, "Specified column number is out of range: %d (ffgcxuk)", colnum); ffpmsg(message); sprintf(message, " There are %d columns in this table.", (fptr->Fptr)->tfield ); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ if (abs(colptr->tdatatype) > TBYTE) { ffpmsg("Can only read bits from X or B type columns. (ffgcxuk)"); return(*status = NOT_LOGICAL_COL); /* not correct datatype column */ } firstbyte = (input_first_bit - 1 ) / 8 + 1; lastbyte = (input_first_bit + input_nbits - 2) / 8 + 1; nbytes = lastbyte - firstbyte + 1; if (colptr->tdatatype == TBIT && input_first_bit + input_nbits - 1 > (long) colptr->trepeat) { ffpmsg("Too many bits. Tried to read past width of column (ffgcxuk)"); return(*status = BAD_ELEM_NUM); } else if (colptr->tdatatype == TBYTE && lastbyte > (long) colptr->trepeat) { ffpmsg("Too many bits. Tried to read past width of column (ffgcxuk)"); return(*status = BAD_ELEM_NUM); } for (ii = 0; ii < nrows; ii++) { /* read the relevant bytes from the row */ if (ffgcvuk(fptr, colnum, firstrow+ii, firstbyte, nbytes, 0, colbyte, NULL, status) > 0) { ffpmsg("Error reading bytes from column (ffgcxuk)"); return(*status); } firstbit = (input_first_bit - 1) % 8; /* modulus operator */ nbits = input_nbits; array[ii] = 0; /* select and shift the bits from each byte into the output word */ while(nbits) { bytenum = firstbit / 8; startbit = firstbit % 8; numbits = minvalue(nbits, 8 - startbit); endbit = startbit + numbits - 1; rshift = 7 - endbit; lshift = nbits - numbits; array[ii] = ((colbyte[bytenum] >> rshift) << lshift) | array[ii]; nbits -= numbits; firstbit += numbits; } } return(*status); } indi-0.5/src/cfitsio/getcold.c0000644000175000017500000020304310610474374014135 0ustar jrjr/* This file, getcold.c, contains routines that read data elements from */ /* a FITS image or table, with double datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double nulval, /* I - value for undefined pixels */ double *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; double nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TDOUBLE, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcld(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TDOUBLE, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcld(fptr, 2, row, firstelem, nelem, 1, 2, 0., array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ double nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ double *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dd(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ double nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ double *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { LONGLONG nfits, narray; long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; double nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TDOUBLE, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcld(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcld(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvd(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ double nulval, /* I - value to set undefined pixels */ double *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; double nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvd is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TDOUBLE, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvd: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgcld(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfd(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ double *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; double nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvd is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TDOUBLE, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvd: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcld(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ double *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcld(fptr, 1, row, firstelem, nelem, 1, 1, 0., array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvd(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double nulval, /* I - value for null pixels */ double *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvm(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double nulval, /* I - value for null pixels */ double *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. TSCAL and ZERO should not be used with complex values. */ { char cdummy; /* a complex double value is interpreted as a pair of double values, */ /* thus need to multiply the first element and number of elements by 2 */ ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfd(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { double dummy = 0; ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfm(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ double *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. TSCAL and ZERO should not be used with complex values. */ { long ii, jj; float dummy = 0; char *carray; /* a complex double value is interpreted as a pair of double values, */ /* thus need to multiply the first element and number of elements by 2 */ /* allocate temporary array */ carray = (char *) calloc( (size_t) (nelem * 2), 1); ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 2, dummy, array, carray, anynul, status); for (ii = 0, jj = 0; jj < nelem; ii += 2, jj++) { if (carray[ii] || carray[ii + 1]) nularray[jj] = 1; else nularray[jj] = 0; } free(carray); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcld( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ double nulval, /* I - value for null pixels if nultyp = 1 */ double *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1, dtemp; int tcode, hdutype, xcode, decimals, maxelem; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TDOUBLE) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, &array[next], status); if (convert) fffr8r8(&array[next], ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1r8((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2r8((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4r8((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8r8( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4r8((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstrr8((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgcld).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgcld).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = (long) (elemnum / repeat); rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (long) ((-elemnum - 1) / repeat + 1); rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1r8(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = input[ii] * scale + zero; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2r8(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = input[ii] * scale + zero; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4r8(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = input[ii] * scale + zero; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8r8(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = input[ii] * scale + zero; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4r8(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else output[ii] = (double) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = zero; } else output[ii] = input[ii] * scale + zero; } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8r8(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { memcpy(output, input, ntodo * sizeof(double) ); } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = input[ii] * scale + zero; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else { nullarray[ii] = 1; /* explicitly set value in case output contains a NaN */ output[ii] = DOUBLENULLVALUE; } } else /* it's an underflow */ output[ii] = 0; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else { nullarray[ii] = 1; /* explicitly set value in case output contains a NaN */ output[ii] = DOUBLENULLVALUE; } } else /* it's an underflow */ output[ii] = zero; } else output[ii] = input[ii] * scale + zero; } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstrr8(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ double nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ double *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); output[ii] = (dvalue * scale + zero); /* apply the scaling */ } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } indi-0.5/src/cfitsio/ricecomp.c0000644000175000017500000003264010610474375014321 0ustar jrjr/* The following code was written by Richard White at STScI and made available for use in CFITSIO in July 1999. These routines were originally contained in 2 source files: rcomp.c and rdecomp.c, and the 'include' file now called ricecomp.h was originally called buffer.h. */ /*----------------------------------------------------------*/ /* */ /* START OF SOURCE FILE ORIGINALLY CALLED rcomp.c */ /* */ /*----------------------------------------------------------*/ /* @(#) rcomp.c 1.5 99/03/01 12:40:27 */ /* rcomp.c Compress image line using * (1) Difference of adjacent pixels * (2) Rice algorithm coding * * Returns number of bytes written to code buffer or * -1 on failure */ #include #include #include #include "ricecomp.h" /* originally included in rcomp.c file (WDP) */ #include "fitsio2.h" static void start_outputing_bits(Buffer *buffer); static int done_outputing_bits(Buffer *buffer); static int output_nbits(Buffer *buffer, int bits, int n); /* this routine used to be called 'rcomp' (WDP) */ int fits_rcomp(int a[], /* input array */ int nx, /* number of input pixels */ unsigned char *c, /* output buffer */ int clen, /* max length of output */ int nblock) /* coding block size */ { Buffer bufmem, *buffer = &bufmem; int bsize, i, j, thisblock; int lastpix, nextpix, pdiff; int v, fs, fsmask, top, fsmax, fsbits, bbits; int lbitbuffer, lbits_to_go; unsigned int psum; double pixelsum, dpsum; unsigned int *diff; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ bsize = 4; /* nblock = 32; */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return(-1); } bbits = 1<start = c; buffer->current = c; buffer->end = c+clen; buffer->bits_to_go = 8; /* * array for differences mapped to non-negative values */ diff = (unsigned int *) malloc(nblock*sizeof(unsigned int)); if (diff == (unsigned int *) NULL) { ffpmsg("fits_rcomp: insufficient memory"); return(-1); } /* * Code in blocks of nblock pixels */ start_outputing_bits(buffer); /* write out first int value to the first 4 bytes of the buffer */ if (output_nbits(buffer, a[0], 32) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } lastpix = a[0]; /* the first difference will always be zero */ thisblock = nblock; for (i=0; i> 1; for (fs = 0; psum>0; fs++) psum >>= 1; /* * write the codes * fsbits ID bits used to indicate split level */ if (fs >= fsmax) { /* Special high entropy case when FS >= fsmax * Just write pixel difference values directly, no Rice coding at all. */ if (output_nbits(buffer, fsmax+1, fsbits) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } for (j=0; jbitbuffer; lbits_to_go = buffer->bits_to_go; for (j=0; j> fs; /* * top is coded by top zeros + 1 */ if (lbits_to_go >= top+1) { lbitbuffer <<= top+1; lbitbuffer |= 1; lbits_to_go -= top+1; } else { lbitbuffer <<= lbits_to_go; if (putcbuf(lbitbuffer & 0xff,buffer) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } for (top -= lbits_to_go; top>=8; top -= 8) { if (putcbuf(0, buffer) == EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } } lbitbuffer = 1; lbits_to_go = 7-top; } /* * bottom FS bits are written without coding * code is output_nbits, moved into this routine to reduce overheads * This code potentially breaks if FS>24, so I am limiting * FS to 24 by choice of FSMAX above. */ if (fs > 0) { lbitbuffer <<= fs; lbitbuffer |= v & fsmask; lbits_to_go -= fs; while (lbits_to_go <= 0) { if (putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer)==EOF) { ffpmsg("rice_encode: end of buffer"); free(diff); return(-1); } lbits_to_go += 8; } } } buffer->bitbuffer = lbitbuffer; buffer->bits_to_go = lbits_to_go; } } done_outputing_bits(buffer); free(diff); /* * return number of bytes used */ return(buffer->current - buffer->start); } /*---------------------------------------------------------------------------*/ /* bit_output.c * * Bit output routines * Procedures return zero on success, EOF on end-of-buffer * * Programmer: R. White Date: 20 July 1998 */ /* Initialize for bit output */ static void start_outputing_bits(Buffer *buffer) { /* * Buffer is empty to start with */ buffer->bitbuffer = 0; buffer->bits_to_go = 8; } /*---------------------------------------------------------------------------*/ /* Output N bits (N must be <= 32) */ static int output_nbits(Buffer *buffer, int bits, int n) { /* local copies */ int lbitbuffer; int lbits_to_go; /* * insert bits at end of bitbuffer */ lbitbuffer = buffer->bitbuffer; lbits_to_go = buffer->bits_to_go; if (lbits_to_go+n > 32) { /* * special case for large n: put out the top lbits_to_go bits first * note that 0 < lbits_to_go <= 8 */ lbitbuffer <<= lbits_to_go; lbitbuffer |= (bits>>(n-lbits_to_go)) & ((1<>(-lbits_to_go)) & 0xff,buffer) == EOF) return(EOF); lbits_to_go += 8; } buffer->bitbuffer = lbitbuffer; buffer->bits_to_go = lbits_to_go; return(0); } /*---------------------------------------------------------------------------*/ /* Flush out the last bits */ static int done_outputing_bits(Buffer *buffer) { if(buffer->bits_to_go < 8) { if (putcbuf(buffer->bitbuffer<bits_to_go,buffer) == EOF) return(EOF); } return(0); } /*---------------------------------------------------------------------------*/ /*----------------------------------------------------------*/ /* */ /* START OF SOURCE FILE ORIGINALLY CALLED rdecomp.c */ /* */ /*----------------------------------------------------------*/ /* @(#) rdecomp.c 1.4 99/03/01 12:38:41 */ /* rdecomp.c Decompress image line using * (1) Difference of adjacent pixels * (2) Rice algorithm coding * * Returns 0 on success or 1 on failure */ /* moved these 'includes' to the beginning of the file (WDP) #include #include */ /* this routine used to be called 'rdecomp' (WDP) */ int fits_rdecomp (unsigned char *c, /* input buffer */ int clen, /* length of input */ unsigned int array[], /* output array */ int nx, /* number of output pixels */ int nblock) /* coding block size */ { int bsize, i, k, imax; int nbits, nzero, fs; unsigned char *cend, bytevalue; unsigned int b, diff, lastpix; int fsmax, fsbits, bbits; static int *nonzero_count = (int *)NULL; /* * Original size of each pixel (bsize, bytes) and coding block * size (nblock, pixels) * Could make bsize a parameter to allow more efficient * compression of short & byte images. */ bsize = 4; /* nblock = 32; */ /* * From bsize derive: * FSBITS = # bits required to store FS * FSMAX = maximum value for FS * BBITS = bits/pixel for direct coding */ switch (bsize) { case 1: fsbits = 3; fsmax = 6; break; case 2: fsbits = 4; fsmax = 14; break; case 4: fsbits = 5; fsmax = 25; break; default: ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes"); return 1; } bbits = 1<=0; ) { for ( ; i>=k; i--) nonzero_count[i] = nzero; k = k/2; nzero--; } } /* * Decode in blocks of nblock pixels */ /* first 4 bytes of input buffer contain the value of the first */ /* 4 byte integer value, without any encoding */ lastpix = 0; bytevalue = c[0]; lastpix = lastpix | (bytevalue<<24); bytevalue = c[1]; lastpix = lastpix | (bytevalue<<16); bytevalue = c[2]; lastpix = lastpix | (bytevalue<<8); bytevalue = c[3]; lastpix = lastpix | bytevalue; c += 4; cend = c + clen - 4; b = *c++; /* bit buffer */ nbits = 8; /* number of bits remaining in b */ for (i = 0; i> nbits) - 1; b &= (1< nx) imax = nx; if (fs<0) { /* low-entropy case, all zero differences */ for ( ; i= 0; k -= 8) { b = *c++; diff |= b<0) { b = *c++; diff |= b>>(-k); b &= (1<>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } else { /* normal case, Rice coding */ for ( ; i>nbits); b &= (1<>1; } else { diff = ~(diff>>1); } array[i] = diff+lastpix; lastpix = array[i]; } } if (c > cend) { ffpmsg("decompression error: hit end of compressed byte stream"); return 1; } } if (c < cend) { ffpmsg("decompression warning: unused bytes at end of compressed buffer"); } return 0; } indi-0.5/src/cfitsio/putcolb.c0000644000175000017500000010705310610474375014171 0ustar jrjr/* This file, putcolb.c, contains routines that write data elements to */ /* a FITS image or table with char (byte) datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; unsigned char nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TBYTE, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclb(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values that are written */ unsigned char nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; unsigned char nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TBYTE, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnb(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2db(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3db(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3db(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; LONGLONG nfits, narray; long fpixel[3]= {1,1,1}, lpixel[3]; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TBYTE, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclb(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclb(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ unsigned char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TBYTE, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclb(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclb(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise, we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && tcode == TBYTE) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TBYTE): if (writeraw) { /* write raw input bytes without conversion */ ffpi1b(fptr, ntodo, incre, &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffi1fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); } break; case (TLONGLONG): ffi1fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TSHORT): ffi1fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONG): ffi1fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffi1fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffi1fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (strchr(tform,'A')) { /* write raw input bytes without conversion */ /* This case is a hack to let users write a stream */ /* of bytes directly to the 'A' format column */ if (incre == twidth) ffpbyt(fptr, ntodo, &array[next], status); else ffpbytoff(fptr, twidth, ntodo/twidth, incre - twidth, &array[next], status); break; } else if (cform[1] != 's') /* "%s" format is a string */ { ffi1fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpclb).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned char *array, /* I - array of values to write */ unsigned char nulvalue, /* I - flag for undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclb(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood + 1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclb(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad + 1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclb(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffpextn( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG offset, /* I - byte offset from start of extension data */ LONGLONG nelem, /* I - number of elements to write */ void *buffer, /* I - stream of bytes to write */ int *status) /* IO - error status */ /* Write a stream of bytes to the current FITS HDU. This primative routine is mainly for writing non-standard "conforming" extensions and should not be used for standard IMAGE, TABLE or BINTABLE extensions. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* move to write position */ ffmbyt(fptr, (fptr->Fptr)->datastart+ offset, IGNORE_EOF, status); /* write the buffer */ ffpbyt(fptr, nelem, buffer, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fi1(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo); /* just copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ( ((double) input[ii]) - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fi2(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; /* just copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (((double) input[ii]) - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fi4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (((double) input[ii]) - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fi8(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fr4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) (( ( (double) input[ii] ) - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fr8(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = ( ( (double) input[ii] ) - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffi1fstr(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } indi-0.5/src/cfitsio/region.c0000644000175000017500000010405310610474375014001 0ustar jrjr#include #include #include #include #include "fitsio2.h" #include "region.h" static int Pt_in_Poly( double x, double y, int nPts, double *Pts ); /*---------------------------------------------------------------------------*/ int ffrrgn( const char *filename, WCSdata *wcs, SAORegion **Rgn, int *status ) /* Read regions from a SAO-style region file and return the information */ /* in the "SAORegion" structure. If it is nonNULL, use wcs to convert the */ /* region coordinates to pixels. Return an error if region is in degrees */ /* but no WCS data is provided. */ /*---------------------------------------------------------------------------*/ { char *currLine; char *namePtr, *paramPtr, *currLoc; char *pX, *pY, *endp; long allocLen, lineLen, hh, mm, dd; double *coords = 0, X, Y, R, x, y, ss, xsave= 0., ysave= 0.; int nParams, nCoords, negdec; int i, done; FILE *rgnFile; coordFmt cFmt; SAORegion *aRgn; RgnShape *newShape, *tmpShape; if( *status ) return( *status ); aRgn = (SAORegion *)malloc( sizeof(SAORegion) ); if( ! aRgn ) { ffpmsg("Couldn't allocate memory to hold Region file contents."); return(*status = MEMORY_ALLOCATION ); } aRgn->nShapes = 0; aRgn->Shapes = NULL; if( wcs && wcs->exists ) aRgn->wcs = *wcs; else aRgn->wcs.exists = 0; cFmt = pixel_fmt; /* set default format */ /* Allocate Line Buffer */ allocLen = 512; currLine = (char *)malloc( allocLen * sizeof(char) ); if( !currLine ) { free( aRgn ); ffpmsg("Couldn't allocate memory to hold Region file contents."); return(*status = MEMORY_ALLOCATION ); } /* Open Region File */ if( (rgnFile = fopen( filename, "r" ))==NULL ) { sprintf(currLine,"Could not open Region file %s.",filename); ffpmsg( currLine ); free( currLine ); free( aRgn ); return( *status = FILE_NOT_OPENED ); } /* Read in file, line by line */ while( fgets(currLine,allocLen,rgnFile) != NULL ) { /* Make sure we have a full line of text */ lineLen = strlen(currLine); while( lineLen==allocLen-1 && currLine[lineLen-1]!='\n' ) { currLoc = (char *)realloc( currLine, 2 * allocLen * sizeof(char) ); if( !currLoc ) { ffpmsg("Couldn't allocate memory to hold Region file contents."); *status = MEMORY_ALLOCATION; goto error; } else { currLine = currLoc; } fgets( currLine+lineLen, allocLen+1, rgnFile ); allocLen += allocLen; lineLen += strlen(currLine+lineLen); } currLoc = currLine; if( *currLoc == '#' ) { /* Look to see if it is followed by a format statement... */ /* if not skip line */ currLoc++; while( *currLoc==' ' ) currLoc++; if( !strncasecmp( currLoc, "format:", 7 ) ) { if( aRgn->nShapes ) { ffpmsg("Format code encountered after reading 1 or more shapes."); *status = PARSE_SYNTAX_ERR; goto error; } currLoc += 7; while( *currLoc==' ' ) currLoc++; if( !strncasecmp( currLoc, "pixel", 5 ) ) { cFmt = pixel_fmt; } else if( !strncasecmp( currLoc, "degree", 6 ) ) { cFmt = degree_fmt; } else if( !strncasecmp( currLoc, "hhmmss", 6 ) ) { cFmt = hhmmss_fmt; } else if( !strncasecmp( currLoc, "hms", 3 ) ) { cFmt = hhmmss_fmt; } else { ffpmsg("Unknown format code encountered in region file."); *status = PARSE_SYNTAX_ERR; goto error; } } } else if( !strncasecmp( currLoc, "glob", 4 ) ) { /* skip lines that begin with the word 'global' */ } else { while( *currLoc != '\0' ) { namePtr = currLoc; paramPtr = NULL; nParams = 1; /* Search for closing parenthesis */ done = 0; while( !done && !*status && *currLoc ) { switch (*currLoc) { case '(': *currLoc = '\0'; currLoc++; if( paramPtr ) /* Can't have two '(' in a region! */ *status = 1; else paramPtr = currLoc; break; case ')': *currLoc = '\0'; currLoc++; if( !paramPtr ) /* Can't have a ')' without a '(' first */ *status = 1; else done = 1; break; case '#': case '\n': *currLoc = '\0'; if( !paramPtr ) /* Allow for a blank line */ done = 1; break; case ':': currLoc++; cFmt = hhmmss_fmt; break; case 'd': currLoc++; cFmt = degree_fmt; break; case ',': nParams++; /* Fall through to default */ default: currLoc++; break; } } if( *status || !done ) { ffpmsg( "Error reading Region file" ); *status = PARSE_SYNTAX_ERR; goto error; } /* Skip white space in region name */ while( *namePtr==' ' ) namePtr++; /* Was this a blank line? Or the end of the current one */ if( ! *namePtr && ! paramPtr ) continue; /* Check for format code at beginning of the line */ if( !strncasecmp( namePtr, "image;", 6 ) ) { namePtr += 6; cFmt = pixel_fmt; } else if( !strncasecmp( namePtr, "physical;", 9 ) ) { namePtr += 9; cFmt = pixel_fmt; } else if( !strncasecmp( namePtr, "linear;", 7 ) ) { namePtr += 7; cFmt = pixel_fmt; } else if( !strncasecmp( namePtr, "fk4;", 4 ) ) { namePtr += 4; cFmt = degree_fmt; } else if( !strncasecmp( namePtr, "fk5;", 4 ) ) { namePtr += 4; cFmt = degree_fmt; } else if( !strncasecmp( namePtr, "icrs;", 5 ) ) { namePtr += 5; cFmt = degree_fmt; /* the following 5 cases support region files created by POW (or ds9 Version 4.x) which may have lines containing only a format code, not followed by a ';' (and with no region specifier on the line). We use the 'continue' statement to jump to the end of the loop and then continue reading the next line of the region file. */ } else if( !strncasecmp( namePtr, "fk5", 3 ) ) { cFmt = degree_fmt; continue; /* supports POW region file format */ } else if( !strncasecmp( namePtr, "fk4", 3 ) ) { cFmt = degree_fmt; continue; /* supports POW region file format */ } else if( !strncasecmp( namePtr, "icrs", 4 ) ) { cFmt = degree_fmt; continue; /* supports POW region file format */ } else if( !strncasecmp( namePtr, "image", 5 ) ) { cFmt = pixel_fmt; continue; /* supports POW region file format */ } else if( !strncasecmp( namePtr, "physical", 8 ) ) { cFmt = pixel_fmt; continue; /* supports POW region file format */ } else if( !strncasecmp( namePtr, "galactic;", 9 ) ) { ffpmsg( "Galactic region coordinates not supported" ); ffpmsg( namePtr ); *status = PARSE_SYNTAX_ERR; goto error; } else if( !strncasecmp( namePtr, "ecliptic;", 9 ) ) { ffpmsg( "ecliptic region coordinates not supported" ); ffpmsg( namePtr ); *status = PARSE_SYNTAX_ERR; goto error; } /**************************************************/ /* We've apparently found a region... Set it up */ /**************************************************/ if( !(aRgn->nShapes % 10) ) { if( aRgn->Shapes ) tmpShape = (RgnShape *)realloc( aRgn->Shapes, (10+aRgn->nShapes) * sizeof(RgnShape) ); else tmpShape = (RgnShape *) malloc( 10 * sizeof(RgnShape) ); if( tmpShape ) { aRgn->Shapes = tmpShape; } else { ffpmsg( "Failed to allocate memory for Region data"); *status = MEMORY_ALLOCATION; goto error; } } newShape = &aRgn->Shapes[aRgn->nShapes++]; newShape->sign = 1; newShape->shape = point_rgn; while( *namePtr==' ' ) namePtr++; /* Check for the shape's sign */ if( *namePtr=='+' ) { namePtr++; } else if( *namePtr=='-' ) { namePtr++; newShape->sign = 0; } /* Skip white space in region name */ while( *namePtr==' ' ) namePtr++; if( *namePtr=='\0' ) { ffpmsg( "Error reading Region file" ); *status = PARSE_SYNTAX_ERR; goto error; } lineLen = strlen( namePtr ) - 1; while( namePtr[lineLen]==' ' ) namePtr[lineLen--] = '\0'; /* Now identify the region */ if( !strcasecmp( namePtr, "circle" ) ) { newShape->shape = circle_rgn; if( nParams != 3 ) *status = PARSE_SYNTAX_ERR; nCoords = 2; } else if( !strcasecmp( namePtr, "annulus" ) ) { newShape->shape = annulus_rgn; if( nParams != 4 ) *status = PARSE_SYNTAX_ERR; nCoords = 2; } else if( !strcasecmp( namePtr, "ellipse" ) ) { newShape->shape = ellipse_rgn; if( nParams < 4 || nParams > 5 ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[4] = 0.0; nCoords = 2; } else if( !strcasecmp( namePtr, "elliptannulus" ) ) { newShape->shape = elliptannulus_rgn; if( !( nParams==8 || nParams==6 ) ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[6] = 0.0; newShape->param.gen.p[7] = 0.0; nCoords = 2; } else if( !strcasecmp( namePtr, "box" ) || !strcasecmp( namePtr, "rotbox" ) ) { newShape->shape = box_rgn; if( nParams < 4 || nParams > 5 ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[4] = 0.0; nCoords = 2; } else if( !strcasecmp( namePtr, "rectangle" ) || !strcasecmp( namePtr, "rotrectangle" ) ) { newShape->shape = rectangle_rgn; if( nParams < 4 || nParams > 5 ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[4] = 0.0; nCoords = 4; } else if( !strcasecmp( namePtr, "diamond" ) || !strcasecmp( namePtr, "rotdiamond" ) || !strcasecmp( namePtr, "rhombus" ) || !strcasecmp( namePtr, "rotrhombus" ) ) { newShape->shape = diamond_rgn; if( nParams < 4 || nParams > 5 ) *status = PARSE_SYNTAX_ERR; newShape->param.gen.p[4] = 0.0; nCoords = 2; } else if( !strcasecmp( namePtr, "sector" ) || !strcasecmp( namePtr, "pie" ) ) { newShape->shape = sector_rgn; if( nParams != 4 ) *status = PARSE_SYNTAX_ERR; nCoords = 2; } else if( !strcasecmp( namePtr, "point" ) ) { newShape->shape = point_rgn; if( nParams != 2 ) *status = PARSE_SYNTAX_ERR; nCoords = 2; } else if( !strcasecmp( namePtr, "line" ) ) { newShape->shape = line_rgn; if( nParams != 4 ) *status = PARSE_SYNTAX_ERR; nCoords = 4; } else if( !strcasecmp( namePtr, "polygon" ) ) { newShape->shape = poly_rgn; if( nParams < 6 || (nParams&1) ) *status = PARSE_SYNTAX_ERR; nCoords = nParams; } else { ffpmsg( "Unrecognized region found in region file:" ); ffpmsg( namePtr ); *status = PARSE_SYNTAX_ERR; goto error; } if( *status ) { ffpmsg( "Wrong number of parameters found for region" ); ffpmsg( namePtr ); goto error; } /* Parse Parameter string... convert to pixels if necessary */ if( newShape->shape==poly_rgn ) { newShape->param.poly.Pts = (double *)malloc( nParams * sizeof(double) ); if( !newShape->param.poly.Pts ) { ffpmsg( "Could not allocate memory to hold polygon parameters" ); *status = MEMORY_ALLOCATION; goto error; } newShape->param.poly.nPts = nParams; coords = newShape->param.poly.Pts; } else coords = newShape->param.gen.p; /* Parse the initial "WCS?" coordinates */ for( i=0; iexists ) { ffpmsg("WCS information needed to convert region coordinates."); *status = NO_WCS_KEY; goto error; } if( ffxypx( X, Y, wcs->xrefval, wcs->yrefval, wcs->xrefpix, wcs->yrefpix, wcs->xinc, wcs->yinc, wcs->rot, wcs->type, &x, &y, status ) ) { ffpmsg("Error converting region to pixel coordinates."); goto error; } X = x; Y = y; } coords[i] = X; coords[i+1] = Y; } /* Read in remaining parameters... */ for( ; ixrefval, wcs->yrefval, wcs->xrefpix, wcs->yrefpix, wcs->xinc, wcs->yinc, wcs->rot, wcs->type, &x, &y, status ) ) { ffpmsg("Error converting region to pixel coordinates."); goto error; } coords[i] = sqrt( pow(x-coords[0],2) + pow(y-coords[1],2) ); } else if (endp && *endp=='\'') { /* parameter given in arcmin so convert to pixels. */ /* Increment first Y coordinate by this amount, then calc */ /* the distance in pixels from the original coordinate. */ /* NOTE: This assumes the pixels are square!! */ if (ysave < 0.) Y = ysave + coords[i]/60.; /* don't exceed -90 */ else Y = ysave - coords[i]/60.; /* don't exceed +90 */ X = xsave; if( ffxypx( X, Y, wcs->xrefval, wcs->yrefval, wcs->xrefpix, wcs->yrefpix, wcs->xinc, wcs->yinc, wcs->rot, wcs->type, &x, &y, status ) ) { ffpmsg("Error converting region to pixel coordinates."); goto error; } coords[i] = sqrt( pow(x-coords[0],2) + pow(y-coords[1],2) ); } else if (endp && *endp=='d') { /* parameter given in degrees so convert to pixels. */ /* Increment first Y coordinate by this amount, then calc */ /* the distance in pixels from the original coordinate. */ /* NOTE: This assumes the pixels are square!! */ if (ysave < 0.) Y = ysave + coords[i]; /* don't exceed -90 */ else Y = ysave - coords[i]; /* don't exceed +90 */ X = xsave; if( ffxypx( X, Y, wcs->xrefval, wcs->yrefval, wcs->xrefpix, wcs->yrefpix, wcs->xinc, wcs->yinc, wcs->rot, wcs->type, &x, &y, status ) ) { ffpmsg("Error converting region to pixel coordinates."); goto error; } coords[i] = sqrt( pow(x-coords[0],2) + pow(y-coords[1],2) ); } } /* Perform some useful calculations now to speed up filter later */ /* Also, correct the position angle for any WCS rotation: */ /* If regions are specified in WCS coordintes, then the angles */ /* are relative to the WCS system, not the pixel X,Y system */ switch( newShape->shape ) { case circle_rgn: newShape->param.gen.a = coords[2] * coords[2]; break; case annulus_rgn: newShape->param.gen.a = coords[2] * coords[2]; newShape->param.gen.b = coords[3] * coords[3]; break; case sector_rgn: if( cFmt!=pixel_fmt ) { coords[2] += (wcs->rot); coords[3] += (wcs->rot); } while( coords[2]> 180.0 ) coords[2] -= 360.0; while( coords[2]<=-180.0 ) coords[2] += 360.0; while( coords[3]> 180.0 ) coords[3] -= 360.0; while( coords[3]<=-180.0 ) coords[3] += 360.0; break; case ellipse_rgn: if( cFmt!=pixel_fmt ) { coords[4] += (wcs->rot); } newShape->param.gen.sinT = sin( myPI * (coords[4] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[4] / 180.0) ); break; case elliptannulus_rgn: if( cFmt!=pixel_fmt ) { coords[6] += (wcs->rot); coords[7] += (wcs->rot); } newShape->param.gen.a = sin( myPI * (coords[6] / 180.0) ); newShape->param.gen.b = cos( myPI * (coords[6] / 180.0) ); newShape->param.gen.sinT = sin( myPI * (coords[7] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[7] / 180.0) ); break; case box_rgn: if( cFmt!=pixel_fmt ) { coords[4] += (wcs->rot); } newShape->param.gen.sinT = sin( myPI * (coords[4] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[4] / 180.0) ); break; case rectangle_rgn: if( cFmt!=pixel_fmt ) { coords[4] += (wcs->rot); } newShape->param.gen.sinT = sin( myPI * (coords[4] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[4] / 180.0) ); X = 0.5 * ( coords[2]-coords[0] ); Y = 0.5 * ( coords[3]-coords[1] ); newShape->param.gen.a = fabs( X * newShape->param.gen.cosT + Y * newShape->param.gen.sinT ); newShape->param.gen.b = fabs( Y * newShape->param.gen.cosT - X * newShape->param.gen.sinT ); newShape->param.gen.p[5] = 0.5 * ( coords[2]+coords[0] ); newShape->param.gen.p[6] = 0.5 * ( coords[3]+coords[1] ); break; case diamond_rgn: if( cFmt!=pixel_fmt ) { coords[4] += (wcs->rot); } newShape->param.gen.sinT = sin( myPI * (coords[4] / 180.0) ); newShape->param.gen.cosT = cos( myPI * (coords[4] / 180.0) ); break; case line_rgn: X = coords[2] - coords[0]; Y = coords[3] - coords[1]; R = sqrt( X*X + Y*Y ); newShape->param.gen.sinT = ( R ? Y/R : 0.0 ); newShape->param.gen.cosT = ( R ? X/R : 1.0 ); newShape->param.gen.a = R + 0.5; break; case point_rgn: break; case poly_rgn: /* Find bounding box */ newShape->param.poly.xmin = coords[0]; newShape->param.poly.xmax = coords[0]; newShape->param.poly.ymin = coords[1]; newShape->param.poly.ymax = coords[1]; for( i=2; iparam.poly.xmin > coords[i] ) /* Min X */ newShape->param.poly.xmin = coords[i]; if( newShape->param.poly.xmax < coords[i] ) /* Max X */ newShape->param.poly.xmax = coords[i]; i++; if( newShape->param.poly.ymin > coords[i] ) /* Min Y */ newShape->param.poly.ymin = coords[i]; if( newShape->param.poly.ymax < coords[i] ) /* Max Y */ newShape->param.poly.ymax = coords[i]; i++; } break; } } /* End of while( *currLoc ) */ /* if (coords)printf("%.8f %.8f %.8f %.8f %.8f\n", coords[0],coords[1],coords[2],coords[3],coords[4]); */ } /* End of if...else parse line */ } /* End of while( fgets(rgnFile) ) */ error: if( *status ) fits_free_region( aRgn ); else *Rgn = aRgn; fclose( rgnFile ); free( currLine ); return( *status ); } /*---------------------------------------------------------------------------*/ int fftrgn( double X, double Y, SAORegion *Rgn ) /* Test if the given point is within the region described by Rgn. X and */ /* Y are in pixel coordinates. */ /*---------------------------------------------------------------------------*/ { double x, y, dx, dy, xprime, yprime, r; RgnShape *Shapes; int i; int result = 0; Shapes = Rgn->Shapes; /* if an excluded region is given first, then implicitly */ /* assume a previous shape that includes the entire image. */ if (!Shapes->sign) result = 1; for( i=0; inShapes; i++, Shapes++ ) { /* only need to test if */ /* the point is not already included and this is an include region, */ /* or the point is included and this is an excluded region */ if ( (!result && Shapes->sign) || (result && !Shapes->sign) ) { result = 1; switch( Shapes->shape ) { case box_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; dx = 0.5 * Shapes->param.gen.p[2]; dy = 0.5 * Shapes->param.gen.p[3]; if( (x < -dx) || (x > dx) || (y < -dy) || (y > dy) ) result = 0; break; case rectangle_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[5]; yprime = Y - Shapes->param.gen.p[6]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; dx = Shapes->param.gen.a; dy = Shapes->param.gen.b; if( (x < -dx) || (x > dx) || (y < -dy) || (y > dy) ) result = 0; break; case diamond_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; dx = 0.5 * Shapes->param.gen.p[2]; dy = 0.5 * Shapes->param.gen.p[3]; r = fabs(x/dx) + fabs(y/dy); if( r > 1 ) result = 0; break; case circle_rgn: /* Shift origin to center of region */ x = X - Shapes->param.gen.p[0]; y = Y - Shapes->param.gen.p[1]; r = x*x + y*y; if ( r > Shapes->param.gen.a ) result = 0; break; case annulus_rgn: /* Shift origin to center of region */ x = X - Shapes->param.gen.p[0]; y = Y - Shapes->param.gen.p[1]; r = x*x + y*y; if ( r < Shapes->param.gen.a || r > Shapes->param.gen.b ) result = 0; break; case sector_rgn: /* Shift origin to center of region */ x = X - Shapes->param.gen.p[0]; y = Y - Shapes->param.gen.p[1]; if( x || y ) { r = atan2( y, x ) * 180.0 / myPI; if( Shapes->param.gen.p[2] <= Shapes->param.gen.p[3] ) { if( r < Shapes->param.gen.p[2] || r > Shapes->param.gen.p[3] ) result = 0; } else { if( r < Shapes->param.gen.p[2] && r > Shapes->param.gen.p[3] ) result = 0; } } break; case ellipse_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to region's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; x /= Shapes->param.gen.p[2]; y /= Shapes->param.gen.p[3]; r = x*x + y*y; if( r>1.0 ) result = 0; break; case elliptannulus_rgn: /* Shift origin to center of region */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to outer ellipse's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; x /= Shapes->param.gen.p[4]; y /= Shapes->param.gen.p[5]; r = x*x + y*y; if( r>1.0 ) result = 0; else { /* Repeat test for inner ellipse */ x = xprime * Shapes->param.gen.b + yprime * Shapes->param.gen.a; y = -xprime * Shapes->param.gen.a + yprime * Shapes->param.gen.b; x /= Shapes->param.gen.p[2]; y /= Shapes->param.gen.p[3]; r = x*x + y*y; if( r<1.0 ) result = 0; } break; case line_rgn: /* Shift origin to first point of line */ xprime = X - Shapes->param.gen.p[0]; yprime = Y - Shapes->param.gen.p[1]; /* Rotate point to line's orientation */ x = xprime * Shapes->param.gen.cosT + yprime * Shapes->param.gen.sinT; y = -xprime * Shapes->param.gen.sinT + yprime * Shapes->param.gen.cosT; if( (y < -0.5) || (y >= 0.5) || (x < -0.5) || (x >= Shapes->param.gen.a) ) result = 0; break; case point_rgn: /* Shift origin to center of region */ x = X - Shapes->param.gen.p[0]; y = Y - Shapes->param.gen.p[1]; if ( (x<-0.5) || (x>=0.5) || (y<-0.5) || (y>=0.5) ) result = 0; break; case poly_rgn: if( Xparam.poly.xmin || X>Shapes->param.poly.xmax || Yparam.poly.ymin || Y>Shapes->param.poly.ymax ) result = 0; else result = Pt_in_Poly( X, Y, Shapes->param.poly.nPts, Shapes->param.poly.Pts ); break; } if( !Shapes->sign ) result = !result; } } return( result ); } /*---------------------------------------------------------------------------*/ void fffrgn( SAORegion *Rgn ) /* Free up memory allocated to hold the region data. */ /*---------------------------------------------------------------------------*/ { int i; for( i=0; inShapes; i++ ) if( Rgn->Shapes[i].shape == poly_rgn ) free( Rgn->Shapes[i].param.poly.Pts ); if( Rgn->Shapes ) free( Rgn->Shapes ); free( Rgn ); } /*---------------------------------------------------------------------------*/ static int Pt_in_Poly( double x, double y, int nPts, double *Pts ) /* Internal routine for testing whether the coordinate x,y is within the */ /* polygon region traced out by the array Pts. */ /*---------------------------------------------------------------------------*/ { int i, j, flag=0; double prevX, prevY; double nextX, nextY; double dx, dy, Dy; nextX = Pts[nPts-2]; nextY = Pts[nPts-1]; for( i=0; iprevY && y>=nextY) || (yprevX && x>=nextX) ) continue; /* Check to see if x,y lies right on the segment */ if( x>=prevX || x>nextX ) { dy = y - prevY; Dy = nextY - prevY; if( fabs(Dy)<1e-10 ) { if( fabs(dy)<1e-10 ) return( 1 ); else continue; } dx = prevX + ( (nextX-prevX)/(Dy) ) * dy - x; if( dx < -1e-10 ) continue; if( dx < 1e-10 ) return( 1 ); } /* There is an intersection! Make sure it isn't a V point. */ if( y != prevY ) { flag = 1 - flag; } else { j = i+1; /* Point to Y component */ do { if( j>1 ) j -= 2; else j = nPts-1; } while( y == Pts[j] ); if( (nextY-y)*(y-Pts[j]) > 0 ) flag = 1-flag; } } return( flag ); } indi-0.5/src/cfitsio/drvrmem.c0000644000175000017500000010314510610474374014172 0ustar jrjr/* This file, drvrmem.c, contains driver routines for memory files. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include /* apparently needed to define size_t */ #include "fitsio2.h" #define RECBUFLEN 1000 static char stdin_outfile[FLEN_FILENAME]; typedef struct /* structure containing mem file structure */ { char **memaddrptr; /* Pointer to memory address pointer; */ /* This may or may not point to memaddr. */ char *memaddr; /* Pointer to starting memory address; may */ /* not always be used, so use *memaddrptr instead */ size_t *memsizeptr; /* Pointer to the size of the memory allocation. */ /* This may or may not point to memsize. */ size_t memsize; /* Size of the memory allocation; this may not */ /* always be used, so use *memsizeptr instead. */ size_t deltasize; /* Suggested increment for reallocating memory */ void *(*mem_realloc)(void *p, size_t newsize); /* realloc function */ LONGLONG currentpos; /* current file position, relative to start */ LONGLONG fitsfilesize; /* size of the FITS file (always <= *memsizeptr) */ FILE *fileptr; /* pointer to compressed output disk file */ } memdriver; static memdriver memTable[NMAXFILES]; /* allocate mem file handle tables */ /*--------------------------------------------------------------------------*/ int mem_init(void) { int ii; for (ii = 0; ii < NMAXFILES; ii++) /* initialize all empty slots in table */ { memTable[ii].memaddrptr = 0; memTable[ii].memaddr = 0; } return(0); } /*--------------------------------------------------------------------------*/ int mem_setoptions(int options) { /* do something with the options argument, to stop compiler warning */ options = 0; return(options); } /*--------------------------------------------------------------------------*/ int mem_getoptions(int *options) { *options = 0; return(0); } /*--------------------------------------------------------------------------*/ int mem_getversion(int *version) { *version = 10; return(0); } /*--------------------------------------------------------------------------*/ int mem_shutdown(void) { return(0); } /*--------------------------------------------------------------------------*/ int mem_create(char *filename, int *handle) /* Create a new empty memory file for subsequent writes. The file name is ignored in this case. */ { int status; /* initially allocate 1 FITS block = 2880 bytes */ status = mem_createmem(2880L, handle); if (status) { ffpmsg("failed to create empty memory file (mem_create)"); return(status); } return(0); } /*--------------------------------------------------------------------------*/ int mem_create_comp(char *filename, int *handle) /* Create a new empty memory file for subsequent writes. Also create an empty compressed .gz file. The memory file will be compressed and written to the disk file when the file is closed. */ { FILE *diskfile; char mode[4]; int status; /* first, create disk file for the compressed output */ if ( !strcmp(filename, "-.gz") || !strcmp(filename, "stdout.gz") || !strcmp(filename, "STDOUT.gz") ) { /* special case: create uncompressed FITS file in memory, then compress it an write it out to 'stdout' when it is closed. */ diskfile = stdout; } else { /* normal case: create disk file for the compressed output */ strcpy(mode, "w+b"); /* create file with read-write */ diskfile = fopen(filename, "r"); /* does file already exist? */ if (diskfile) { fclose(diskfile); /* close file and exit with error */ return(FILE_NOT_CREATED); } #if MACHINE == ALPHAVMS || MACHINE == VAXVMS /* specify VMS record structure: fixed format, 2880 byte records */ /* but force stream mode access to enable random I/O access */ diskfile = fopen(filename, mode, "rfm=fix", "mrs=2880", "ctx=stm"); #else diskfile = fopen(filename, mode); #endif if (!(diskfile)) /* couldn't create file */ { return(FILE_NOT_CREATED); } } /* now create temporary memory file */ /* initially allocate 1 FITS block = 2880 bytes */ status = mem_createmem(2880L, handle); if (status) { ffpmsg("failed to create empty memory file (mem_create_comp)"); return(status); } memTable[*handle].fileptr = diskfile; return(0); } /*--------------------------------------------------------------------------*/ int mem_openmem(void **buffptr, /* I - address of memory pointer */ size_t *buffsize, /* I - size of buffer, in bytes */ size_t deltasize, /* I - increment for future realloc's */ void *(*memrealloc)(void *p, size_t newsize), /* function */ int *handle) /* lowest level routine to open a pre-existing memory file. */ { int ii; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in handle table */ { if (memTable[ii].memaddrptr == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ memTable[ii].memaddrptr = (char **) buffptr; /* pointer to start addres */ memTable[ii].memsizeptr = buffsize; /* allocated size of memory */ memTable[ii].deltasize = deltasize; /* suggested realloc increment */ memTable[ii].fitsfilesize = *buffsize; /* size of FITS file (upper limit) */ memTable[ii].currentpos = 0; /* at beginning of the file */ memTable[ii].mem_realloc = memrealloc; /* memory realloc function */ return(0); } /*--------------------------------------------------------------------------*/ int mem_createmem(size_t msize, int *handle) /* lowest level routine to allocate a memory file. */ { int ii; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in handle table */ { if (memTable[ii].memaddrptr == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ /* use the internally allocated memaddr and memsize variables */ memTable[ii].memaddrptr = &memTable[ii].memaddr; memTable[ii].memsizeptr = &memTable[ii].memsize; /* allocate initial block of memory for the file */ if (msize > 0) { memTable[ii].memaddr = (char *) malloc(msize); if ( !(memTable[ii].memaddr) ) { ffpmsg("malloc of initial memory failed (mem_createmem)"); return(FILE_NOT_OPENED); } } /* set initial state of the file */ memTable[ii].memsize = msize; memTable[ii].deltasize = 2880; memTable[ii].fitsfilesize = 0; memTable[ii].currentpos = 0; memTable[ii].mem_realloc = realloc; return(0); } /*--------------------------------------------------------------------------*/ int mem_truncate(int handle, LONGLONG filesize) /* truncate the file to a new size */ { char *ptr; /* call the memory reallocation function, if defined */ if ( memTable[handle].mem_realloc ) { /* explicit LONGLONG->size_t cast */ ptr = (memTable[handle].mem_realloc)( *(memTable[handle].memaddrptr), (size_t) filesize); if (!ptr) { ffpmsg("Failed to reallocate memory (mem_truncate)"); return(MEMORY_ALLOCATION); } /* if allocated more memory, initialize it to zero */ if ( filesize > *(memTable[handle].memsizeptr) ) { memset(ptr + *(memTable[handle].memsizeptr), 0, ((size_t) filesize) - *(memTable[handle].memsizeptr) ); } *(memTable[handle].memaddrptr) = ptr; *(memTable[handle].memsizeptr) = (size_t) (filesize); } memTable[handle].fitsfilesize = filesize; return(0); } /*--------------------------------------------------------------------------*/ int stdin_checkfile(char *urltype, char *infile, char *outfile) /* do any special case checking when opening a file on the stdin stream */ { if (strlen(outfile)) { strcpy(stdin_outfile,outfile); /* an output file is specified */ strcpy(urltype,"stdinfile://"); } else *stdin_outfile = '\0'; /* no output file was specified */ return(0); } /*--------------------------------------------------------------------------*/ int stdin_open(char *filename, int rwmode, int *handle) /* open a FITS file from the stdin file stream by copying it into memory The file name is ignored in this case. */ { int status = 0; char cbuff; if (*stdin_outfile) { /* copy the stdin stream to the specified disk file then open the file */ /* Create the output file */ status = file_create(stdin_outfile,handle); if (status) { ffpmsg("Unable to create output file to copy stdin (stdin_open):"); ffpmsg(stdin_outfile); return(status); } /* copy the whole stdin stream to the file */ status = stdin2file(*handle); file_close(*handle); if (status) { ffpmsg("failed to copy stdin to file (stdin_open)"); ffpmsg(stdin_outfile); return(status); } /* reopen file with proper rwmode attribute */ status = file_open(stdin_outfile, rwmode, handle); } else { /* get the first character, then put it back */ cbuff = fgetc(stdin); ungetc(cbuff, stdin); /* compressed files begin with 037 or 'P' */ if (cbuff == 31 || cbuff == 75) { /* looks like the input stream is compressed */ status = mem_compress_stdin_open(filename, rwmode, handle); } else { /* copy the stdin stream into memory then open file in memory */ if (rwmode != READONLY) { ffpmsg("cannot open stdin with WRITE access"); return(READONLY_FILE); } status = mem_createmem(2880L, handle); if (status) { ffpmsg("failed to create empty memory file (stdin_open)"); return(status); } /* copy the whole stdin stream into memory */ status = stdin2mem(*handle); if (status) { ffpmsg("failed to copy stdin into memory (stdin_open)"); free(memTable[*handle].memaddr); } } } return(status); } /*--------------------------------------------------------------------------*/ int stdin2mem(int hd) /* handle number */ /* Copy the stdin stream into memory. Fill whatever amount of memory has already been allocated, then realloc more memory if necessary. */ { size_t nread, memsize, delta; LONGLONG filesize; char *memptr; char simple[] = "SIMPLE"; int c, ii, jj; memptr = *memTable[hd].memaddrptr; memsize = *memTable[hd].memsizeptr; delta = memTable[hd].deltasize; filesize = 0; ii = 0; for(jj = 0; (c = fgetc(stdin)) != EOF && jj < 2000; jj++) { /* Skip over any garbage at the beginning of the stdin stream by */ /* reading 1 char at a time, looking for 'S', 'I', 'M', 'P', 'L', 'E' */ /* Give up if not found in the first 2000 characters */ if (c == simple[ii]) { ii++; if (ii == 6) /* found the complete string? */ { memcpy(memptr, simple, 6); /* copy "SIMPLE" to buffer */ filesize = 6; break; } } else ii = 0; /* reset search to beginning of the string */ } if (filesize == 0) { ffpmsg("Couldn't find the string 'SIMPLE' in the stdin stream."); ffpmsg("This does not look like a FITS file."); return(FILE_NOT_OPENED); } /* fill up the remainder of the initial memory allocation */ nread = fread(memptr + 6, 1, memsize - 6, stdin); nread += 6; /* add in the 6 characters in 'SIMPLE' */ if (nread < memsize) /* reached the end? */ { memTable[hd].fitsfilesize = nread; return(0); } filesize = nread; while (1) { /* allocate memory for another FITS block */ memptr = realloc(memptr, memsize + delta); if (!memptr) { ffpmsg("realloc failed while copying stdin (stdin2mem)"); return(MEMORY_ALLOCATION); } memsize += delta; /* read another FITS block */ nread = fread(memptr + filesize, 1, delta, stdin); filesize += nread; if (nread < delta) /* reached the end? */ break; } memTable[hd].fitsfilesize = filesize; *memTable[hd].memaddrptr = memptr; *memTable[hd].memsizeptr = memsize; return(0); } /*--------------------------------------------------------------------------*/ int stdin2file(int handle) /* handle number */ /* Copy the stdin stream to a file. . */ { size_t nread = 0; char simple[] = "SIMPLE"; int c, ii, jj, status = 0; char recbuf[RECBUFLEN]; ii = 0; for(jj = 0; (c = fgetc(stdin)) != EOF && jj < 2000; jj++) { /* Skip over any garbage at the beginning of the stdin stream by */ /* reading 1 char at a time, looking for 'S', 'I', 'M', 'P', 'L', 'E' */ /* Give up if not found in the first 2000 characters */ if (c == simple[ii]) { ii++; if (ii == 6) /* found the complete string? */ { memcpy(recbuf, simple, 6); /* copy "SIMPLE" to buffer */ break; } } else ii = 0; /* reset search to beginning of the string */ } if (ii != 6) { ffpmsg("Couldn't find the string 'SIMPLE' in the stdin stream"); return(FILE_NOT_OPENED); } /* fill up the remainder of the buffer */ nread = fread(recbuf + 6, 1, RECBUFLEN - 6, stdin); nread += 6; /* add in the 6 characters in 'SIMPLE' */ status = file_write(handle, recbuf, nread); if (status) return(status); /* copy the rest of stdin stream */ while(0 != (nread = fread(recbuf,1,RECBUFLEN, stdin))) { status = file_write(handle, recbuf, nread); if (status) return(status); } return(status); } /*--------------------------------------------------------------------------*/ int stdout_close(int handle) /* copy the memory file to stdout, then free the memory */ { int status = 0; /* copy from memory to standard out. explicit LONGLONG->size_t cast */ if(fwrite(memTable[handle].memaddr, 1, ((size_t) memTable[handle].fitsfilesize), stdout) != (size_t) memTable[handle].fitsfilesize ) { ffpmsg("failed to copy memory file to stdout (stdout_close)"); status = WRITE_ERROR; } free( memTable[handle].memaddr ); /* free the memory */ memTable[handle].memaddrptr = 0; memTable[handle].memaddr = 0; return(status); } /*--------------------------------------------------------------------------*/ int mem_compress_openrw(char *filename, int rwmode, int *hdl) /* This routine opens the compressed diskfile and creates an empty memory buffer with an appropriate size, then calls mem_uncompress2mem. It allows the memory 'file' to be opened with READWRITE access. */ { return(mem_compress_open(filename, READONLY, hdl)); } /*--------------------------------------------------------------------------*/ int mem_compress_open(char *filename, int rwmode, int *hdl) /* This routine opens the compressed diskfile and creates an empty memory buffer with an appropriate size, then calls mem_uncompress2mem. */ { FILE *diskfile; int status, estimated = 1; unsigned char buffer[4]; size_t finalsize; char *ptr; if (rwmode != READONLY) { ffpmsg( "cannot open compressed file with WRITE access (mem_compress_open)"); ffpmsg(filename); return(READONLY_FILE); } /* open the compressed disk file */ status = file_openfile(filename, READONLY, &diskfile); if (status) { ffpmsg("failed to open compressed disk file (compress_open)"); ffpmsg(filename); return(status); } if (fread(buffer, 1, 2, diskfile) != 2) /* read 2 bytes */ { fclose(diskfile); return(READ_ERROR); } if (memcmp(buffer, "\037\213", 2) == 0) /* GZIP */ { /* the uncompressed file size is give at the end of the file */ fseek(diskfile, 0, 2); /* move to end of file */ fseek(diskfile, -4L, 1); /* move back 4 bytes */ fread(buffer, 1, 4L, diskfile); /* read 4 bytes */ /* have to worry about integer byte order */ finalsize = buffer[0]; finalsize |= buffer[1] << 8; finalsize |= buffer[2] << 16; finalsize |= buffer[3] << 24; estimated = 0; /* file size is known, not estimated */ } else if (memcmp(buffer, "\120\113", 2) == 0) /* PKZIP */ { /* the uncompressed file size is give at byte 22 the file */ fseek(diskfile, 22L, 0); /* move to byte 22 */ fread(buffer, 1, 4L, diskfile); /* read 4 bytes */ /* have to worry about integer byte order */ finalsize = buffer[0]; finalsize |= buffer[1] << 8; finalsize |= buffer[2] << 16; finalsize |= buffer[3] << 24; estimated = 0; /* file size is known, not estimated */ } else if (memcmp(buffer, "\037\036", 2) == 0) /* PACK */ finalsize = 0; /* for most methods we can't determine final size */ else if (memcmp(buffer, "\037\235", 2) == 0) /* LZW */ finalsize = 0; /* for most methods we can't determine final size */ else if (memcmp(buffer, "\037\240", 2) == 0) /* LZH */ finalsize = 0; /* for most methods we can't determine final size */ else { /* not a compressed file; this should never happen */ fclose(diskfile); return(1); } if (finalsize == 0) /* estimate uncompressed file size */ { fseek(diskfile, 0, 2); /* move to end of the compressed file */ finalsize = ftell(diskfile); /* position = size of file */ finalsize = finalsize * 3; /* assume factor of 3 compression */ } fseek(diskfile, 0, 0); /* move back to beginning of file */ /* create a memory file big enough (hopefully) for the uncompressed file */ status = mem_createmem(finalsize, hdl); if (status && estimated) { /* memory allocation failed, so try a smaller estimated size */ finalsize = finalsize / 3; status = mem_createmem(finalsize, hdl); } if (status) { fclose(diskfile); ffpmsg("failed to create empty memory file (compress_open)"); return(status); } /* uncompress file into memory */ status = mem_uncompress2mem(filename, diskfile, *hdl); fclose(diskfile); if (status) { mem_close_free(*hdl); /* free up the memory */ ffpmsg("failed to uncompress file into memory (compress_open)"); return(status); } /* if we allocated too much memory initially, then free it */ if (*(memTable[*hdl].memsizeptr) > (( (size_t) memTable[*hdl].fitsfilesize) + 256L) ) { ptr = realloc(*(memTable[*hdl].memaddrptr), ((size_t) memTable[*hdl].fitsfilesize) ); if (!ptr) { ffpmsg("Failed to reduce size of allocated memory (compress_open)"); return(MEMORY_ALLOCATION); } *(memTable[*hdl].memaddrptr) = ptr; *(memTable[*hdl].memsizeptr) = (size_t) (memTable[*hdl].fitsfilesize); } return(0); } /*--------------------------------------------------------------------------*/ int mem_compress_stdin_open(char *filename, int rwmode, int *hdl) /* This routine reads the compressed input stream and creates an empty memory buffer, then calls mem_uncompress2mem. */ { int status; char *ptr; if (rwmode != READONLY) { ffpmsg( "cannot open compressed input stream with WRITE access (mem_compress_stdin_open)"); return(READONLY_FILE); } /* create a memory file for the uncompressed file */ status = mem_createmem(28800, hdl); if (status) { ffpmsg("failed to create empty memory file (compress_stdin_open)"); return(status); } /* uncompress file into memory */ status = mem_uncompress2mem(filename, stdin, *hdl); if (status) { mem_close_free(*hdl); /* free up the memory */ ffpmsg("failed to uncompress stdin into memory (compress_stdin_open)"); return(status); } /* if we allocated too much memory initially, then free it */ if (*(memTable[*hdl].memsizeptr) > (( (size_t) memTable[*hdl].fitsfilesize) + 256L) ) { ptr = realloc(*(memTable[*hdl].memaddrptr), ((size_t) memTable[*hdl].fitsfilesize) ); if (!ptr) { ffpmsg("Failed to reduce size of allocated memory (compress_stdin_open)"); return(MEMORY_ALLOCATION); } *(memTable[*hdl].memaddrptr) = ptr; *(memTable[*hdl].memsizeptr) = (size_t) (memTable[*hdl].fitsfilesize); } return(0); } /*--------------------------------------------------------------------------*/ int mem_iraf_open(char *filename, int rwmode, int *hdl) /* This routine creates an empty memory buffer, then calls iraf2mem to open the IRAF disk file and convert it to a FITS file in memeory. */ { int status; size_t filesize = 0; /* create a memory file with size = 0 for the FITS converted IRAF file */ status = mem_createmem(filesize, hdl); if (status) { ffpmsg("failed to create empty memory file (mem_iraf_open)"); return(status); } /* convert the iraf file into a FITS file in memory */ status = iraf2mem(filename, memTable[*hdl].memaddrptr, memTable[*hdl].memsizeptr, &filesize, &status); if (status) { mem_close_free(*hdl); /* free up the memory */ ffpmsg("failed to convert IRAF file into memory (mem_iraf_open)"); return(status); } memTable[*hdl].currentpos = 0; /* save starting position */ memTable[*hdl].fitsfilesize=filesize; /* and initial file size */ return(0); } /*--------------------------------------------------------------------------*/ int mem_rawfile_open(char *filename, int rwmode, int *hdl) /* This routine creates an empty memory buffer, writes a minimal image header, then copies the image data from the raw file into memory. It will byteswap the pixel values if the raw array is in little endian byte order. */ { FILE *diskfile; fitsfile *fptr; short *sptr; int status, endian, datatype, bytePerPix, naxis; long dim[5] = {1,1,1,1,1}, ii, nvals, offset = 0; size_t filesize = 0, datasize; char rootfile[FLEN_FILENAME], *cptr = 0, *cptr2 = 0; void *ptr; if (rwmode != READONLY) { ffpmsg( "cannot open raw binary file with WRITE access (mem_rawfile_open)"); ffpmsg(filename); return(READONLY_FILE); } cptr = strchr(filename, '['); /* search for opening bracket [ */ if (!cptr) { ffpmsg("binary file name missing '[' character (mem_rawfile_open)"); ffpmsg(filename); return(URL_PARSE_ERROR); } *rootfile = '\0'; strncat(rootfile, filename, cptr - filename); /* store the rootname */ cptr++; while (*cptr == ' ') cptr++; /* skip leading blanks */ /* Get the Data Type of the Image */ if (*cptr == 'b' || *cptr == 'B') { datatype = BYTE_IMG; bytePerPix = 1; } else if (*cptr == 'i' || *cptr == 'I') { datatype = SHORT_IMG; bytePerPix = 2; } else if (*cptr == 'u' || *cptr == 'U') { datatype = USHORT_IMG; bytePerPix = 2; } else if (*cptr == 'j' || *cptr == 'J') { datatype = LONG_IMG; bytePerPix = 4; } else if (*cptr == 'r' || *cptr == 'R' || *cptr == 'f' || *cptr == 'F') { datatype = FLOAT_IMG; bytePerPix = 4; } else if (*cptr == 'd' || *cptr == 'D') { datatype = DOUBLE_IMG; bytePerPix = 8; } else { ffpmsg("error in raw binary file datatype (mem_rawfile_open)"); ffpmsg(filename); return(URL_PARSE_ERROR); } cptr++; /* get Endian: Big or Little; default is same as the local machine */ if (*cptr == 'b' || *cptr == 'B') { endian = 0; cptr++; } else if (*cptr == 'l' || *cptr == 'L') { endian = 1; cptr++; } else endian = BYTESWAPPED; /* byteswapped machines are little endian */ /* read each dimension (up to 5) */ naxis = 1; dim[0] = strtol(cptr, &cptr2, 10); if (cptr2 && *cptr2 == ',') { naxis = 2; dim[1] = strtol(cptr2+1, &cptr, 10); if (cptr && *cptr == ',') { naxis = 3; dim[2] = strtol(cptr+1, &cptr2, 10); if (cptr2 && *cptr2 == ',') { naxis = 4; dim[3] = strtol(cptr2+1, &cptr, 10); if (cptr && *cptr == ',') naxis = 5; dim[4] = strtol(cptr+1, &cptr2, 10); } } } cptr = maxvalue(cptr, cptr2); if (*cptr == ':') /* read starting offset value */ offset = strtol(cptr+1, 0, 10); nvals = dim[0] * dim[1] * dim[2] * dim[3] * dim[4]; datasize = nvals * bytePerPix; filesize = nvals * bytePerPix + 2880; filesize = ((filesize - 1) / 2880 + 1) * 2880; /* open the raw binary disk file */ status = file_openfile(rootfile, READONLY, &diskfile); if (status) { ffpmsg("failed to open raw binary file (mem_rawfile_open)"); ffpmsg(rootfile); return(status); } /* create a memory file with corrct size for the FITS converted raw file */ status = mem_createmem(filesize, hdl); if (status) { ffpmsg("failed to create memory file (mem_rawfile_open)"); fclose(diskfile); return(status); } /* open this piece of memory as a new FITS file */ ffimem(&fptr, (void **) memTable[*hdl].memaddrptr, &filesize, 0, 0, &status); /* write the required header keywords */ ffcrim(fptr, datatype, naxis, dim, &status); /* close the FITS file, but keep the memory allocated */ ffclos(fptr, &status); if (status > 0) { ffpmsg("failed to write basic image header (mem_rawfile_open)"); fclose(diskfile); mem_close_free(*hdl); /* free up the memory */ return(status); } if (offset > 0) fseek(diskfile, offset, 0); /* offset to start of the data */ /* read the raw data into memory */ ptr = *memTable[*hdl].memaddrptr + 2880; if (fread((char *) ptr, 1, datasize, diskfile) != datasize) status = READ_ERROR; fclose(diskfile); /* close the raw binary disk file */ if (status) { mem_close_free(*hdl); /* free up the memory */ ffpmsg("failed to copy raw file data into memory (mem_rawfile_open)"); return(status); } if (datatype == USHORT_IMG) /* have to subtract 32768 from each unsigned */ { /* value to conform to FITS convention. More */ /* efficient way to do this is to just flip */ /* the most significant bit. */ sptr = (short *) ptr; if (endian == BYTESWAPPED) /* working with native format */ { for (ii = 0; ii < nvals; ii++, sptr++) { *sptr = ( *sptr ) ^ 0x8000; } } else /* pixels are byteswapped WRT the native format */ { for (ii = 0; ii < nvals; ii++, sptr++) { *sptr = ( *sptr ) ^ 0x80; } } } if (endian) /* swap the bytes if array is in little endian byte order */ { if (datatype == SHORT_IMG || datatype == USHORT_IMG) { ffswap2( (short *) ptr, nvals); } else if (datatype == LONG_IMG || datatype == FLOAT_IMG) { ffswap4( (INT32BIT *) ptr, nvals); } else if (datatype == DOUBLE_IMG) { ffswap8( (double *) ptr, nvals); } } memTable[*hdl].currentpos = 0; /* save starting position */ memTable[*hdl].fitsfilesize=filesize; /* and initial file size */ return(0); } /*--------------------------------------------------------------------------*/ int mem_uncompress2mem(char *filename, FILE *diskfile, int hdl) { /* lower level routine to uncompress a file into memory. The file has already been opened and the memory buffer has been allocated. */ size_t finalsize; int status; /* uncompress file into memory */ status = 0; uncompress2mem(filename, diskfile, memTable[hdl].memaddrptr, /* pointer to memory address */ memTable[hdl].memsizeptr, /* pointer to size of memory */ realloc, /* reallocation function */ &finalsize, &status); /* returned file size nd status*/ memTable[hdl].currentpos = 0; /* save starting position */ memTable[hdl].fitsfilesize=finalsize; /* and initial file size */ return status; } /*--------------------------------------------------------------------------*/ int mem_size(int handle, LONGLONG *filesize) /* return the size of the file; only called when the file is first opened */ { *filesize = memTable[handle].fitsfilesize; return(0); } /*--------------------------------------------------------------------------*/ int mem_close_free(int handle) /* close the file and free the memory. */ { free( *(memTable[handle].memaddrptr) ); memTable[handle].memaddrptr = 0; memTable[handle].memaddr = 0; return(0); } /*--------------------------------------------------------------------------*/ int mem_close_keep(int handle) /* close the memory file but do not free the memory. */ { memTable[handle].memaddrptr = 0; memTable[handle].memaddr = 0; return(0); } /*--------------------------------------------------------------------------*/ int mem_close_comp(int handle) /* compress the memory file, writing it out to the fileptr (which might be stdout) */ { int status = 0; size_t compsize; /* compress file in memory to a .gz disk file */ if(compress2file_from_mem(memTable[handle].memaddr, (size_t) (memTable[handle].fitsfilesize), memTable[handle].fileptr, &compsize, &status ) ) { ffpmsg("failed to copy memory file to file (mem_close_comp)"); status = WRITE_ERROR; } free( memTable[handle].memaddr ); /* free the memory */ memTable[handle].memaddrptr = 0; memTable[handle].memaddr = 0; /* close the compressed disk file (except if it is 'stdout' */ if (memTable[handle].fileptr != stdout) fclose(memTable[handle].fileptr); return(status); } /*--------------------------------------------------------------------------*/ int mem_seek(int handle, LONGLONG offset) /* seek to position relative to start of the file. */ { if (offset > memTable[handle].fitsfilesize ) return(END_OF_FILE); memTable[handle].currentpos = offset; return(0); } /*--------------------------------------------------------------------------*/ int mem_read(int hdl, void *buffer, long nbytes) /* read bytes from the current position in the file */ { if (memTable[hdl].currentpos + nbytes > memTable[hdl].fitsfilesize) return(END_OF_FILE); memcpy(buffer, *(memTable[hdl].memaddrptr) + memTable[hdl].currentpos, nbytes); memTable[hdl].currentpos += nbytes; return(0); } /*--------------------------------------------------------------------------*/ int mem_write(int hdl, void *buffer, long nbytes) /* write bytes at the current position in the file */ { size_t newsize; char *ptr; if ((size_t) (memTable[hdl].currentpos + nbytes) > *(memTable[hdl].memsizeptr) ) { if (!(memTable[hdl].mem_realloc)) { ffpmsg("realloc function not defined (mem_write)"); return(WRITE_ERROR); } /* Attempt to reallocate additional memory: the memory buffer size is incremented by the larger of: 1 FITS block (2880 bytes) or the defined 'deltasize' parameter */ newsize = maxvalue( (size_t) (((memTable[hdl].currentpos + nbytes - 1) / 2880) + 1) * 2880, *(memTable[hdl].memsizeptr) + memTable[hdl].deltasize); /* call the realloc function */ ptr = (memTable[hdl].mem_realloc)( *(memTable[hdl].memaddrptr), newsize); if (!ptr) { ffpmsg("Failed to reallocate memory (mem_write)"); return(MEMORY_ALLOCATION); } *(memTable[hdl].memaddrptr) = ptr; *(memTable[hdl].memsizeptr) = newsize; } /* now copy the bytes from the buffer into memory */ memcpy( *(memTable[hdl].memaddrptr) + memTable[hdl].currentpos, buffer, nbytes); memTable[hdl].currentpos += nbytes; memTable[hdl].fitsfilesize = maxvalue(memTable[hdl].fitsfilesize, memTable[hdl].currentpos); return(0); } indi-0.5/src/cfitsio/putcold.c0000644000175000017500000011146310610474375014173 0ustar jrjr/* This file, putcold.c, contains routines that write data elements to */ /* a FITS image or table, with double datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; double nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TDOUBLE, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcld(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values that are written */ double nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; double nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TDOUBLE, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnd(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ double *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dd(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ double *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TDOUBLE, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcld(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcld(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssd(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ double *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TDOUBLE, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcld(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpd( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ double *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcld(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcld( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped, then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise, we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TDOUBLE) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TDOUBLE): if (writeraw) { /* write raw input bytes without conversion */ ffpr8b(fptr, ntodo, incre, &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffr8fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); } break; case (TLONGLONG): ffr8fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffr8fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffr8fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONG): ffr8fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffr8fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffr8fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpcld).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpclm( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of double complex values to a column in the current FITS HDU. Each complex number if interpreted as a pair of float values. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column if necessary, but normally complex values should only be written to a binary table with TFORMn = 'rM' where r is an optional repeat count. The TSCALn and TZERO keywords should not be used with complex numbers because mathmatically the scaling should only be applied to the real (first) component of the complex value. */ { /* simply multiply the number of elements by 2, and call ffpcld */ ffpcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnd( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ double *array, /* I - array of values to write */ double nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ if (abs(tcode) >= TCOMPLEX) { /* treat complex columns as pairs of numbers */ repeat *= 2; } /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcld(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ /* call ffpcluc, not ffpclu, in case we are writing to a complex ('C') binary table column */ if (ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcld(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcld(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fi1(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fi2(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fi4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = (INT32BIT) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fi8(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fr4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fr8(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { memcpy(output, input, ntodo * sizeof(double) ); /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffr8fstr(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } indi-0.5/src/cfitsio/eval_l.c0000644000175000017500000016437110610474374013770 0ustar jrjr/* A lexical scanner generated by flex */ /* Scanner skeleton version: * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ */ #define FLEX_SCANNER #define FF_FLEX_MAJOR_VERSION 2 #define FF_FLEX_MINOR_VERSION 5 #include /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ #ifdef c_plusplus #ifndef __cplusplus #define __cplusplus #endif #endif #ifdef __cplusplus #include #include /* Use prototypes in function declarations. */ #define FF_USE_PROTOS /* The "const" storage-class-modifier is valid. */ #define FF_USE_CONST #else /* ! __cplusplus */ #if __STDC__ #define FF_USE_PROTOS #define FF_USE_CONST #endif /* __STDC__ */ #endif /* ! __cplusplus */ #ifdef __TURBOC__ #pragma warn -rch #pragma warn -use #include #include #define FF_USE_CONST #define FF_USE_PROTOS #endif #ifdef FF_USE_CONST #define ffconst const #else #define ffconst #endif #ifdef FF_USE_PROTOS #define FF_PROTO(proto) proto #else #define FF_PROTO(proto) () #endif /* Returned upon end-of-file. */ #define FF_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define FF_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN ff_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The FFSTATE alias is for lex * compatibility. */ #define FF_START ((ff_start - 1) / 2) #define FFSTATE FF_START /* Action number for EOF rule of a given start state. */ #define FF_STATE_EOF(state) (FF_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define FF_NEW_FILE ffrestart( ffin ) #define FF_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #define FF_BUF_SIZE 16384 typedef struct ff_buffer_state *FF_BUFFER_STATE; extern int ffleng; extern FILE *ffin, *ffout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 /* The funky do-while in the following #define is used to turn the definition * int a single C statement (which needs a semi-colon terminator). This * avoids problems with code like: * * if ( condition_holds ) * ffless( 5 ); * else * do_something_else(); * * Prior to using the do-while the compiler would get upset at the * "else" because it interpreted the "if" statement as being all * done when it reached the ';' after the ffless() call. */ /* Return all but the first 'n' matched characters back to the input stream. */ #define ffless(n) \ do \ { \ /* Undo effects of setting up fftext. */ \ *ff_cp = ff_hold_char; \ FF_RESTORE_FF_MORE_OFFSET \ ff_c_buf_p = ff_cp = ff_bp + n - FF_MORE_ADJ; \ FF_DO_BEFORE_ACTION; /* set up fftext again */ \ } \ while ( 0 ) #define unput(c) ffunput( c, fftext_ptr ) /* The following is because we cannot portably get our hands on size_t * (without autoconf's help, which isn't available because we want * flex-generated scanners to compile on their own). */ typedef unsigned int ff_size_t; struct ff_buffer_state { FILE *ff_input_file; char *ff_ch_buf; /* input buffer */ char *ff_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ ff_size_t ff_buf_size; /* Number of characters read into ff_ch_buf, not including EOB * characters. */ int ff_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int ff_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int ff_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int ff_at_bol; /* Whether to try to fill the input buffer when we reach the * end of it. */ int ff_fill_buffer; int ff_buffer_status; #define FF_BUFFER_NEW 0 #define FF_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as FF_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via ffrestart()), so that the user can continue scanning by * just pointing ffin at a new input file. */ #define FF_BUFFER_EOF_PENDING 2 }; static FF_BUFFER_STATE ff_current_buffer = 0; /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". */ #define FF_CURRENT_BUFFER ff_current_buffer /* ff_hold_char holds the character lost when fftext is formed. */ static char ff_hold_char; static int ff_n_chars; /* number of characters read into ff_ch_buf */ int ffleng; /* Points to current character in buffer. */ static char *ff_c_buf_p = (char *) 0; static int ff_init = 1; /* whether we need to initialize */ static int ff_start = 0; /* start state number */ /* Flag which is used to allow ffwrap()'s to do buffer switches * instead of setting up a fresh ffin. A bit of a hack ... */ static int ff_did_buffer_switch_on_eof; void ffrestart FF_PROTO(( FILE *input_file )); void ff_switch_to_buffer FF_PROTO(( FF_BUFFER_STATE new_buffer )); void ff_load_buffer_state FF_PROTO(( void )); FF_BUFFER_STATE ff_create_buffer FF_PROTO(( FILE *file, int size )); void ff_delete_buffer FF_PROTO(( FF_BUFFER_STATE b )); void ff_init_buffer FF_PROTO(( FF_BUFFER_STATE b, FILE *file )); void ff_flush_buffer FF_PROTO(( FF_BUFFER_STATE b )); #define FF_FLUSH_BUFFER ff_flush_buffer( ff_current_buffer ) FF_BUFFER_STATE ff_scan_buffer FF_PROTO(( char *base, ff_size_t size )); FF_BUFFER_STATE ff_scan_string FF_PROTO(( ffconst char *ff_str )); FF_BUFFER_STATE ff_scan_bytes FF_PROTO(( ffconst char *bytes, int len )); static void *ff_flex_alloc FF_PROTO(( ff_size_t )); static void *ff_flex_realloc FF_PROTO(( void *, ff_size_t )); static void ff_flex_free FF_PROTO(( void * )); #define ff_new_buffer ff_create_buffer #define ff_set_interactive(is_interactive) \ { \ if ( ! ff_current_buffer ) \ ff_current_buffer = ff_create_buffer( ffin, FF_BUF_SIZE ); \ ff_current_buffer->ff_is_interactive = is_interactive; \ } #define ff_set_bol(at_bol) \ { \ if ( ! ff_current_buffer ) \ ff_current_buffer = ff_create_buffer( ffin, FF_BUF_SIZE ); \ ff_current_buffer->ff_at_bol = at_bol; \ } #define FF_AT_BOL() (ff_current_buffer->ff_at_bol) typedef unsigned char FF_CHAR; FILE *ffin = (FILE *) 0, *ffout = (FILE *) 0; typedef int ff_state_type; extern char *fftext; #define fftext_ptr fftext static ff_state_type ff_get_previous_state FF_PROTO(( void )); static ff_state_type ff_try_NUL_trans FF_PROTO(( ff_state_type current_state )); static int ff_get_next_buffer FF_PROTO(( void )); static void ff_fatal_error FF_PROTO(( ffconst char msg[] )); /* Done after the current pattern has been matched and before the * corresponding action - sets up fftext. */ #define FF_DO_BEFORE_ACTION \ fftext_ptr = ff_bp; \ ffleng = (int) (ff_cp - ff_bp); \ ff_hold_char = *ff_cp; \ *ff_cp = '\0'; \ ff_c_buf_p = ff_cp; #define FF_NUM_RULES 26 #define FF_END_OF_BUFFER 27 static ffconst short int ff_accept[160] = { 0, 0, 0, 27, 25, 1, 24, 15, 25, 25, 25, 25, 25, 25, 25, 7, 5, 21, 25, 20, 10, 10, 10, 10, 6, 10, 10, 10, 10, 10, 14, 10, 10, 10, 10, 10, 10, 10, 25, 1, 19, 0, 9, 0, 8, 0, 10, 17, 0, 0, 0, 0, 0, 0, 0, 14, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 5, 0, 23, 18, 22, 10, 10, 10, 2, 10, 10, 10, 4, 10, 10, 10, 10, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 16, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 11, 10, 20, 21, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0 } ; static ffconst int ff_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 5, 6, 7, 1, 8, 9, 10, 11, 12, 13, 1, 13, 14, 1, 15, 15, 16, 16, 16, 16, 16, 16, 17, 17, 1, 1, 18, 19, 20, 1, 1, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 30, 31, 30, 32, 33, 30, 34, 35, 30, 36, 37, 30, 30, 38, 30, 30, 1, 1, 1, 39, 40, 1, 41, 42, 23, 43, 44, 45, 46, 28, 47, 30, 30, 48, 30, 49, 50, 30, 51, 52, 30, 53, 54, 30, 30, 38, 30, 30, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static ffconst int ff_meta[56] = { 0, 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1 } ; static ffconst short int ff_base[167] = { 0, 0, 0, 367, 368, 364, 368, 346, 359, 356, 355, 353, 351, 32, 347, 66, 103, 339, 44, 338, 25, 52, 316, 26, 315, 34, 133, 48, 61, 125, 368, 0, 29, 45, 60, 81, 82, 93, 299, 351, 368, 347, 368, 344, 343, 342, 368, 368, 339, 314, 315, 313, 294, 295, 293, 368, 121, 164, 307, 301, 70, 117, 43, 296, 276, 271, 58, 86, 79, 269, 152, 168, 181, 368, 368, 368, 151, 162, 0, 180, 189, 190, 191, 309, 196, 199, 205, 204, 211, 214, 207, 223, 224, 232, 238, 243, 245, 222, 246, 368, 311, 310, 279, 282, 278, 259, 262, 258, 252, 286, 295, 294, 293, 292, 291, 290, 267, 288, 258, 285, 284, 278, 270, 268, 259, 218, 252, 264, 272, 368, 251, 368, 368, 260, 280, 283, 236, 222, 230, 193, 184, 212, 208, 202, 173, 156, 368, 133, 126, 368, 104, 98, 119, 132, 80, 94, 92, 368, 78, 368, 323, 325, 329, 333, 68, 67, 337 } ; static ffconst short int ff_def[167] = { 0, 159, 1, 159, 159, 159, 159, 159, 160, 161, 162, 159, 163, 159, 159, 159, 159, 159, 159, 159, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 159, 165, 164, 164, 164, 164, 164, 164, 159, 159, 159, 160, 159, 166, 161, 162, 159, 159, 163, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 164, 164, 165, 164, 164, 164, 164, 26, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 159, 166, 166, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 164, 159, 159, 164, 164, 164, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 0, 159, 159, 159, 159, 159, 159, 159 } ; static ffconst short int ff_nxt[424] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 14, 4, 15, 16, 16, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 25, 26, 22, 22, 27, 28, 29, 22, 22, 24, 22, 22, 30, 31, 32, 21, 22, 33, 24, 34, 22, 35, 36, 37, 22, 22, 24, 22, 38, 49, 77, 50, 81, 80, 51, 73, 74, 75, 78, 78, 79, 115, 78, 82, 78, 76, 84, 78, 52, 116, 53, 90, 54, 56, 57, 57, 57, 85, 78, 86, 58, 78, 157, 79, 59, 78, 60, 87, 111, 91, 61, 62, 63, 78, 78, 120, 157, 92, 157, 112, 64, 88, 88, 65, 121, 66, 93, 67, 68, 69, 70, 71, 71, 71, 78, 78, 124, 158, 94, 96, 72, 72, 125, 122, 88, 97, 78, 95, 56, 108, 108, 108, 123, 88, 88, 113, 157, 156, 98, 72, 72, 83, 83, 83, 155, 154, 114, 83, 83, 83, 83, 83, 83, 89, 129, 153, 88, 152, 78, 56, 57, 57, 57, 146, 83, 129, 78, 83, 83, 83, 83, 83, 57, 57, 57, 70, 71, 71, 71, 130, 47, 72, 72, 129, 78, 72, 72, 127, 79, 128, 128, 128, 129, 129, 129, 78, 74, 75, 131, 129, 72, 72, 129, 73, 72, 72, 132, 129, 129, 146, 129, 79, 40, 78, 129, 47, 149, 129, 151, 88, 88, 99, 78, 78, 78, 129, 129, 129, 150, 78, 74, 75, 78, 133, 149, 129, 148, 78, 78, 131, 78, 129, 88, 134, 78, 73, 129, 78, 129, 129, 132, 147, 40, 99, 129, 78, 78, 78, 47, 99, 108, 108, 108, 129, 145, 78, 40, 146, 135, 72, 72, 78, 128, 128, 128, 132, 78, 73, 78, 78, 128, 128, 128, 129, 78, 131, 129, 47, 72, 72, 146, 75, 74, 78, 144, 99, 143, 40, 132, 73, 131, 75, 74, 142, 141, 140, 139, 138, 137, 136, 101, 101, 129, 78, 126, 119, 78, 41, 118, 41, 41, 44, 44, 45, 117, 45, 45, 48, 110, 48, 48, 100, 109, 100, 100, 107, 106, 105, 104, 103, 102, 42, 46, 159, 101, 42, 39, 99, 78, 78, 75, 73, 55, 42, 47, 46, 43, 42, 40, 39, 159, 3, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159 } ; static ffconst short int ff_chk[424] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 20, 13, 25, 23, 13, 18, 18, 18, 20, 23, 21, 62, 32, 25, 165, 164, 27, 25, 13, 62, 13, 32, 13, 15, 15, 15, 15, 27, 33, 28, 15, 27, 158, 21, 15, 21, 15, 28, 60, 33, 15, 15, 15, 34, 28, 66, 156, 34, 155, 60, 15, 37, 37, 15, 66, 15, 34, 15, 15, 15, 16, 16, 16, 16, 35, 36, 68, 154, 35, 36, 16, 16, 68, 67, 37, 36, 37, 35, 56, 56, 56, 56, 67, 29, 29, 61, 153, 152, 37, 16, 16, 26, 26, 26, 151, 150, 61, 26, 26, 26, 26, 26, 26, 29, 76, 148, 29, 147, 29, 70, 70, 70, 70, 145, 26, 77, 26, 26, 26, 26, 26, 26, 57, 57, 57, 71, 71, 71, 71, 77, 144, 57, 57, 79, 76, 71, 71, 72, 79, 72, 72, 72, 80, 81, 82, 77, 80, 81, 82, 84, 57, 57, 85, 84, 71, 71, 85, 87, 86, 143, 90, 79, 86, 79, 88, 142, 141, 89, 140, 88, 88, 89, 80, 81, 82, 97, 91, 92, 139, 84, 91, 92, 85, 87, 138, 93, 137, 87, 86, 93, 90, 94, 88, 90, 88, 94, 95, 89, 96, 98, 95, 136, 96, 98, 130, 97, 91, 92, 130, 126, 108, 108, 108, 133, 125, 93, 124, 133, 97, 108, 108, 94, 127, 127, 127, 123, 95, 122, 96, 98, 128, 128, 128, 134, 130, 121, 135, 134, 108, 108, 135, 120, 119, 133, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 107, 106, 105, 104, 103, 102, 101, 100, 83, 134, 69, 65, 135, 160, 64, 160, 160, 161, 161, 162, 63, 162, 162, 163, 59, 163, 163, 166, 58, 166, 166, 54, 53, 52, 51, 50, 49, 48, 45, 44, 43, 41, 39, 38, 24, 22, 19, 17, 14, 12, 11, 10, 9, 8, 7, 5, 3, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159 } ; static ff_state_type ff_last_accepting_state; static char *ff_last_accepting_cpos; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define ffmore() ffmore_used_but_not_detected #define FF_MORE_ADJ 0 #define FF_RESTORE_FF_MORE_OFFSET char *fftext; #line 1 "eval.l" #define INITIAL 0 #line 2 "eval.l" /************************************************************************/ /* */ /* CFITSIO Lexical Parser */ /* */ /* This file is one of 3 files containing code which parses an */ /* arithmetic expression and evaluates it in the context of an input */ /* FITS file table extension. The CFITSIO lexical parser is divided */ /* into the following 3 parts/files: the CFITSIO "front-end", */ /* eval_f.c, contains the interface between the user/CFITSIO and the */ /* real core of the parser; the FLEX interpreter, eval_l.c, takes the */ /* input string and parses it into tokens and identifies the FITS */ /* information required to evaluate the expression (ie, keywords and */ /* columns); and, the BISON grammar and evaluation routines, eval_y.c, */ /* receives the FLEX output and determines and performs the actual */ /* operations. The files eval_l.c and eval_y.c are produced from */ /* running flex and bison on the files eval.l and eval.y, respectively. */ /* (flex and bison are available from any GNU archive: see www.gnu.org) */ /* */ /* The grammar rules, rather than evaluating the expression in situ, */ /* builds a tree, or Nodal, structure mapping out the order of */ /* operations and expression dependencies. This "compilation" process */ /* allows for much faster processing of multiple rows. This technique */ /* was developed by Uwe Lammers of the XMM Science Analysis System, */ /* although the CFITSIO implementation is entirely code original. */ /* */ /* */ /* Modification History: */ /* */ /* Kent Blackburn c1992 Original parser code developed for the */ /* FTOOLS software package, in particular, */ /* the fselect task. */ /* Kent Blackburn c1995 BIT column support added */ /* Peter D Wilson Feb 1998 Vector column support added */ /* Peter D Wilson May 1998 Ported to CFITSIO library. User */ /* interface routines written, in essence */ /* making fselect, fcalc, and maketime */ /* capabilities available to all tools */ /* via single function calls. */ /* Peter D Wilson Jun 1998 Major rewrite of parser core, so as to */ /* create a run-time evaluation tree, */ /* inspired by the work of Uwe Lammers, */ /* resulting in a speed increase of */ /* 10-100 times. */ /* Peter D Wilson Jul 1998 gtifilter(a,b,c,d) function added */ /* Peter D Wilson Aug 1998 regfilter(a,b,c,d) function added */ /* Peter D Wilson Jul 1999 Make parser fitsfile-independent, */ /* allowing a purely vector-based usage */ /* */ /************************************************************************/ #include #include #include #ifdef sparc #include #else #include #endif #include "eval_defs.h" ParseData gParse; /* Global structure holding all parser information */ /***** Internal functions *****/ int ffGetVariable( char *varName, FFSTYPE *varVal ); static int find_variable( char *varName ); static int expr_read( char *buf, int nbytes ); /***** Definitions *****/ #define FF_NO_UNPUT /* Don't include FFUNPUT function */ #define FF_NEVER_INTERACTIVE 1 #define MAXCHR 256 #define MAXBIT 128 #define OCT_0 "000" #define OCT_1 "001" #define OCT_2 "010" #define OCT_3 "011" #define OCT_4 "100" #define OCT_5 "101" #define OCT_6 "110" #define OCT_7 "111" #define OCT_X "xxx" #define HEX_0 "0000" #define HEX_1 "0001" #define HEX_2 "0010" #define HEX_3 "0011" #define HEX_4 "0100" #define HEX_5 "0101" #define HEX_6 "0110" #define HEX_7 "0111" #define HEX_8 "1000" #define HEX_9 "1001" #define HEX_A "1010" #define HEX_B "1011" #define HEX_C "1100" #define HEX_D "1101" #define HEX_E "1110" #define HEX_F "1111" #define HEX_X "xxxx" /* MJT - 13 June 1996 read from buffer instead of stdin (as per old ftools.skel) */ #undef FF_INPUT #define FF_INPUT(buf,result,max_size) \ if ( (result = expr_read( (char *) buf, max_size )) < 0 ) \ FF_FATAL_ERROR( "read() in flex scanner failed" ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef FF_SKIP_FFWRAP #ifdef __cplusplus extern "C" int ffwrap FF_PROTO(( void )); #else extern int ffwrap FF_PROTO(( void )); #endif #endif #ifndef FF_NO_UNPUT static void ffunput FF_PROTO(( int c, char *buf_ptr )); #endif #ifndef fftext_ptr static void ff_flex_strncpy FF_PROTO(( char *, ffconst char *, int )); #endif #ifdef FF_NEED_STRLEN static int ff_flex_strlen FF_PROTO(( ffconst char * )); #endif #ifndef FF_NO_INPUT #ifdef __cplusplus static int ffinput FF_PROTO(( void )); #else static int input FF_PROTO(( void )); #endif #endif #if FF_STACK_USED static int ff_start_stack_ptr = 0; static int ff_start_stack_depth = 0; static int *ff_start_stack = 0; #ifndef FF_NO_PUSH_STATE static void ff_push_state FF_PROTO(( int new_state )); #endif #ifndef FF_NO_POP_STATE static void ff_pop_state FF_PROTO(( void )); #endif #ifndef FF_NO_TOP_STATE static int ff_top_state FF_PROTO(( void )); #endif #else #define FF_NO_PUSH_STATE 1 #define FF_NO_POP_STATE 1 #define FF_NO_TOP_STATE 1 #endif #ifdef FF_MALLOC_DECL FF_MALLOC_DECL #else #if __STDC__ #ifndef __cplusplus #include #endif #else /* Just try to get by without declaring the routines. This will fail * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) * or sizeof(void*) != sizeof(int). */ #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef FF_READ_BUF_SIZE #define FF_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO (void) fwrite( fftext, ffleng, 1, ffout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or FF_NULL, * is returned in "result". */ #ifndef FF_INPUT #define FF_INPUT(buf,result,max_size) \ if ( ff_current_buffer->ff_is_interactive ) \ { \ int c = '*', n; \ for ( n = 0; n < max_size && \ (c = getc( ffin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( ffin ) ) \ FF_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else if ( ((result = fread( buf, 1, max_size, ffin )) == 0) \ && ferror( ffin ) ) \ FF_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "ffterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef ffterminate #define ffterminate() return FF_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef FF_START_STACK_INCR #define FF_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef FF_FATAL_ERROR #define FF_FATAL_ERROR(msg) ff_fatal_error( msg ) #endif /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef FF_DECL #define FF_DECL int fflex FF_PROTO(( void )) #endif /* Code executed at the beginning of each rule, after fftext and ffleng * have been set up. */ #ifndef FF_USER_ACTION #define FF_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef FF_BREAK #define FF_BREAK break; #endif #define FF_RULE_SETUP \ FF_USER_ACTION FF_DECL { register ff_state_type ff_current_state; register char *ff_cp, *ff_bp; register int ff_act; #line 142 "eval.l" if ( ff_init ) { ff_init = 0; #ifdef FF_USER_INIT FF_USER_INIT; #endif if ( ! ff_start ) ff_start = 1; /* first start state */ if ( ! ffin ) ffin = stdin; if ( ! ffout ) ffout = stdout; if ( ! ff_current_buffer ) ff_current_buffer = ff_create_buffer( ffin, FF_BUF_SIZE ); ff_load_buffer_state(); } while ( 1 ) /* loops until end-of-file is reached */ { ff_cp = ff_c_buf_p; /* Support of fftext. */ *ff_cp = ff_hold_char; /* ff_bp points to the position in ff_ch_buf of the start of * the current run. */ ff_bp = ff_cp; ff_current_state = ff_start; ff_match: do { register FF_CHAR ff_c = ff_ec[FF_SC_TO_UI(*ff_cp)]; if ( ff_accept[ff_current_state] ) { ff_last_accepting_state = ff_current_state; ff_last_accepting_cpos = ff_cp; } while ( ff_chk[ff_base[ff_current_state] + ff_c] != ff_current_state ) { ff_current_state = (int) ff_def[ff_current_state]; if ( ff_current_state >= 160 ) ff_c = ff_meta[(unsigned int) ff_c]; } ff_current_state = ff_nxt[ff_base[ff_current_state] + (unsigned int) ff_c]; ++ff_cp; } while ( ff_base[ff_current_state] != 368 ); ff_find_action: ff_act = ff_accept[ff_current_state]; if ( ff_act == 0 ) { /* have to back up */ ff_cp = ff_last_accepting_cpos; ff_current_state = ff_last_accepting_state; ff_act = ff_accept[ff_current_state]; } FF_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( ff_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of FF_DO_BEFORE_ACTION */ *ff_cp = ff_hold_char; ff_cp = ff_last_accepting_cpos; ff_current_state = ff_last_accepting_state; goto ff_find_action; case 1: FF_RULE_SETUP #line 144 "eval.l" ; FF_BREAK case 2: FF_RULE_SETUP #line 145 "eval.l" { int len; len = strlen(fftext); while (fftext[len] == ' ') len--; len = len - 1; strncpy(fflval.str,&fftext[1],len); fflval.str[len] = '\0'; return( BITSTR ); } FF_BREAK case 3: FF_RULE_SETUP #line 155 "eval.l" { int len; char tmpstring[256]; char bitstring[256]; len = strlen(fftext); while (fftext[len] == ' ') len--; len = len - 1; strncpy(tmpstring,&fftext[1],len); tmpstring[len] = '\0'; bitstring[0] = '\0'; len = 0; while ( tmpstring[len] != '\0') { switch ( tmpstring[len] ) { case '0': strcat(bitstring,OCT_0); break; case '1': strcat(bitstring,OCT_1); break; case '2': strcat(bitstring,OCT_2); break; case '3': strcat(bitstring,OCT_3); break; case '4': strcat(bitstring,OCT_4); break; case '5': strcat(bitstring,OCT_5); break; case '6': strcat(bitstring,OCT_6); break; case '7': strcat(bitstring,OCT_7); break; case 'x': case 'X': strcat(bitstring,OCT_X); break; } len++; } strcpy( fflval.str, bitstring ); return( BITSTR ); } FF_BREAK case 4: FF_RULE_SETUP #line 205 "eval.l" { int len; char tmpstring[256]; char bitstring[256]; len = strlen(fftext); while (fftext[len] == ' ') len--; len = len - 1; strncpy(tmpstring,&fftext[1],len); tmpstring[len] = '\0'; bitstring[0] = '\0'; len = 0; while ( tmpstring[len] != '\0') { switch ( tmpstring[len] ) { case '0': strcat(bitstring,HEX_0); break; case '1': strcat(bitstring,HEX_1); break; case '2': strcat(bitstring,HEX_2); break; case '3': strcat(bitstring,HEX_3); break; case '4': strcat(bitstring,HEX_4); break; case '5': strcat(bitstring,HEX_5); break; case '6': strcat(bitstring,HEX_6); break; case '7': strcat(bitstring,HEX_7); break; case '8': strcat(bitstring,HEX_8); break; case '9': strcat(bitstring,HEX_9); break; case 'a': case 'A': strcat(bitstring,HEX_A); break; case 'b': case 'B': strcat(bitstring,HEX_B); break; case 'c': case 'C': strcat(bitstring,HEX_C); break; case 'd': case 'D': strcat(bitstring,HEX_D); break; case 'e': case 'E': strcat(bitstring,HEX_E); break; case 'f': case 'F': strcat(bitstring,HEX_F); break; case 'x': case 'X': strcat(bitstring,HEX_X); break; } len++; } strcpy( fflval.str, bitstring ); return( BITSTR ); } FF_BREAK case 5: FF_RULE_SETUP #line 286 "eval.l" { fflval.lng = atol(fftext); return( LONG ); } FF_BREAK case 6: FF_RULE_SETUP #line 290 "eval.l" { if ((fftext[0] == 't') || (fftext[0] == 'T')) fflval.log = 1; else fflval.log = 0; return( BOOLEAN ); } FF_BREAK case 7: FF_RULE_SETUP #line 297 "eval.l" { fflval.dbl = atof(fftext); return( DOUBLE ); } FF_BREAK case 8: FF_RULE_SETUP #line 301 "eval.l" { if( !strcasecmp(fftext,"#PI") ) { fflval.dbl = (double)(4) * atan((double)(1)); return( DOUBLE ); } else if( !strcasecmp(fftext,"#E") ) { fflval.dbl = exp((double)(1)); return( DOUBLE ); } else if( !strcasecmp(fftext,"#DEG") ) { fflval.dbl = ((double)4)*atan((double)1)/((double)180); return( DOUBLE ); } else if( !strcasecmp(fftext,"#ROW") ) { return( ROWREF ); } else if( !strcasecmp(fftext,"#NULL") ) { return( NULLREF ); } else if( !strcasecmp(fftext,"#SNULL") ) { return( SNULLREF ); } else { int len; if (fftext[1] == '$') { len = strlen(fftext) - 3; fflval.str[0] = '#'; strncpy(fflval.str+1,&fftext[2],len); fflval.str[len+1] = '\0'; fftext = fflval.str; } return( (*gParse.getData)(fftext, &fflval) ); } } FF_BREAK case 9: FF_RULE_SETUP #line 329 "eval.l" { int len; len = strlen(fftext) - 2; strncpy(fflval.str,&fftext[1],len); fflval.str[len] = '\0'; return( STRING ); } FF_BREAK case 10: FF_RULE_SETUP #line 336 "eval.l" { int len,type; if (fftext[0] == '$') { len = strlen(fftext) - 2; strncpy(fflval.str,&fftext[1],len); fflval.str[len] = '\0'; fftext = fflval.str; } type = ffGetVariable(fftext, &fflval); return( type ); } FF_BREAK case 11: FF_RULE_SETUP #line 348 "eval.l" { char *fname; int len=0; fname = &fflval.str[0]; while( (fname[len]=toupper(fftext[len])) ) len++; if( FSTRCMP(fname,"BOX(")==0 || FSTRCMP(fname,"CIRCLE(")==0 || FSTRCMP(fname,"ELLIPSE(")==0 || FSTRCMP(fname,"NEAR(")==0 || FSTRCMP(fname,"ISNULL(")==0 ) /* Return type is always boolean */ return( BFUNCTION ); else if( FSTRCMP(fname,"GTIFILTER(")==0 ) return( GTIFILTER ); else if( FSTRCMP(fname,"REGFILTER(")==0 ) return( REGFILTER ); else return( FUNCTION ); } FF_BREAK case 12: FF_RULE_SETUP #line 372 "eval.l" { return( INTCAST ); } FF_BREAK case 13: FF_RULE_SETUP #line 373 "eval.l" { return( FLTCAST ); } FF_BREAK case 14: FF_RULE_SETUP #line 374 "eval.l" { return( POWER ); } FF_BREAK case 15: FF_RULE_SETUP #line 375 "eval.l" { return( NOT ); } FF_BREAK case 16: FF_RULE_SETUP #line 376 "eval.l" { return( OR ); } FF_BREAK case 17: FF_RULE_SETUP #line 377 "eval.l" { return( AND ); } FF_BREAK case 18: FF_RULE_SETUP #line 378 "eval.l" { return( EQ ); } FF_BREAK case 19: FF_RULE_SETUP #line 379 "eval.l" { return( NE ); } FF_BREAK case 20: FF_RULE_SETUP #line 380 "eval.l" { return( GT ); } FF_BREAK case 21: FF_RULE_SETUP #line 381 "eval.l" { return( LT ); } FF_BREAK case 22: FF_RULE_SETUP #line 382 "eval.l" { return( GTE ); } FF_BREAK case 23: FF_RULE_SETUP #line 383 "eval.l" { return( LTE ); } FF_BREAK case 24: FF_RULE_SETUP #line 384 "eval.l" { return( '\n' ); } FF_BREAK case 25: FF_RULE_SETUP #line 385 "eval.l" { return( fftext[0] ); } FF_BREAK case 26: FF_RULE_SETUP #line 386 "eval.l" ECHO; FF_BREAK case FF_STATE_EOF(INITIAL): ffterminate(); case FF_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int ff_amount_of_matched_text = (int) (ff_cp - fftext_ptr) - 1; /* Undo the effects of FF_DO_BEFORE_ACTION. */ *ff_cp = ff_hold_char; FF_RESTORE_FF_MORE_OFFSET if ( ff_current_buffer->ff_buffer_status == FF_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed ffin at a new source and called * fflex(). If so, then we have to assure * consistency between ff_current_buffer and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ ff_n_chars = ff_current_buffer->ff_n_chars; ff_current_buffer->ff_input_file = ffin; ff_current_buffer->ff_buffer_status = FF_BUFFER_NORMAL; } /* Note that here we test for ff_c_buf_p "<=" to the position * of the first EOB in the buffer, since ff_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( ff_c_buf_p <= &ff_current_buffer->ff_ch_buf[ff_n_chars] ) { /* This was really a NUL. */ ff_state_type ff_next_state; ff_c_buf_p = fftext_ptr + ff_amount_of_matched_text; ff_current_state = ff_get_previous_state(); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * ff_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ ff_next_state = ff_try_NUL_trans( ff_current_state ); ff_bp = fftext_ptr + FF_MORE_ADJ; if ( ff_next_state ) { /* Consume the NUL. */ ff_cp = ++ff_c_buf_p; ff_current_state = ff_next_state; goto ff_match; } else { ff_cp = ff_c_buf_p; goto ff_find_action; } } else switch ( ff_get_next_buffer() ) { case EOB_ACT_END_OF_FILE: { ff_did_buffer_switch_on_eof = 0; if ( ffwrap() ) { /* Note: because we've taken care in * ff_get_next_buffer() to have set up * fftext, we can now set up * ff_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * FF_NULL, it'll still work - another * FF_NULL will get returned. */ ff_c_buf_p = fftext_ptr + FF_MORE_ADJ; ff_act = FF_STATE_EOF(FF_START); goto do_action; } else { if ( ! ff_did_buffer_switch_on_eof ) FF_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: ff_c_buf_p = fftext_ptr + ff_amount_of_matched_text; ff_current_state = ff_get_previous_state(); ff_cp = ff_c_buf_p; ff_bp = fftext_ptr + FF_MORE_ADJ; goto ff_match; case EOB_ACT_LAST_MATCH: ff_c_buf_p = &ff_current_buffer->ff_ch_buf[ff_n_chars]; ff_current_state = ff_get_previous_state(); ff_cp = ff_c_buf_p; ff_bp = fftext_ptr + FF_MORE_ADJ; goto ff_find_action; } break; } default: FF_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of fflex */ /* ff_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int ff_get_next_buffer() { register char *dest = ff_current_buffer->ff_ch_buf; register char *source = fftext_ptr; register int number_to_move, i; int ret_val; if ( ff_c_buf_p > &ff_current_buffer->ff_ch_buf[ff_n_chars + 1] ) FF_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( ff_current_buffer->ff_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( ff_c_buf_p - fftext_ptr - FF_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (ff_c_buf_p - fftext_ptr) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( ff_current_buffer->ff_buffer_status == FF_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ ff_current_buffer->ff_n_chars = ff_n_chars = 0; else { int num_to_read = ff_current_buffer->ff_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ #ifdef FF_USES_REJECT FF_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); #else /* just a shorter name for the current buffer */ FF_BUFFER_STATE b = ff_current_buffer; int ff_c_buf_p_offset = (int) (ff_c_buf_p - b->ff_ch_buf); if ( b->ff_is_our_buffer ) { int new_size = b->ff_buf_size * 2; if ( new_size <= 0 ) b->ff_buf_size += b->ff_buf_size / 8; else b->ff_buf_size *= 2; b->ff_ch_buf = (char *) /* Include room in for 2 EOB chars. */ ff_flex_realloc( (void *) b->ff_ch_buf, b->ff_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->ff_ch_buf = 0; if ( ! b->ff_ch_buf ) FF_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); ff_c_buf_p = &b->ff_ch_buf[ff_c_buf_p_offset]; num_to_read = ff_current_buffer->ff_buf_size - number_to_move - 1; #endif } if ( num_to_read > FF_READ_BUF_SIZE ) num_to_read = FF_READ_BUF_SIZE; /* Read in more data. */ FF_INPUT( (&ff_current_buffer->ff_ch_buf[number_to_move]), ff_n_chars, num_to_read ); ff_current_buffer->ff_n_chars = ff_n_chars; } if ( ff_n_chars == 0 ) { if ( number_to_move == FF_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; ffrestart( ffin ); } else { ret_val = EOB_ACT_LAST_MATCH; ff_current_buffer->ff_buffer_status = FF_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; ff_n_chars += number_to_move; ff_current_buffer->ff_ch_buf[ff_n_chars] = FF_END_OF_BUFFER_CHAR; ff_current_buffer->ff_ch_buf[ff_n_chars + 1] = FF_END_OF_BUFFER_CHAR; fftext_ptr = &ff_current_buffer->ff_ch_buf[0]; return ret_val; } /* ff_get_previous_state - get the state just before the EOB char was reached */ static ff_state_type ff_get_previous_state() { register ff_state_type ff_current_state; register char *ff_cp; ff_current_state = ff_start; for ( ff_cp = fftext_ptr + FF_MORE_ADJ; ff_cp < ff_c_buf_p; ++ff_cp ) { register FF_CHAR ff_c = (*ff_cp ? ff_ec[FF_SC_TO_UI(*ff_cp)] : 1); if ( ff_accept[ff_current_state] ) { ff_last_accepting_state = ff_current_state; ff_last_accepting_cpos = ff_cp; } while ( ff_chk[ff_base[ff_current_state] + ff_c] != ff_current_state ) { ff_current_state = (int) ff_def[ff_current_state]; if ( ff_current_state >= 160 ) ff_c = ff_meta[(unsigned int) ff_c]; } ff_current_state = ff_nxt[ff_base[ff_current_state] + (unsigned int) ff_c]; } return ff_current_state; } /* ff_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = ff_try_NUL_trans( current_state ); */ #ifdef FF_USE_PROTOS static ff_state_type ff_try_NUL_trans( ff_state_type ff_current_state ) #else static ff_state_type ff_try_NUL_trans( ff_current_state ) ff_state_type ff_current_state; #endif { register int ff_is_jam; register char *ff_cp = ff_c_buf_p; register FF_CHAR ff_c = 1; if ( ff_accept[ff_current_state] ) { ff_last_accepting_state = ff_current_state; ff_last_accepting_cpos = ff_cp; } while ( ff_chk[ff_base[ff_current_state] + ff_c] != ff_current_state ) { ff_current_state = (int) ff_def[ff_current_state]; if ( ff_current_state >= 160 ) ff_c = ff_meta[(unsigned int) ff_c]; } ff_current_state = ff_nxt[ff_base[ff_current_state] + (unsigned int) ff_c]; ff_is_jam = (ff_current_state == 159); return ff_is_jam ? 0 : ff_current_state; } #ifndef FF_NO_UNPUT #ifdef FF_USE_PROTOS static void ffunput( int c, register char *ff_bp ) #else static void ffunput( c, ff_bp ) int c; register char *ff_bp; #endif { register char *ff_cp = ff_c_buf_p; /* undo effects of setting up fftext */ *ff_cp = ff_hold_char; if ( ff_cp < ff_current_buffer->ff_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register int number_to_move = ff_n_chars + 2; register char *dest = &ff_current_buffer->ff_ch_buf[ ff_current_buffer->ff_buf_size + 2]; register char *source = &ff_current_buffer->ff_ch_buf[number_to_move]; while ( source > ff_current_buffer->ff_ch_buf ) *--dest = *--source; ff_cp += (int) (dest - source); ff_bp += (int) (dest - source); ff_current_buffer->ff_n_chars = ff_n_chars = ff_current_buffer->ff_buf_size; if ( ff_cp < ff_current_buffer->ff_ch_buf + 2 ) FF_FATAL_ERROR( "flex scanner push-back overflow" ); } *--ff_cp = (char) c; fftext_ptr = ff_bp; ff_hold_char = *ff_cp; ff_c_buf_p = ff_cp; } #endif /* ifndef FF_NO_UNPUT */ #ifdef __cplusplus static int ffinput() #else static int input() #endif { int c; *ff_c_buf_p = ff_hold_char; if ( *ff_c_buf_p == FF_END_OF_BUFFER_CHAR ) { /* ff_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( ff_c_buf_p < &ff_current_buffer->ff_ch_buf[ff_n_chars] ) /* This was really a NUL. */ *ff_c_buf_p = '\0'; else { /* need more input */ int offset = ff_c_buf_p - fftext_ptr; ++ff_c_buf_p; switch ( ff_get_next_buffer() ) { case EOB_ACT_LAST_MATCH: /* This happens because ff_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ ffrestart( ffin ); /* fall through */ case EOB_ACT_END_OF_FILE: { if ( ffwrap() ) return EOF; if ( ! ff_did_buffer_switch_on_eof ) FF_NEW_FILE; #ifdef __cplusplus return ffinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: ff_c_buf_p = fftext_ptr + offset; break; } } } c = *(unsigned char *) ff_c_buf_p; /* cast for 8-bit char's */ *ff_c_buf_p = '\0'; /* preserve fftext */ ff_hold_char = *++ff_c_buf_p; return c; } #ifdef FF_USE_PROTOS void ffrestart( FILE *input_file ) #else void ffrestart( input_file ) FILE *input_file; #endif { if ( ! ff_current_buffer ) ff_current_buffer = ff_create_buffer( ffin, FF_BUF_SIZE ); ff_init_buffer( ff_current_buffer, input_file ); ff_load_buffer_state(); } #ifdef FF_USE_PROTOS void ff_switch_to_buffer( FF_BUFFER_STATE new_buffer ) #else void ff_switch_to_buffer( new_buffer ) FF_BUFFER_STATE new_buffer; #endif { if ( ff_current_buffer == new_buffer ) return; if ( ff_current_buffer ) { /* Flush out information for old buffer. */ *ff_c_buf_p = ff_hold_char; ff_current_buffer->ff_buf_pos = ff_c_buf_p; ff_current_buffer->ff_n_chars = ff_n_chars; } ff_current_buffer = new_buffer; ff_load_buffer_state(); /* We don't actually know whether we did this switch during * EOF (ffwrap()) processing, but the only time this flag * is looked at is after ffwrap() is called, so it's safe * to go ahead and always set it. */ ff_did_buffer_switch_on_eof = 1; } #ifdef FF_USE_PROTOS void ff_load_buffer_state( void ) #else void ff_load_buffer_state() #endif { ff_n_chars = ff_current_buffer->ff_n_chars; fftext_ptr = ff_c_buf_p = ff_current_buffer->ff_buf_pos; ffin = ff_current_buffer->ff_input_file; ff_hold_char = *ff_c_buf_p; } #ifdef FF_USE_PROTOS FF_BUFFER_STATE ff_create_buffer( FILE *file, int size ) #else FF_BUFFER_STATE ff_create_buffer( file, size ) FILE *file; int size; #endif { FF_BUFFER_STATE b; b = (FF_BUFFER_STATE) ff_flex_alloc( sizeof( struct ff_buffer_state ) ); if ( ! b ) FF_FATAL_ERROR( "out of dynamic memory in ff_create_buffer()" ); b->ff_buf_size = size; /* ff_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->ff_ch_buf = (char *) ff_flex_alloc( b->ff_buf_size + 2 ); if ( ! b->ff_ch_buf ) FF_FATAL_ERROR( "out of dynamic memory in ff_create_buffer()" ); b->ff_is_our_buffer = 1; ff_init_buffer( b, file ); return b; } #ifdef FF_USE_PROTOS void ff_delete_buffer( FF_BUFFER_STATE b ) #else void ff_delete_buffer( b ) FF_BUFFER_STATE b; #endif { if ( ! b ) return; if ( b == ff_current_buffer ) ff_current_buffer = (FF_BUFFER_STATE) 0; if ( b->ff_is_our_buffer ) ff_flex_free( (void *) b->ff_ch_buf ); ff_flex_free( (void *) b ); } #ifndef FF_ALWAYS_INTERACTIVE #ifndef FF_NEVER_INTERACTIVE extern int isatty FF_PROTO(( int )); #endif #endif #ifdef FF_USE_PROTOS void ff_init_buffer( FF_BUFFER_STATE b, FILE *file ) #else void ff_init_buffer( b, file ) FF_BUFFER_STATE b; FILE *file; #endif { ff_flush_buffer( b ); b->ff_input_file = file; b->ff_fill_buffer = 1; #if FF_ALWAYS_INTERACTIVE b->ff_is_interactive = 1; #else #if FF_NEVER_INTERACTIVE b->ff_is_interactive = 0; #else b->ff_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; #endif #endif } #ifdef FF_USE_PROTOS void ff_flush_buffer( FF_BUFFER_STATE b ) #else void ff_flush_buffer( b ) FF_BUFFER_STATE b; #endif { if ( ! b ) return; b->ff_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->ff_ch_buf[0] = FF_END_OF_BUFFER_CHAR; b->ff_ch_buf[1] = FF_END_OF_BUFFER_CHAR; b->ff_buf_pos = &b->ff_ch_buf[0]; b->ff_at_bol = 1; b->ff_buffer_status = FF_BUFFER_NEW; if ( b == ff_current_buffer ) ff_load_buffer_state(); } #ifndef FF_NO_SCAN_BUFFER #ifdef FF_USE_PROTOS FF_BUFFER_STATE ff_scan_buffer( char *base, ff_size_t size ) #else FF_BUFFER_STATE ff_scan_buffer( base, size ) char *base; ff_size_t size; #endif { FF_BUFFER_STATE b; if ( size < 2 || base[size-2] != FF_END_OF_BUFFER_CHAR || base[size-1] != FF_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (FF_BUFFER_STATE) ff_flex_alloc( sizeof( struct ff_buffer_state ) ); if ( ! b ) FF_FATAL_ERROR( "out of dynamic memory in ff_scan_buffer()" ); b->ff_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->ff_buf_pos = b->ff_ch_buf = base; b->ff_is_our_buffer = 0; b->ff_input_file = 0; b->ff_n_chars = b->ff_buf_size; b->ff_is_interactive = 0; b->ff_at_bol = 1; b->ff_fill_buffer = 0; b->ff_buffer_status = FF_BUFFER_NEW; ff_switch_to_buffer( b ); return b; } #endif #ifndef FF_NO_SCAN_STRING #ifdef FF_USE_PROTOS FF_BUFFER_STATE ff_scan_string( ffconst char *ff_str ) #else FF_BUFFER_STATE ff_scan_string( ff_str ) ffconst char *ff_str; #endif { int len; for ( len = 0; ff_str[len]; ++len ) ; return ff_scan_bytes( ff_str, len ); } #endif #ifndef FF_NO_SCAN_BYTES #ifdef FF_USE_PROTOS FF_BUFFER_STATE ff_scan_bytes( ffconst char *bytes, int len ) #else FF_BUFFER_STATE ff_scan_bytes( bytes, len ) ffconst char *bytes; int len; #endif { FF_BUFFER_STATE b; char *buf; ff_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = len + 2; buf = (char *) ff_flex_alloc( n ); if ( ! buf ) FF_FATAL_ERROR( "out of dynamic memory in ff_scan_bytes()" ); for ( i = 0; i < len; ++i ) buf[i] = bytes[i]; buf[len] = buf[len+1] = FF_END_OF_BUFFER_CHAR; b = ff_scan_buffer( buf, n ); if ( ! b ) FF_FATAL_ERROR( "bad buffer in ff_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->ff_is_our_buffer = 1; return b; } #endif #ifndef FF_NO_PUSH_STATE #ifdef FF_USE_PROTOS static void ff_push_state( int new_state ) #else static void ff_push_state( new_state ) int new_state; #endif { if ( ff_start_stack_ptr >= ff_start_stack_depth ) { ff_size_t new_size; ff_start_stack_depth += FF_START_STACK_INCR; new_size = ff_start_stack_depth * sizeof( int ); if ( ! ff_start_stack ) ff_start_stack = (int *) ff_flex_alloc( new_size ); else ff_start_stack = (int *) ff_flex_realloc( (void *) ff_start_stack, new_size ); if ( ! ff_start_stack ) FF_FATAL_ERROR( "out of memory expanding start-condition stack" ); } ff_start_stack[ff_start_stack_ptr++] = FF_START; BEGIN(new_state); } #endif #ifndef FF_NO_POP_STATE static void ff_pop_state() { if ( --ff_start_stack_ptr < 0 ) FF_FATAL_ERROR( "start-condition stack underflow" ); BEGIN(ff_start_stack[ff_start_stack_ptr]); } #endif #ifndef FF_NO_TOP_STATE static int ff_top_state() { return ff_start_stack[ff_start_stack_ptr - 1]; } #endif #ifndef FF_EXIT_FAILURE #define FF_EXIT_FAILURE 2 #endif #ifdef FF_USE_PROTOS static void ff_fatal_error( ffconst char msg[] ) #else static void ff_fatal_error( msg ) char msg[]; #endif { (void) fprintf( stderr, "%s\n", msg ); exit( FF_EXIT_FAILURE ); } /* Redefine ffless() so it works in section 3 code. */ #undef ffless #define ffless(n) \ do \ { \ /* Undo effects of setting up fftext. */ \ fftext[ffleng] = ff_hold_char; \ ff_c_buf_p = fftext + n; \ ff_hold_char = *ff_c_buf_p; \ *ff_c_buf_p = '\0'; \ ffleng = n; \ } \ while ( 0 ) /* Internal utility routines. */ #ifndef fftext_ptr #ifdef FF_USE_PROTOS static void ff_flex_strncpy( char *s1, ffconst char *s2, int n ) #else static void ff_flex_strncpy( s1, s2, n ) char *s1; ffconst char *s2; int n; #endif { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef FF_NEED_STRLEN #ifdef FF_USE_PROTOS static int ff_flex_strlen( ffconst char *s ) #else static int ff_flex_strlen( s ) ffconst char *s; #endif { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif #ifdef FF_USE_PROTOS static void *ff_flex_alloc( ff_size_t size ) #else static void *ff_flex_alloc( size ) ff_size_t size; #endif { return (void *) malloc( size ); } #ifdef FF_USE_PROTOS static void *ff_flex_realloc( void *ptr, ff_size_t size ) #else static void *ff_flex_realloc( ptr, size ) void *ptr; ff_size_t size; #endif { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } #ifdef FF_USE_PROTOS static void ff_flex_free( void *ptr ) #else static void ff_flex_free( ptr ) void *ptr; #endif { free( ptr ); } #if FF_MAIN int main() { fflex(); return 0; } #endif #line 386 "eval.l" int ffwrap() { /* MJT -- 13 June 1996 Supplied for compatibility with pre-2.5.1 versions of flex which do not recognize %option noffwrap */ return(1); } /* expr_read is lifted from old ftools.skel. Now we can use any version of flex with no .skel file necessary! MJT - 13 June 1996 keep a memory of how many bytes have been read previously, so that an unlimited-sized buffer can be supported. PDW - 28 Feb 1998 */ static int expr_read(char *buf, int nbytes) { int n; n = 0; if( !gParse.is_eobuf ) { do { buf[n++] = gParse.expr[gParse.index++]; } while ((nlng = varNum; } return( type ); } static int find_variable(char *varName) { int i; if( gParse.nCols ) for( i=0; i c2) return(1); if (c1 == 0) return(0); s1++; s2++; } } int strncasecmp(const char *s1, const char *s2, size_t n) { char c1, c2; for (; n-- ;) { c1 = toupper( *s1 ); c2 = toupper( *s2 ); if (c1 < c2) return(-1); if (c1 > c2) return(1); if (c1 == 0) return(0); s1++; s2++; } return(0); } #endif indi-0.5/src/cfitsio/Makefile.am0000644000175000017500000000131310605175703014376 0ustar jrjrnoinst_LTLIBRARIES = libcfitsio.la libcfitsio_la_SOURCES = buffers.c cfileio.c checksum.c compress.c drvrfile.c drvrmem.c \ drvrnet.c drvrsmem.c editcol.c edithdu.c eval_l.c eval_y.c \ eval_f.c fitscore.c getcol.c getcolb.c getcold.c getcole.c \ getcoli.c getcolj.c getcolk.c getcoll.c getcols.c getcolsb.c \ getcoluk.c getcolui.c getcoluj.c getkey.c group.c grparser.c \ histo.c iraffits.c \ modkey.c putcol.c putcolb.c putcold.c putcole.c putcoli.c \ putcolj.c putcolk.c putcoluk.c putcoll.c putcols.c putcolsb.c \ putcolu.c putcolui.c putcoluj.c putkey.c region.c scalnull.c \ swapproc.c wcssub.c wcsutil.c imcompress.c quantize.c ricecomp.c \ pliocomp.c fits_hcompress.c fits_hdecompress.c indi-0.5/src/cfitsio/getcoluk.c0000644000175000017500000021722510610474375014341 0ustar jrjr/* This file, getcolk.c, contains routines that read data elements from */ /* a FITS image or table, with 'unsigned int' data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvuk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned int nulval, /* I - value for undefined pixels */ unsigned int *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; unsigned int nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TUINT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluk(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfuk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned int *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TUINT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluk(fptr, 2, row, firstelem, nelem, 1, 2, 0L, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2duk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned int nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3duk(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3duk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned int nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; unsigned int nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TUINT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcluk(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcluk(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned int nulval, /* I - value to set undefined pixels */ unsigned int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; unsigned int nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvuk is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TUINT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvuk: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcluk(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned int *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; long nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TUINT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcluk(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpuk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ unsigned int *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcluk(fptr, 1, row, firstelem, nelem, 1, 1, 0L, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned int nulval, /* I - value for null pixels */ unsigned int *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfuk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned int *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { int dummy = 0; ffgcluk(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcluk( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ unsigned int nulval, /* I - value for null pixels if nultyp = 1 */ unsigned int *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int nulcheck; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* call the 'short' or 'long' version of this routine, if possible */ if (sizeof(int) == sizeof(short)) ffgclui(fptr, colnum, firstrow, firstelem, nelem, elemincre, nultyp, (unsigned short) nulval, (unsigned short *) array, nularray, anynul, status); else if (sizeof(int) == sizeof(long)) ffgcluj(fptr, colnum, firstrow, firstelem, nelem, elemincre, nultyp, (unsigned long) nulval, (unsigned long *) array, nularray, anynul, status); else { /* This is a special case: sizeof(int) is not equal to sizeof(short) or sizeof(long). This occurs on Alpha OSF systems where short = 2 bytes, int = 4 bytes, and long = 8 bytes. */ buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ if (tcode == TLONG) /* Special Case: */ { /* data are 4-bytes long, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) &array[next], status); fffi4uint((INT32BIT *) &array[next], ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8uint( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1uint((unsigned char *) buffer, ntodo, scale, zero,nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2uint((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4uint((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8uint((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstruint((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgcluk).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgcluk).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } } /* end of DEC Alpha special case */ return(*status); } /*--------------------------------------------------------------------------*/ int fffi1uint(unsigned char *input,/* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (unsigned int) input[ii]; /* copy input */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2uint(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4uint(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 2147483648.) { /* Instead of adding 2147483648, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(unsigned int *) &input[ii] ) ^ 0x80000000; } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned int) input[ii]; /* copy to output */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 2147483648.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = ( *(unsigned int *) &input[ii] ) ^ 0x80000000; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8uint(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4uint(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8uint(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (unsigned int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstruint(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ unsigned int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DUINT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUINT_MAX) { *status = OVERFLOW_ERR; output[ii] = UINT_MAX; } else output[ii] = (long) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } indi-0.5/src/cfitsio/group.c0000644000175000017500000052064010610474375013656 0ustar jrjr/* This file, group.c, contains the grouping convention suport routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ /* */ /* The group.c module of CFITSIO was written by Donald G. Jennings of */ /* the INTEGRAL Science Data Centre (ISDC) under NASA contract task */ /* 66002J6. The above copyright laws apply. Copyright guidelines of The */ /* University of Geneva might also apply. */ /* The following routines are designed to create, read, and manipulate */ /* FITS Grouping Tables as defined in the FITS Grouping Convention paper */ /* by Jennings, Pence, Folk and Schlesinger. The development of the */ /* grouping structure was partially funded under the NASA AISRP Program. */ #include "fitsio2.h" #include "group.h" #include #include #include #if defined(WIN32) || defined(__WIN32__) #include /* defines the getcwd function on Windows PCs */ #endif #if defined(unix) || defined(__unix__) || defined(__unix) #include /* needed for getcwd prototype on unix machines */ #endif #define HEX_ESCAPE '%' /*--------------------------------------------------------------------------- Change record: D. Jennings, 18/06/98, version 1.0 of group module delivered to B. Pence for integration into CFITSIO 2.005 D. Jennings, 17/11/98, fixed bug in ffgtcpr(). Now use fits_find_nextkey() correctly and insert auxiliary keyword records directly before the TTYPE1 keyword in the copied group table. D. Jennings, 22/01/99, ffgmop() now looks for relative file paths when the MEMBER_LOCATION information is given in a grouping table. D. Jennings, 01/02/99, ffgtop() now looks for relatve file paths when the GRPLCn keyword value is supplied in the member HDU header. D. Jennings, 01/02/99, ffgtam() now trys to construct relative file paths from the member's file to the group table's file (and visa versa) when both the member's file and group table file are of access type FILE://. D. Jennings, 05/05/99, removed the ffgtcn() function; made obsolete by fits_get_url(). D. Jennings, 05/05/99, updated entire module to handle partial URLs and absolute URLs more robustly. Host dependent directory paths are now converted to true URLs before being read from/written to grouping tables. D. Jennings, 05/05/99, added the following new functions (note, none of these are directly callable by the application) int fits_path2url() int fits_url2path() int fits_get_cwd() int fits_get_url() int fits_clean_url() int fits_relurl2url() int fits_encode_url() int fits_unencode_url() int fits_is_url_absolute() -----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ int ffgtcr(fitsfile *fptr, /* FITS file pointer */ char *grpname, /* name of the grouping table */ int grouptype, /* code specifying the type of grouping table information: GT_ID_ALL_URI 0 ==> defualt (all columns) GT_ID_REF 1 ==> ID by reference GT_ID_POS 2 ==> ID by position GT_ID_ALL 3 ==> ID by ref. and position GT_ID_REF_URI 11 ==> (1) + URI info GT_ID_POS_URI 12 ==> (2) + URI info */ int *status )/* return status code */ /* create a grouping table at the end of the current FITS file. This function makes the last HDU in the file the CHDU, then calls the fits_insert_group() function to actually create the new grouping table. */ { int hdutype; int hdunum; if(*status != 0) return(*status); *status = fits_get_num_hdus(fptr,&hdunum,status); /* If hdunum is 0 then we are at the beginning of the file and we actually haven't closed the first header yet, so don't do anything more */ if (0 != hdunum) { *status = fits_movabs_hdu(fptr,hdunum,&hdutype,status); } /* Now, the whole point of the above two fits_ calls was to get to the end of file. Let's ignore errors at this point and keep going since any error is likely to mean that we are already at the EOF, or the file is fatally corrupted. If we are at the EOF then the next fits_ call will be ok. If it's corrupted then the next call will fail, but that's not big deal at this point. */ if (0 != *status ) *status = 0; *status = fits_insert_group(fptr,grpname,grouptype,status); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtis(fitsfile *fptr, /* FITS file pointer */ char *grpname, /* name of the grouping table */ int grouptype, /* code specifying the type of grouping table information: GT_ID_ALL_URI 0 ==> defualt (all columns) GT_ID_REF 1 ==> ID by reference GT_ID_POS 2 ==> ID by position GT_ID_ALL 3 ==> ID by ref. and position GT_ID_REF_URI 11 ==> (1) + URI info GT_ID_POS_URI 12 ==> (2) + URI info */ int *status) /* return status code */ /* insert a grouping table just after the current HDU of the current FITS file. This is the same as fits_create_group() only it allows the user to select the place within the FITS file to add the grouping table. */ { int tfields = 0; int hdunum = 0; int hdutype = 0; int extver = 0; int i; long pcount = 0; char *ttype[6]; char *tform[6]; char ttypeBuff[102]; char tformBuff[54]; char extname[] = "GROUPING"; char keyword[FLEN_KEYWORD]; char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; do { /* set up the ttype and tform character buffers */ for(i = 0; i < 6; ++i) { ttype[i] = ttypeBuff+(i*17); tform[i] = tformBuff+(i*9); } /* define the columns required according to the grouptype parameter */ *status = ffgtdc(grouptype,0,0,0,0,0,0,ttype,tform,&tfields,status); /* create the grouping table using the columns defined above */ *status = fits_insert_btbl(fptr,0,tfields,ttype,tform,NULL, NULL,pcount,status); if(*status != 0) continue; /* retrieve the hdu position of the new grouping table for future use */ fits_get_hdu_num(fptr,&hdunum); /* add the EXTNAME and EXTVER keywords to the HDU just after the TFIELDS keyword; for now the EXTVER value is set to 0, it will be set to the correct value later on */ fits_read_keyword(fptr,"TFIELDS",keyvalue,comment,status); fits_insert_key_str(fptr,"EXTNAME",extname, "HDU contains a Grouping Table",status); fits_insert_key_lng(fptr,"EXTVER",0,"Grouping Table vers. (this file)", status); /* if the grpname parameter value was defined (Non NULL and non zero length) then add the GRPNAME keyword and value */ if(grpname != NULL && strlen(grpname) > 0) fits_insert_key_str(fptr,"GRPNAME",grpname,"Grouping Table name", status); /* add the TNULL keywords and values for each integer column defined; integer null values are zero (0) for the MEMBER_POSITION and MEMBER_VERSION columns. */ for(i = 0; i < tfields && *status == 0; ++i) { if(strcasecmp(ttype[i],"MEMBER_POSITION") == 0 || strcasecmp(ttype[i],"MEMBER_VERSION") == 0) { sprintf(keyword,"TFORM%d",i+1); *status = fits_read_key_str(fptr,keyword,keyvalue,comment, status); sprintf(keyword,"TNULL%d",i+1); *status = fits_insert_key_lng(fptr,keyword,0,"Column Null Value", status); } } /* determine the correct EXTVER value for the new grouping table by finding the highest numbered grouping table EXTVER value the currently exists */ for(extver = 1; (fits_movnam_hdu(fptr,ANY_HDU,"GROUPING",extver,status)) == 0; ++extver); if(*status == BAD_HDU_NUM) *status = 0; /* move back to the new grouping table HDU and update the EXTVER keyword value */ fits_movabs_hdu(fptr,hdunum,&hdutype,status); fits_modify_key_lng(fptr,"EXTVER",extver,"&",status); }while(0); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtch(fitsfile *gfptr, /* FITS pointer to group */ int grouptype, /* code specifying the type of grouping table information: GT_ID_ALL_URI 0 ==> defualt (all columns) GT_ID_REF 1 ==> ID by reference GT_ID_POS 2 ==> ID by position GT_ID_ALL 3 ==> ID by ref. and position GT_ID_REF_URI 11 ==> (1) + URI info GT_ID_POS_URI 12 ==> (2) + URI info */ int *status) /* return status code */ /* Change the grouping table structure of the grouping table pointed to by gfptr. The grouptype code specifies the new structure of the table. This operation only adds or removes grouping table columns, it does not add or delete group members (i.e., table rows). If the grouping table already has the desired structure then no operations are performed and function simply returns with a (0) success status code. If the requested structure change creates new grouping table columns, then the column values for all existing members will be filled with the appropriate null values. */ { int xtensionCol, extnameCol, extverCol, positionCol, locationCol, uriCol; int ncols = 0; int colnum = 0; int nrows = 0; int grptype = 0; int i,j; long intNull = 0; long tfields = 0; char *tform[6]; char *ttype[6]; unsigned char charNull[1] = {'\0'}; char ttypeBuff[102]; char tformBuff[54]; char keyword[FLEN_KEYWORD]; char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; if(*status != 0) return(*status); do { /* set up the ttype and tform character buffers */ for(i = 0; i < 6; ++i) { ttype[i] = ttypeBuff+(i*17); tform[i] = tformBuff+(i*9); } /* retrieve positions of all Grouping table reserved columns */ *status = ffgtgc(gfptr,&xtensionCol,&extnameCol,&extverCol,&positionCol, &locationCol,&uriCol,&grptype,status); if(*status != 0) continue; /* determine the total number of grouping table columns */ *status = fits_read_key_lng(gfptr,"TFIELDS",&tfields,comment,status); /* define grouping table columns to be added to the configuration */ *status = ffgtdc(grouptype,xtensionCol,extnameCol,extverCol,positionCol, locationCol,uriCol,ttype,tform,&ncols,status); /* delete any grouping tables columns that exist but do not belong to new desired configuration; note that we delete before creating new columns for (file size) efficiency reasons */ switch(grouptype) { case GT_ID_ALL_URI: /* no columns to be deleted in this case */ break; case GT_ID_REF: if(positionCol != 0) { *status = fits_delete_col(gfptr,positionCol,status); --tfields; if(uriCol > positionCol) --uriCol; if(locationCol > positionCol) --locationCol; } if(uriCol != 0) { *status = fits_delete_col(gfptr,uriCol,status); --tfields; if(locationCol > uriCol) --locationCol; } if(locationCol != 0) *status = fits_delete_col(gfptr,locationCol,status); break; case GT_ID_POS: if(xtensionCol != 0) { *status = fits_delete_col(gfptr,xtensionCol,status); --tfields; if(extnameCol > xtensionCol) --extnameCol; if(extverCol > xtensionCol) --extverCol; if(uriCol > xtensionCol) --uriCol; if(locationCol > xtensionCol) --locationCol; } if(extnameCol != 0) { *status = fits_delete_col(gfptr,extnameCol,status); --tfields; if(extverCol > extnameCol) --extverCol; if(uriCol > extnameCol) --uriCol; if(locationCol > extnameCol) --locationCol; } if(extverCol != 0) { *status = fits_delete_col(gfptr,extverCol,status); --tfields; if(uriCol > extverCol) --uriCol; if(locationCol > extverCol) --locationCol; } if(uriCol != 0) { *status = fits_delete_col(gfptr,uriCol,status); --tfields; if(locationCol > uriCol) --locationCol; } if(locationCol != 0) { *status = fits_delete_col(gfptr,locationCol,status); --tfields; } break; case GT_ID_ALL: if(uriCol != 0) { *status = fits_delete_col(gfptr,uriCol,status); --tfields; if(locationCol > uriCol) --locationCol; } if(locationCol != 0) { *status = fits_delete_col(gfptr,locationCol,status); --tfields; } break; case GT_ID_REF_URI: if(positionCol != 0) { *status = fits_delete_col(gfptr,positionCol,status); --tfields; } break; case GT_ID_POS_URI: if(xtensionCol != 0) { *status = fits_delete_col(gfptr,xtensionCol,status); --tfields; if(extnameCol > xtensionCol) --extnameCol; if(extverCol > xtensionCol) --extverCol; } if(extnameCol != 0) { *status = fits_delete_col(gfptr,extnameCol,status); --tfields; if(extverCol > extnameCol) --extverCol; } if(extverCol != 0) { *status = fits_delete_col(gfptr,extverCol,status); --tfields; } break; default: *status = BAD_OPTION; ffpmsg("Invalid value for grouptype parameter specified (ffgtch)"); break; } /* add all the new grouping table columns that were not there previously but are called for by the grouptype parameter */ for(i = 0; i < ncols && *status == 0; ++i) *status = fits_insert_col(gfptr,tfields+i+1,ttype[i],tform[i],status); /* add the TNULL keywords and values for each new integer column defined; integer null values are zero (0) for the MEMBER_POSITION and MEMBER_VERSION columns. Insert a null ("/0") into each new string column defined: MEMBER_XTENSION, MEMBER_NAME, MEMBER_URI_TYPE and MEMBER_LOCATION. Note that by convention a null string is the TNULL value for character fields so no TNULL is required. */ for(i = 0; i < ncols && *status == 0; ++i) { if(strcasecmp(ttype[i],"MEMBER_POSITION") == 0 || strcasecmp(ttype[i],"MEMBER_VERSION") == 0) { /* col contains int data; set TNULL and insert 0 for each col */ *status = fits_get_colnum(gfptr,CASESEN,ttype[i],&colnum, status); sprintf(keyword,"TFORM%d",colnum); *status = fits_read_key_str(gfptr,keyword,keyvalue,comment, status); sprintf(keyword,"TNULL%d",colnum); *status = fits_insert_key_lng(gfptr,keyword,0, "Column Null Value",status); for(j = 1; j <= nrows && *status == 0; ++j) *status = fits_write_col_lng(gfptr,colnum,j,1,1,&intNull, status); } else if(strcasecmp(ttype[i],"MEMBER_XTENSION") == 0 || strcasecmp(ttype[i],"MEMBER_NAME") == 0 || strcasecmp(ttype[i],"MEMBER_URI_TYPE") == 0 || strcasecmp(ttype[i],"MEMBER_LOCATION") == 0) { /* new col contains character data; insert NULLs into each col */ *status = fits_get_colnum(gfptr,CASESEN,ttype[i],&colnum, status); for(j = 1; j <= nrows && *status == 0; ++j) /* WILL THIS WORK FOR VAR LENTH CHAR COLS??????*/ *status = fits_write_col_byt(gfptr,colnum,j,1,1,charNull, status); } } }while(0); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtrm(fitsfile *gfptr, /* FITS file pointer to group */ int rmopt, /* code specifying if member elements are to be deleted: OPT_RM_GPT ==> remove only group table OPT_RM_ALL ==> recursively remove members and their members (if groups) */ int *status) /* return status code */ /* remove a grouping table, and optionally all its members. Any groups containing the grouping table are updated, and all members (if not deleted) have their GRPIDn and GRPLCn keywords updated accordingly. If the (deleted) members are members of another grouping table then those tables are also updated. The CHDU of the FITS file pointed to by gfptr must be positioned to the grouping table to be deleted. */ { int hdutype; long i; long nmembers = 0; HDUtracker HDU; if(*status != 0) return(*status); /* remove the grouping table depending upon the rmopt parameter */ switch(rmopt) { case OPT_RM_GPT: /* for this option, the grouping table is deleted, but the member HDUs remain; in this case we only have to remove each member from the grouping table by calling fits_remove_member() with the OPT_RM_ENTRY option */ /* get the number of members contained by this table */ *status = fits_get_num_members(gfptr,&nmembers,status); /* loop over all grouping table members and remove them */ for(i = nmembers; i > 0 && *status == 0; --i) *status = fits_remove_member(gfptr,i,OPT_RM_ENTRY,status); break; case OPT_RM_ALL: /* for this option the entire Group is deleted -- this includes all members and their members (if grouping tables themselves). Call the recursive form of this function to perform the removal. */ /* add the current grouping table to the HDUtracker struct */ HDU.nHDU = 0; *status = fftsad(gfptr,&HDU,NULL,NULL); /* call the recursive group remove function */ *status = ffgtrmr(gfptr,&HDU,status); /* free the memory allocated to the HDUtracker struct */ for(i = 0; i < HDU.nHDU; ++i) { free(HDU.filename[i]); free(HDU.newFilename[i]); } break; default: *status = BAD_OPTION; ffpmsg("Invalid value for the rmopt parameter specified (ffgtrm)"); break; } /* if all went well then unlink and delete the grouping table HDU */ *status = ffgmul(gfptr,0,status); *status = fits_delete_hdu(gfptr,&hdutype,status); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtcp(fitsfile *infptr, /* input FITS file pointer */ fitsfile *outfptr, /* output FITS file pointer */ int cpopt, /* code specifying copy options: OPT_GCP_GPT (0) ==> copy only grouping table OPT_GCP_ALL (2) ==> recusrively copy members and their members (if groups) */ int *status) /* return status code */ /* copy a grouping table, and optionally all its members, to a new FITS file. If the cpopt is set to OPT_GCP_GPT (copy grouping table only) then the existing members have their GRPIDn and GRPLCn keywords updated to reflect the existance of the new group, since they now belong to another group. If cpopt is set to OPT_GCP_ALL (copy grouping table and members recursively) then the original members are not updated; the new grouping table is modified to include only the copied member HDUs and not the original members. Note that the recursive version of this function, ffgtcpr(), is called to perform the group table copy. In the case of cpopt == OPT_GCP_GPT ffgtcpr() does not actually use recursion. */ { int i; HDUtracker HDU; if(*status != 0) return(*status); /* make sure infptr and outfptr are not the same pointer */ if(infptr == outfptr) *status = IDENTICAL_POINTERS; else { /* initialize the HDUtracker struct */ HDU.nHDU = 0; *status = fftsad(infptr,&HDU,NULL,NULL); /* call the recursive form of this function to copy the grouping table. If the cpopt is OPT_GCP_GPT then there is actually no recursion performed */ *status = ffgtcpr(infptr,outfptr,cpopt,&HDU,status); /* free memory allocated for the HDUtracker struct */ for(i = 0; i < HDU.nHDU; ++i) { free(HDU.filename[i]); free(HDU.newFilename[i]); } } return(*status); } /*---------------------------------------------------------------------------*/ int ffgtmg(fitsfile *infptr, /* FITS file ptr to source grouping table */ fitsfile *outfptr, /* FITS file ptr to target grouping table */ int mgopt, /* code specifying merge options: OPT_MRG_COPY (0) ==> copy members to target group, leaving source group in place OPT_MRG_MOV (1) ==> move members to target group, source group is deleted after merge */ int *status) /* return status code */ /* merge two grouping tables by combining their members into a single table. The source grouping table must be the CHDU of the fitsfile pointed to by infptr, and the target grouping table must be the CHDU of the fitsfile to by outfptr. All members of the source grouping table shall be copied to the target grouping table. If the mgopt parameter is OPT_MRG_COPY then the source grouping table continues to exist after the merge. If the mgopt parameter is OPT_MRG_MOV then the source grouping table is deleted after the merge, and all member HDUs are updated accordingly. */ { long i ; long nmembers = 0; fitsfile *tmpfptr = NULL; if(*status != 0) return(*status); do { *status = fits_get_num_members(infptr,&nmembers,status); for(i = 1; i <= nmembers && *status == 0; ++i) { *status = fits_open_member(infptr,i,&tmpfptr,status); *status = fits_add_group_member(outfptr,tmpfptr,0,status); if(*status == HDU_ALREADY_MEMBER) *status = 0; if(tmpfptr != NULL) { fits_close_file(tmpfptr,status); tmpfptr = NULL; } } if(*status != 0) continue; if(mgopt == OPT_MRG_MOV) *status = fits_remove_group(infptr,OPT_RM_GPT,status); }while(0); if(tmpfptr != NULL) { fits_close_file(tmpfptr,status); } return(*status); } /*---------------------------------------------------------------------------*/ int ffgtcm(fitsfile *gfptr, /* FITS file pointer to grouping table */ int cmopt, /* code specifying compact options OPT_CMT_MBR (1) ==> compact only direct members (if groups) OPT_CMT_MBR_DEL (11) ==> (1) + delete all compacted groups */ int *status) /* return status code */ /* "Compact" a group pointed to by the FITS file pointer gfptr. This is achieved by flattening the tree structure of a group and its (grouping table) members. All members HDUs of a grouping table which is itself a member of the grouping table gfptr are added to gfptr. Optionally, the grouping tables which are "compacted" are deleted. If the grouping table contains no members that are themselves grouping tables then this function performs a NOOP. */ { long i; long nmembers = 0; char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; fitsfile *mfptr = NULL; if(*status != 0) return(*status); do { if(cmopt != OPT_CMT_MBR && cmopt != OPT_CMT_MBR_DEL) { *status = BAD_OPTION; ffpmsg("Invalid value for cmopt parameter specified (ffgtcm)"); continue; } /* reteive the number of grouping table members */ *status = fits_get_num_members(gfptr,&nmembers,status); /* loop over all the grouping table members; if the member is a grouping table then merge its members with the parent grouping table */ for(i = 1; i <= nmembers && *status == 0; ++i) { *status = fits_open_member(gfptr,i,&mfptr,status); if(*status != 0) continue; *status = fits_read_key_str(mfptr,"EXTNAME",keyvalue,comment,status); /* if no EXTNAME keyword then cannot be a grouping table */ if(*status == KEY_NO_EXIST) { *status = 0; continue; } prepare_keyvalue(keyvalue); if(*status != 0) continue; /* if EXTNAME == "GROUPING" then process member as grouping table */ if(strcasecmp(keyvalue,"GROUPING") == 0) { /* merge the member (grouping table) into the grouping table */ *status = fits_merge_groups(mfptr,gfptr,OPT_MRG_COPY,status); *status = fits_close_file(mfptr,status); mfptr = NULL; /* remove the member from the grouping table now that all of its members have been transferred; if cmopt is set to OPT_CMT_MBR_DEL then remove and delete the member */ if(cmopt == OPT_CMT_MBR) *status = fits_remove_member(gfptr,i,OPT_RM_ENTRY,status); else *status = fits_remove_member(gfptr,i,OPT_RM_MBR,status); } else { /* not a grouping table; just close the opened member */ *status = fits_close_file(mfptr,status); mfptr = NULL; } } }while(0); return(*status); } /*--------------------------------------------------------------------------*/ int ffgtvf(fitsfile *gfptr, /* FITS file pointer to group */ long *firstfailed, /* Member ID (if positive) of first failed member HDU verify check or GRPID index (if negitive) of first failed group link verify check. */ int *status) /* return status code */ /* check the integrity of a grouping table to make sure that all group members are accessible and all the links to other grouping tables are valid. The firstfailed parameter returns the member ID of the first member HDU to fail verification if positive or the first group link to fail if negative; otherwise firstfailed contains a return value of 0. */ { long i; long nmembers = 0; long ngroups = 0; char errstr[FLEN_VALUE]; fitsfile *fptr = NULL; if(*status != 0) return(*status); *firstfailed = 0; do { /* attempt to open all the members of the grouping table. We stop at the first member which cannot be opened (which implies that it cannot be located) */ *status = fits_get_num_members(gfptr,&nmembers,status); for(i = 1; i <= nmembers && *status == 0; ++i) { *status = fits_open_member(gfptr,i,&fptr,status); fits_close_file(fptr,status); } /* if the status is non-zero from the above loop then record the member index that caused the error */ if(*status != 0) { *firstfailed = i; sprintf(errstr,"Group table verify failed for member %ld (ffgtvf)", i); ffpmsg(errstr); continue; } /* attempt to open all the groups linked to this grouping table. We stop at the first group which cannot be opened (which implies that it cannot be located) */ *status = fits_get_num_groups(gfptr,&ngroups,status); for(i = 1; i <= ngroups && *status == 0; ++i) { *status = fits_open_group(gfptr,i,&fptr,status); fits_close_file(fptr,status); } /* if the status from the above loop is non-zero, then record the GRPIDn index of the group that caused the failure */ if(*status != 0) { *firstfailed = -1*i; sprintf(errstr, "Group table verify failed for GRPID index %ld (ffgtvf)",i); ffpmsg(errstr); continue; } }while(0); return(*status); } /*---------------------------------------------------------------------------*/ int ffgtop(fitsfile *mfptr, /* FITS file pointer to the member HDU */ int grpid, /* group ID (GRPIDn index) within member HDU */ fitsfile **gfptr, /* FITS file pointer to grouping table HDU */ int *status) /* return status code */ /* open the grouping table that contains the member HDU. The member HDU must be the CHDU of the FITS file pointed to by mfptr, and the grouping table is identified by the Nth index number of the GRPIDn keywords specified in the member HDU's header. The fitsfile gfptr pointer is positioned with the appropriate FITS file with the grouping table as the CHDU. If the group grouping table resides in a file other than the member then an attempt is first made to open the file readwrite, and failing that readonly. Note that it is possible for the GRPIDn/GRPLCn keywords in a member header to be non-continuous, e.g., GRPID1, GRPID2, GRPID5, GRPID6. In such cases, the grpid index value specified in the function call shall identify the (grpid)th GRPID value. In the above example, if grpid == 3, then the group specified by GRPID5 would be opened. */ { int i; int found; long ngroups = 0; long grpExtver = 0; char keyword[FLEN_KEYWORD]; char keyvalue[FLEN_FILENAME]; char *tkeyvalue; char location[FLEN_FILENAME]; char location1[FLEN_FILENAME]; char location2[FLEN_FILENAME]; char comment[FLEN_COMMENT]; char *url[2]; if(*status != 0) return(*status); do { /* set the grouping table pointer to NULL for error checking later */ *gfptr = NULL; /* make sure that the group ID requested is valid ==> cannot be larger than the number of GRPIDn keywords in the member HDU header */ *status = fits_get_num_groups(mfptr,&ngroups,status); if(grpid > ngroups) { *status = BAD_GROUP_ID; sprintf(comment, "GRPID index %d larger total GRPID keywords %ld (ffgtop)", grpid,ngroups); ffpmsg(comment); continue; } /* find the (grpid)th group that the member HDU belongs to and read the value of the GRPID(grpid) keyword; fits_get_num_groups() automatically re-enumerates the GRPIDn/GRPLCn keywords to fill in any gaps */ sprintf(keyword,"GRPID%d",grpid); *status = fits_read_key_lng(mfptr,keyword,&grpExtver,comment,status); if(*status != 0) continue; /* if the value of the GRPIDn keyword is positive then the member is in the same FITS file as the grouping table and we only have to reopen the current FITS file. Else the member and grouping table HDUs reside in different files and another FITS file must be opened as specified by the corresponding GRPLCn keyword The DO WHILE loop only executes once and is used to control the file opening logic. */ do { if(grpExtver > 0) { /* the member resides in the same file as the grouping table, so just reopen the grouping table file */ *status = fits_reopen_file(mfptr,gfptr,status); continue; } else if(grpExtver == 0) { /* a GRPIDn value of zero (0) is undefined */ *status = BAD_GROUP_ID; sprintf(comment,"Invalid value of %ld for GRPID%d (ffgtop)", grpExtver,grpid); ffpmsg(comment); continue; } /* The GRPLCn keyword value is negative, which implies that the grouping table must reside in another FITS file; search for the corresponding GRPLCn keyword */ /* set the grpExtver value positive */ grpExtver = -1*grpExtver; /* read the GRPLCn keyword value */ sprintf(keyword,"GRPLC%d",grpid); /* SPR 1738 */ *status = fits_read_key_longstr(mfptr,keyword,&tkeyvalue,comment, status); if (0 == *status) { strcpy(keyvalue,tkeyvalue); free(tkeyvalue); } /* if the GRPLCn keyword was not found then there is a problem */ if(*status == KEY_NO_EXIST) { *status = BAD_GROUP_ID; sprintf(comment,"Cannot find GRPLC%d keyword (ffgtop)", grpid); ffpmsg(comment); continue; } prepare_keyvalue(keyvalue); /* if the GRPLCn keyword value specifies an absolute URL then try to open the file; we cannot attempt any relative URL or host-dependent file path reconstruction */ if(fits_is_url_absolute(keyvalue)) { ffpmsg("Try to open group table file as absolute URL (ffgtop)"); *status = fits_open_file(gfptr,keyvalue,READWRITE,status); /* if the open was successful then continue */ if(*status == 0) continue; /* if READWRITE failed then try opening it READONLY */ ffpmsg("OK, try open group table file as READONLY (ffgtop)"); *status = 0; *status = fits_open_file(gfptr,keyvalue,READONLY,status); /* continue regardless of the outcome */ continue; } /* see if the URL gives a file path that is absolute on the host machine */ *status = fits_url2path(keyvalue,location1,status); *status = fits_open_file(gfptr,location1,READWRITE,status); /* if the file opened then continue */ if(*status == 0) continue; /* if READWRITE failed then try opening it READONLY */ ffpmsg("OK, try open group table file as READONLY (ffgtop)"); *status = 0; *status = fits_open_file(gfptr,location1,READONLY,status); /* if the file opened then continue */ if(*status == 0) continue; /* the grouping table location given by GRPLCn must specify a relative URL. We assume that this URL is relative to the member HDU's FITS file. Try to construct a full URL location for the grouping table's FITS file and then open it */ *status = 0; /* retrieve the URL information for the member HDU's file */ url[0] = location1; url[1] = location2; *status = fits_get_url(mfptr,url[0],url[1],NULL,NULL,NULL,status); /* It is possible that the member HDU file has an initial URL it was opened with and a real URL that the file actually exists at (e.g., an HTTP accessed file copied to a local file). For each possible URL try to construct a */ for(i = 0, found = 0, *gfptr = NULL; i < 2 && !found; ++i) { /* the url string could be empty */ if(*url[i] == 0) continue; /* create a full URL from the partial and the member HDU file URL */ *status = fits_relurl2url(url[i],keyvalue,location,status); /* if an error occured then contniue */ if(*status != 0) { *status = 0; continue; } /* if the location does not specify an access method then turn it into a host dependent path */ if(! fits_is_url_absolute(location)) { *status = fits_url2path(location,url[i],status); strcpy(location,url[i]); } /* try to open the grouping table file READWRITE */ *status = fits_open_file(gfptr,location,READWRITE,status); if(*status != 0) { /* try to open the grouping table file READONLY */ ffpmsg("opening file as READWRITE failed (ffgtop)"); ffpmsg("OK, try to open file as READONLY (ffgtop)"); *status = 0; *status = fits_open_file(gfptr,location,READONLY,status); } /* either set the found flag or reset the status flag */ if(*status == 0) found = 1; else *status = 0; } }while(0); /* end of file opening loop */ /* if an error occured with the file opening then exit */ if(*status != 0) continue; if(*gfptr == NULL) { ffpmsg("Cannot open or find grouping table FITS file (ffgtop)"); *status = GROUP_NOT_FOUND; continue; } /* search for the grouping table in its FITS file */ *status = fits_movnam_hdu(*gfptr,ANY_HDU,"GROUPING",(int)grpExtver, status); if(*status != 0) *status = GROUP_NOT_FOUND; }while(0); if(*status != 0 && *gfptr != NULL) { fits_close_file(*gfptr,status); *gfptr = NULL; } return(*status); } /*---------------------------------------------------------------------------*/ int ffgtam(fitsfile *gfptr, /* FITS file pointer to grouping table HDU */ fitsfile *mfptr, /* FITS file pointer to member HDU */ int hdupos, /* member HDU position IF in the same file as the grouping table AND mfptr == NULL */ int *status) /* return status code */ /* add a member HDU to an existing grouping table. The fitsfile pointer gfptr must be positioned with the grouping table as the CHDU. The member HDU may either be identifed with the fitsfile *mfptr (which must be positioned to the member HDU) or the hdupos parameter (the HDU number of the member HDU) if both reside in the same FITS file. The hdupos value is only used if the mfptr parameter has a value of NULL (0). The new member HDU shall have the appropriate GRPIDn and GRPLCn keywords created in its header. Note that if the member HDU to be added to the grouping table is already a member of the group then it will not be added a sceond time. */ { int xtensionCol,extnameCol,extverCol,positionCol,locationCol,uriCol; int memberPosition = 0; int grptype = 0; int hdutype = 0; int useLocation = 0; int nkeys = 6; int found; int i; int memberIOstate; int groupIOstate; int iomode; long memberExtver = 0; long groupExtver = 0; long memberID = 0; long nmembers = 0; long ngroups = 0; long grpid = 0; char memberAccess1[FLEN_VALUE]; char memberAccess2[FLEN_VALUE]; char memberFileName[FLEN_FILENAME]; char memberLocation[FLEN_FILENAME]; char grplc[FLEN_FILENAME]; char *tgrplc; char memberHDUtype[FLEN_VALUE]; char memberExtname[FLEN_VALUE]; char memberURI[] = "URL"; char groupAccess1[FLEN_VALUE]; char groupAccess2[FLEN_VALUE]; char groupFileName[FLEN_FILENAME]; char groupLocation[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char *keys[] = {"GRPNAME","EXTVER","EXTNAME","TFIELDS","GCOUNT","EXTEND"}; char *tmpPtr[1]; char keyword[FLEN_KEYWORD]; char card[FLEN_CARD]; unsigned char charNull[] = {'\0'}; fitsfile *tmpfptr = NULL; int parentStatus = 0; if(*status != 0) return(*status); do { /* make sure the grouping table can be modified before proceeding */ fits_file_mode(gfptr,&iomode,status); if(iomode != READWRITE) { ffpmsg("cannot modify grouping table (ffgtam)"); *status = BAD_GROUP_ATTACH; continue; } /* if the calling function supplied the HDU position of the member HDU instead of fitsfile pointer then get a fitsfile pointer */ if(mfptr == NULL) { *status = fits_reopen_file(gfptr,&tmpfptr,status); *status = fits_movabs_hdu(tmpfptr,hdupos,&hdutype,status); if(*status != 0) continue; } else tmpfptr = mfptr; /* determine all the information about the member HDU that will be needed later; note that we establish the default values for all information values that are not explicitly found */ *status = fits_read_key_str(tmpfptr,"XTENSION",memberHDUtype,card, status); if(*status == KEY_NO_EXIST) { strcpy(memberHDUtype,"PRIMARY"); *status = 0; } prepare_keyvalue(memberHDUtype); *status = fits_read_key_lng(tmpfptr,"EXTVER",&memberExtver,card,status); if(*status == KEY_NO_EXIST) { memberExtver = 1; *status = 0; } *status = fits_read_key_str(tmpfptr,"EXTNAME",memberExtname,card, status); if(*status == KEY_NO_EXIST) { memberExtname[0] = 0; *status = 0; } prepare_keyvalue(memberExtname); fits_get_hdu_num(tmpfptr,&memberPosition); /* Determine if the member HDU's FITS file location needs to be taken into account when building its grouping table reference If the member location needs to be used (==> grouping table and member HDU reside in different files) then create an appropriate URL for the member HDU's file and grouping table's file. Note that the logic for this is rather complicated */ /* SPR 3463, don't do this if(tmpfptr->Fptr == gfptr->Fptr) { */ /* member HDU and grouping table reside in the same file, no need to use the location information */ /* printf ("same file\n"); useLocation = 0; memberIOstate = 1; *memberFileName = 0; } else { */ /* the member HDU and grouping table FITS file location information must be used. First determine the correct driver and file name for the group table and member HDU files. If either are disk files then construct an absolute file path for them. Finally, if both are disk files construct relative file paths from the group(member) file to the member(group) file. */ /* set the USELOCATION flag to true */ useLocation = 1; /* get the location, access type and iostate (RO, RW) of the member HDU file */ *status = fits_get_url(tmpfptr,memberFileName,memberLocation, memberAccess1,memberAccess2,&memberIOstate, status); /* if the memberFileName string is empty then use the values of the memberLocation string. This corresponds to a file where the "real" file is a temporary memory file, and we must assume the the application really wants the original file to be the group member */ if(strlen(memberFileName) == 0) { strcpy(memberFileName,memberLocation); strcpy(memberAccess1,memberAccess2); } /* get the location, access type and iostate (RO, RW) of the grouping table file */ *status = fits_get_url(gfptr,groupFileName,groupLocation, groupAccess1,groupAccess2,&groupIOstate, status); if(*status != 0) continue; /* the grouping table file must be writable to continue */ if(groupIOstate == 0) { ffpmsg("cannot modify grouping table (ffgtam)"); *status = BAD_GROUP_ATTACH; continue; } /* determine how to construct the resulting URLs for the member and group files */ if(strcasecmp(groupAccess1,"file://") && strcasecmp(memberAccess1,"file://")) { *cwd = 0; /* nothing to do in this case; both the member and group files must be of an access type that already gives valid URLs; i.e., URLs that we can pass directly to the file drivers */ } else { /* retrieve the Current Working Directory as a Unix-like URL standard string */ *status = fits_get_cwd(cwd,status); /* create full file path for the member HDU FITS file URL if it is of access type file:// */ if(strcasecmp(memberAccess1,"file://") == 0) { if(*memberFileName == '/') { strcpy(memberLocation,memberFileName); } else { strcpy(memberLocation,cwd); strcat(memberLocation,"/"); strcat(memberLocation,memberFileName); } *status = fits_clean_url(memberLocation,memberFileName, status); } /* create full file path for the grouping table HDU FITS file URL if it is of access type file:// */ if(strcasecmp(groupAccess1,"file://") == 0) { if(*groupFileName == '/') { strcpy(groupLocation,groupFileName); } else { strcpy(groupLocation,cwd); strcat(groupLocation,"/"); strcat(groupLocation,groupFileName); } *status = fits_clean_url(groupLocation,groupFileName,status); } /* if both the member and group files are disk files then create a relative path (relative URL) strings with respect to the grouping table's file and the grouping table's file with respect to the member HDU's file */ if(strcasecmp(groupAccess1,"file://") == 0 && strcasecmp(memberAccess1,"file://") == 0) { fits_url2relurl(memberFileName,groupFileName, groupLocation,status); fits_url2relurl(groupFileName,memberFileName, memberLocation,status); /* copy the resulting partial URL strings to the memberFileName and groupFileName variables for latter use in the function */ strcpy(memberFileName,memberLocation); strcpy(groupFileName,groupLocation); } } /* beo done */ /* } */ /* retrieve the grouping table's EXTVER value */ *status = fits_read_key_lng(gfptr,"EXTVER",&groupExtver,card,status); /* if useLocation is true then make the group EXTVER value negative for the subsequent GRPIDn/GRPLCn matching */ /* SPR 3463 change test */ if(tmpfptr->Fptr != gfptr->Fptr) groupExtver = -1*groupExtver; /* retrieve the number of group members */ *status = fits_get_num_members(gfptr,&nmembers,status); do { /* make sure the member HDU is not already an entry in the grouping table before adding it */ *status = ffgmf(gfptr,memberHDUtype,memberExtname,memberExtver, memberPosition,memberFileName,&memberID,status); if(*status == MEMBER_NOT_FOUND) *status = 0; else if(*status == 0) { parentStatus = HDU_ALREADY_MEMBER; ffpmsg("Specified HDU is already a member of the Grouping table (ffgtam)"); continue; } else continue; /* if the member HDU is not already recorded in the grouping table then add it */ /* add a new row to the grouping table */ *status = fits_insert_rows(gfptr,nmembers,1,status); ++nmembers; /* retrieve the grouping table column IDs and structure type */ *status = ffgtgc(gfptr,&xtensionCol,&extnameCol,&extverCol,&positionCol, &locationCol,&uriCol,&grptype,status); /* fill in the member HDU data in the new grouping table row */ *tmpPtr = memberHDUtype; if(xtensionCol != 0) fits_write_col_str(gfptr,xtensionCol,nmembers,1,1,tmpPtr,status); *tmpPtr = memberExtname; if(extnameCol != 0) { if(strlen(memberExtname) != 0) fits_write_col_str(gfptr,extnameCol,nmembers,1,1,tmpPtr,status); else /* WILL THIS WORK FOR VAR LENTH CHAR COLS??????*/ fits_write_col_byt(gfptr,extnameCol,nmembers,1,1,charNull,status); } if(extverCol != 0) fits_write_col_lng(gfptr,extverCol,nmembers,1,1,&memberExtver, status); if(positionCol != 0) fits_write_col_int(gfptr,positionCol,nmembers,1,1, &memberPosition,status); *tmpPtr = memberFileName; if(locationCol != 0) { /* Change the test for SPR 3463 */ if(tmpfptr->Fptr != gfptr->Fptr) fits_write_col_str(gfptr,locationCol,nmembers,1,1,tmpPtr,status); else /* WILL THIS WORK FOR VAR LENTH CHAR COLS??????*/ fits_write_col_byt(gfptr,locationCol,nmembers,1,1,charNull,status); } *tmpPtr = memberURI; if(uriCol != 0) { /* Change the test for SPR 3463 */ if(tmpfptr->Fptr != gfptr->Fptr) fits_write_col_str(gfptr,uriCol,nmembers,1,1,tmpPtr,status); else /* WILL THIS WORK FOR VAR LENTH CHAR COLS??????*/ fits_write_col_byt(gfptr,uriCol,nmembers,1,1,charNull,status); } } while(0); if(0 != *status) continue; /* add GRPIDn/GRPLCn keywords to the member HDU header to link it to the grouing table if the they do not already exist and the member file is RW */ fits_file_mode(tmpfptr,&iomode,status); if(memberIOstate == 0 || iomode != READWRITE) { ffpmsg("cannot add GRPID/LC keywords to member HDU: (ffgtam)"); ffpmsg(memberFileName); continue; } *status = fits_get_num_groups(tmpfptr,&ngroups,status); /* look for the GRPID/LC keywords in the member HDU; if the keywords for the back-link to the grouping table already exist then no need to add them again */ for(i = 1, found = 0; i <= ngroups && !found && *status == 0; ++i) { sprintf(keyword,"GRPID%d",(int)ngroups); *status = fits_read_key_lng(tmpfptr,keyword,&grpid,card,status); if(grpid == groupExtver) { if(grpid < 0) { /* have to make sure the GRPLCn keyword matches too */ sprintf(keyword,"GRPLC%d",(int)ngroups); /* SPR 1738 */ *status = fits_read_key_longstr(mfptr,keyword,&tgrplc,card, status); if (0 == *status) { strcpy(grplc,tgrplc); free(tgrplc); } /* always compare files using absolute paths the presence of a non-empty cwd indicates that the file names may require conversion to absolute paths */ if(0 < strlen(cwd)) { /* temp buffer for use in assembling abs. path(s) */ char tmp[FLEN_FILENAME]; /* make grplc absolute if necessary */ if(!fits_is_url_absolute(grplc)) { fits_path2url(grplc,groupLocation,status); if(groupLocation[0] != '/') { strcpy(tmp, cwd); strcat(tmp,"/"); strcat(tmp,groupLocation); fits_clean_url(tmp,grplc,status); } } /* make groupFileName absolute if necessary */ if(!fits_is_url_absolute(groupFileName)) { fits_path2url(groupFileName,groupLocation,status); if(groupLocation[0] != '/') { strcpy(tmp, cwd); strcat(tmp,"/"); strcat(tmp,groupLocation); /* note: use groupLocation (which is not used below this block), to store the absolute file name instead of using groupFileName. The latter may be needed unaltered if the GRPLC is written below */ fits_clean_url(tmp,groupLocation,status); } } } /* see if the grplc value and the group file name match */ if(strcmp(grplc,groupLocation) == 0) found = 1; } else { /* the match is found with GRPIDn alone */ found = 1; } } } /* if FOUND is true then no need to continue */ if(found) { ffpmsg("HDU already has GRPID/LC keywords for group table (ffgtam)"); continue; } /* add the GRPID/LC keywords to the member header for this grouping table If NGROUPS == 0 then we must position the header pointer to the record where we want to insert the GRPID/LC keywords (the pointer is already correctly positioned if the above search loop activiated) */ if(ngroups == 0) { /* no GRPIDn/GRPLCn keywords currently exist in header so try to position the header pointer to a desirable position */ for(i = 0, *status = KEY_NO_EXIST; i < nkeys && *status == KEY_NO_EXIST; ++i) { *status = 0; *status = fits_read_card(tmpfptr,keys[i],card,status); } /* all else fails: move write pointer to end of header */ if(*status == KEY_NO_EXIST) { *status = 0; fits_get_hdrspace(tmpfptr,&nkeys,&i,status); ffgrec(tmpfptr,nkeys,card,status); } /* any other error status then abort */ if(*status != 0) continue; } /* now that the header pointer is positioned for the GRPID/LC keyword insertion increment the number of group links counter for the member HDU */ ++ngroups; /* if the member HDU and grouping table reside in the same FITS file then there is no need to add a GRPLCn keyword */ /* SPR 3463 change test */ if(tmpfptr->Fptr == gfptr->Fptr) { /* add the GRPIDn keyword only */ sprintf(keyword,"GRPID%d",(int)ngroups); fits_insert_key_lng(tmpfptr,keyword,groupExtver, "EXTVER of Group containing this HDU",status); } else { /* add the GRPIDn and GRPLCn keywords */ sprintf(keyword,"GRPID%d",(int)ngroups); fits_insert_key_lng(tmpfptr,keyword,groupExtver, "EXTVER of Group containing this HDU",status); sprintf(keyword,"GRPLC%d",(int)ngroups); /* SPR 1738 */ fits_insert_key_longstr(tmpfptr,keyword,groupFileName, "URL of file containing Group",status); fits_write_key_longwarn(tmpfptr,status); } }while(0); /* close the tmpfptr pointer if it was opened in this function */ if(mfptr == NULL) { *status = fits_close_file(tmpfptr,status); } *status = 0 == *status ? parentStatus : *status; return(*status); } /*---------------------------------------------------------------------------*/ int ffgtnm(fitsfile *gfptr, /* FITS file pointer to grouping table */ long *nmembers, /* member count of the groping table */ int *status) /* return status code */ /* return the number of member HDUs in a grouping table. The fitsfile pointer gfptr must be positioned with the grouping table as the CHDU. The number of grouping table member HDUs is just the NAXIS2 value of the grouping table. */ { char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; if(*status != 0) return(*status); *status = fits_read_keyword(gfptr,"EXTNAME",keyvalue,comment,status); if(*status == KEY_NO_EXIST) *status = NOT_GROUP_TABLE; else { prepare_keyvalue(keyvalue); if(strcasecmp(keyvalue,"GROUPING") != 0) { *status = NOT_GROUP_TABLE; ffpmsg("Specified HDU is not a Grouping table (ffgtnm)"); } *status = fits_read_key_lng(gfptr,"NAXIS2",nmembers,comment,status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgmng(fitsfile *mfptr, /* FITS file pointer to member HDU */ long *ngroups, /* total number of groups linked to HDU */ int *status) /* return status code */ /* return the number of groups to which a HDU belongs, as defined by the number of GRPIDn/GRPLCn keyword records that appear in the HDU header. The fitsfile pointer mfptr must be positioned with the member HDU as the CHDU. Each time this function is called, the indicies of the GRPIDn/GRPLCn keywords are checked to make sure they are continuous (ie no gaps) and are re-enumerated to eliminate gaps if gaps are found to be present. */ { int offset; int index; int newIndex; int i; long grpid; char *inclist[] = {"GRPID#"}; char keyword[FLEN_KEYWORD]; char newKeyword[FLEN_KEYWORD]; char card[FLEN_CARD]; char comment[FLEN_COMMENT]; char *tkeyvalue; if(*status != 0) return(*status); *ngroups = 0; /* reset the member HDU keyword counter to the beginning */ *status = ffgrec(mfptr,0,card,status); /* search for the number of GRPIDn keywords in the member HDU header and count them with the ngroups variable */ while(*status == 0) { /* read the next GRPIDn keyword in the series */ *status = fits_find_nextkey(mfptr,inclist,1,NULL,0,card,status); if(*status != 0) continue; ++(*ngroups); } if(*status == KEY_NO_EXIST) *status = 0; /* read each GRPIDn/GRPLCn keyword and adjust their index values so that there are no gaps in the index count */ for(index = 1, offset = 0, i = 1; i <= *ngroups && *status == 0; ++index) { sprintf(keyword,"GRPID%d",index); /* try to read the next GRPIDn keyword in the series */ *status = fits_read_key_lng(mfptr,keyword,&grpid,card,status); /* if not found then increment the offset counter and continue */ if(*status == KEY_NO_EXIST) { *status = 0; ++offset; } else { /* increment the number_keys_found counter and see if the index of the keyword needs to be updated */ ++i; if(offset > 0) { /* compute the new index for the GRPIDn/GRPLCn keywords */ newIndex = index - offset; /* update the GRPIDn keyword index */ sprintf(newKeyword,"GRPID%d",newIndex); fits_modify_name(mfptr,keyword,newKeyword,status); /* If present, update the GRPLCn keyword index */ sprintf(keyword,"GRPLC%d",index); sprintf(newKeyword,"GRPLC%d",newIndex); /* SPR 1738 */ *status = fits_read_key_longstr(mfptr,keyword,&tkeyvalue,comment, status); if (0 == *status) { fits_delete_key(mfptr,keyword,status); fits_insert_key_longstr(mfptr,newKeyword,tkeyvalue,comment,status); fits_write_key_longwarn(mfptr,status); free(tkeyvalue); } if(*status == KEY_NO_EXIST) *status = 0; } } } return(*status); } /*---------------------------------------------------------------------------*/ int ffgmop(fitsfile *gfptr, /* FITS file pointer to grouping table */ long member, /* member ID (row num) within grouping table */ fitsfile **mfptr, /* FITS file pointer to member HDU */ int *status) /* return status code */ /* open a grouping table member, returning a pointer to the member's FITS file with the CHDU set to the member HDU. The grouping table must be the CHDU of the FITS file pointed to by gfptr. The member to open is identified by its row number within the grouping table (first row/member == 1). If the member resides in a FITS file different from the grouping table the member file is first opened readwrite and if this fails then it is opened readonly. For access type of FILE:// the member file is searched for assuming (1) an absolute path is given, (2) a path relative to the CWD is given, and (3) a path relative to the grouping table file but not relative to the CWD is given. If all of these fail then the error FILE_NOT_FOUND is returned. */ { int xtensionCol,extnameCol,extverCol,positionCol,locationCol,uriCol; int grptype,hdutype; int dummy; long hdupos = 0; long extver = 0; char xtension[FLEN_VALUE]; char extname[FLEN_VALUE]; char uri[FLEN_VALUE]; char grpLocation1[FLEN_FILENAME]; char grpLocation2[FLEN_FILENAME]; char mbrLocation1[FLEN_FILENAME]; char mbrLocation2[FLEN_FILENAME]; char mbrLocation3[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char card[FLEN_CARD]; char nstr[] = {'\0'}; char *tmpPtr[1]; if(*status != 0) return(*status); do { /* retrieve the Grouping Convention reserved column positions within the grouping table */ *status = ffgtgc(gfptr,&xtensionCol,&extnameCol,&extverCol,&positionCol, &locationCol,&uriCol,&grptype,status); if(*status != 0) continue; /* extract the member information from grouping table */ tmpPtr[0] = xtension; if(xtensionCol != 0) { *status = fits_read_col_str(gfptr,xtensionCol,member,1,1,nstr, tmpPtr,&dummy,status); /* convert the xtension string to a hdutype code */ if(strcasecmp(xtension,"PRIMARY") == 0) hdutype = IMAGE_HDU; else if(strcasecmp(xtension,"IMAGE") == 0) hdutype = IMAGE_HDU; else if(strcasecmp(xtension,"TABLE") == 0) hdutype = ASCII_TBL; else if(strcasecmp(xtension,"BINTABLE") == 0) hdutype = BINARY_TBL; else hdutype = ANY_HDU; } tmpPtr[0] = extname; if(extnameCol != 0) *status = fits_read_col_str(gfptr,extnameCol,member,1,1,nstr, tmpPtr,&dummy,status); if(extverCol != 0) *status = fits_read_col_lng(gfptr,extverCol,member,1,1,0, (long*)&extver,&dummy,status); if(positionCol != 0) *status = fits_read_col_lng(gfptr,positionCol,member,1,1,0, (long*)&hdupos,&dummy,status); tmpPtr[0] = mbrLocation1; if(locationCol != 0) *status = fits_read_col_str(gfptr,locationCol,member,1,1,nstr, tmpPtr,&dummy,status); tmpPtr[0] = uri; if(uriCol != 0) *status = fits_read_col_str(gfptr,uriCol,member,1,1,nstr, tmpPtr,&dummy,status); if(*status != 0) continue; /* decide what FITS file the member HDU resides in and open the file using the fitsfile* pointer mfptr; note that this logic is rather complicated and is based primiarly upon if a URL specifier is given for the member file in the grouping table */ switch(grptype) { case GT_ID_POS: case GT_ID_REF: case GT_ID_ALL: /* no location information is given so we must assume that the member HDU resides in the same FITS file as the grouping table; if the grouping table was incorrectly constructed then this assumption will be false, but there is nothing to be done about it at this point */ *status = fits_reopen_file(gfptr,mfptr,status); break; case GT_ID_REF_URI: case GT_ID_POS_URI: case GT_ID_ALL_URI: /* The member location column exists. Determine if the member resides in the same file as the grouping table or in a separate file; open the member file in either case */ if(strlen(mbrLocation1) == 0) { /* since no location information was given we must assume that the member is in the same FITS file as the grouping table */ *status = fits_reopen_file(gfptr,mfptr,status); } else { /* make sure the location specifiation is "URL"; we cannot decode any other URI types at this time */ if(strcasecmp(uri,"URL") != 0) { *status = FILE_NOT_OPENED; sprintf(card, "Cannot open member HDU file with URI type %s (ffgmop)", uri); ffpmsg(card); continue; } /* The location string for the member is not NULL, so it does not necessially reside in the same FITS file as the grouping table. Three cases are attempted for opening the member's file in the following order: 1. The URL given for the member's file is absolute (i.e., access method supplied); try to open the member 2. The URL given for the member's file is not absolute but is an absolute file path; try to open the member as a file after the file path is converted to a host-dependent form 3. The URL given for the member's file is not absolute and is given as a relative path to the location of the grouping table's file. Create an absolute URL using the grouping table's file URL and try to open the member. If all three cases fail then an error is returned. In each case the file is first opened in read/write mode and failing that readonly mode. The following DO loop is only used as a mechanism to break (continue) when the proper file opening method is found */ do { /* CASE 1: See if the member URL is absolute (i.e., includes a access directive) and if so open the file */ if(fits_is_url_absolute(mbrLocation1)) { /* the URL must specify an access method, which implies that its an absolute reference regardless of the access method, pass the whole URL to the open function for processing */ ffpmsg("member URL is absolute, try open R/W (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation1,READWRITE, status); if(*status == 0) continue; *status = 0; /* now try to open file using full URL specs in readonly mode */ ffpmsg("OK, now try to open read-only (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation1,READONLY, status); /* break from DO loop regardless of status */ continue; } /* CASE 2: If we got this far then the member URL location has no access type ==> FILE:// Try to open the member file using the URL as is, i.e., assume that it is given as absolute, if it starts with a '/' character */ ffpmsg("Member URL is of type FILE (ffgmop)"); if(*mbrLocation1 == '/') { ffpmsg("Member URL specifies abs file path (ffgmop)"); /* convert the URL path to a host dependent path */ *status = fits_url2path(mbrLocation1,mbrLocation2, status); ffpmsg("Try to open member URL in R/W mode (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation2,READWRITE, status); if(*status == 0) continue; *status = 0; /* now try to open file using the URL as an absolute path in readonly mode */ ffpmsg("OK, now try to open read-only (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation2,READONLY, status); /* break from the Do loop regardless of the status */ continue; } /* CASE 3: If we got this far then the URL does not specify an absoulte file path or URL with access method. Since the path to the group table's file is (obviously) valid for the CWD, create a full location string for the member HDU using the grouping table URL as a basis The only problem is that the grouping table file might have two URLs, the original one used to open it and the one that points to the real file being accessed (i.e., a file accessed via HTTP but transferred to a local disk file). Have to attempt to build a URL to the member HDU file using both of these URLs if defined. */ ffpmsg("Try to open member file as relative URL (ffgmop)"); /* get the URL information for the grouping table file */ *status = fits_get_url(gfptr,grpLocation1,grpLocation2, NULL,NULL,NULL,status); /* if the "real" grouping table file URL is defined then build a full url for the member HDU file using it and try to open the member HDU file */ if(*grpLocation1) { /* make sure the group location is absolute */ if(! fits_is_url_absolute(grpLocation1) && *grpLocation1 != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,grpLocation1); strcpy(grpLocation1,cwd); } /* create a full URL for the member HDU file */ *status = fits_relurl2url(grpLocation1,mbrLocation1, mbrLocation2,status); if(*status != 0) continue; /* if the URL does not have an access method given then translate it into a host dependent file path */ if(! fits_is_url_absolute(mbrLocation2)) { *status = fits_url2path(mbrLocation2,mbrLocation3, status); strcpy(mbrLocation2,mbrLocation3); } /* try to open the member file READWRITE */ *status = fits_open_file(mfptr,mbrLocation2,READWRITE, status); if(*status == 0) continue; *status = 0; /* now try to open in readonly mode */ ffpmsg("now try to open file as READONLY (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation2,READONLY, status); if(*status == 0) continue; *status = 0; } /* if we got this far then either the "real" grouping table file URL was not defined or all attempts to open the resulting member HDU file URL failed. if the "original" grouping table file URL is defined then build a full url for the member HDU file using it and try to open the member HDU file */ if(*grpLocation2) { /* make sure the group location is absolute */ if(! fits_is_url_absolute(grpLocation2) && *grpLocation2 != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,grpLocation2); strcpy(grpLocation2,cwd); } /* create an absolute URL for the member HDU file */ *status = fits_relurl2url(grpLocation2,mbrLocation1, mbrLocation2,status); if(*status != 0) continue; /* if the URL does not have an access method given then translate it into a host dependent file path */ if(! fits_is_url_absolute(mbrLocation2)) { *status = fits_url2path(mbrLocation2,mbrLocation3, status); strcpy(mbrLocation2,mbrLocation3); } /* try to open the member file READWRITE */ *status = fits_open_file(mfptr,mbrLocation2,READWRITE, status); if(*status == 0) continue; *status = 0; /* now try to open in readonly mode */ ffpmsg("now try to open file as READONLY (ffgmop)"); *status = fits_open_file(mfptr,mbrLocation2,READONLY, status); if(*status == 0) continue; *status = 0; } /* if we got this far then the member HDU file could not be opened using any method. Log the error. */ ffpmsg("Cannot open member HDU FITS file (ffgmop)"); *status = MEMBER_NOT_FOUND; }while(0); } break; default: /* no default action */ break; } if(*status != 0) continue; /* attempt to locate the member HDU within its FITS file as determined and opened above */ switch(grptype) { case GT_ID_POS: case GT_ID_POS_URI: /* try to find the member hdu in the the FITS file pointed to by mfptr based upon its HDU posistion value. Note that is impossible to verify if the HDU is actually the correct HDU due to a lack of information. */ *status = fits_movabs_hdu(*mfptr,(int)hdupos,&hdutype,status); break; case GT_ID_REF: case GT_ID_REF_URI: /* try to find the member hdu in the FITS file pointed to by mfptr based upon its XTENSION, EXTNAME and EXTVER keyword values */ *status = fits_movnam_hdu(*mfptr,hdutype,extname,extver,status); if(*status == BAD_HDU_NUM) { *status = MEMBER_NOT_FOUND; ffpmsg("Cannot find specified member HDU (ffgmop)"); } /* if the above function returned without error then the mfptr is pointed to the member HDU */ break; case GT_ID_ALL: case GT_ID_ALL_URI: /* if the member entry has reference information then use it (ID by reference is safer than ID by position) else use the position information */ if(strlen(xtension) > 0 && strlen(extname) > 0 && extver > 0) { /* valid reference info exists so use it */ /* try to find the member hdu in the grouping table's file */ *status = fits_movnam_hdu(*mfptr,hdutype,extname,extver,status); if(*status == BAD_HDU_NUM) { *status = MEMBER_NOT_FOUND; ffpmsg("Cannot find specified member HDU (ffgmop)"); } } else { *status = fits_movabs_hdu(*mfptr,(int)hdupos,&hdutype, status); if(*status == END_OF_FILE) *status = MEMBER_NOT_FOUND; } /* if the above function returned without error then the mfptr is pointed to the member HDU */ break; default: /* no default action */ break; } }while(0); if(*status != 0 && *mfptr != NULL) { fits_close_file(*mfptr,status); } return(*status); } /*---------------------------------------------------------------------------*/ int ffgmcp(fitsfile *gfptr, /* FITS file pointer to group */ fitsfile *mfptr, /* FITS file pointer to new member FITS file */ long member, /* member ID (row num) within grouping table */ int cpopt, /* code specifying copy options: OPT_MCP_ADD (0) ==> add copied member to the grouping table OPT_MCP_NADD (1) ==> do not add member copy to the grouping table OPT_MCP_REPL (2) ==> replace current member entry with member copy */ int *status) /* return status code */ /* copy a member HDU of a grouping table to a new FITS file. The grouping table must be the CHDU of the FITS file pointed to by gfptr. The copy of the group member shall be appended to the end of the FITS file pointed to by mfptr. If the cpopt parameter is set to OPT_MCP_ADD then the copy of the member is added to the grouping table as a new member, if OPT_MCP_NADD then the copied member is not added to the grouping table, and if OPT_MCP_REPL then the copied member is used to replace the original member. The copied member HDU also has its EXTVER value updated so that its combination of XTENSION, EXTNAME and EXVTER is unique within its new FITS file. */ { int numkeys = 0; int keypos = 0; int hdunum = 0; int hdutype = 0; int i; char *incList[] = {"GRPID#","GRPLC#"}; char extname[FLEN_VALUE]; char card[FLEN_CARD]; char comment[FLEN_COMMENT]; char keyname[FLEN_CARD]; char value[FLEN_CARD]; fitsfile *tmpfptr = NULL; if(*status != 0) return(*status); do { /* open the member HDU to be copied */ *status = fits_open_member(gfptr,member,&tmpfptr,status); if(*status != 0) continue; /* if the member is a grouping table then copy it with a call to fits_copy_group() using the "copy only the grouping table" option if it is not a grouping table then copy the hdu with fits_copy_hdu() remove all GRPIDn and GRPLCn keywords, and update the EXTVER keyword value */ /* get the member HDU's EXTNAME value */ *status = fits_read_key_str(tmpfptr,"EXTNAME",extname,comment,status); /* if no EXTNAME value was found then set the extname to a null string */ if(*status == KEY_NO_EXIST) { extname[0] = 0; *status = 0; } else if(*status != 0) continue; prepare_keyvalue(extname); /* if a grouping table then copy with fits_copy_group() */ if(strcasecmp(extname,"GROUPING") == 0) *status = fits_copy_group(tmpfptr,mfptr,OPT_GCP_GPT,status); else { /* copy the non-grouping table HDU the conventional way */ *status = fits_copy_hdu(tmpfptr,mfptr,0,status); ffgrec(mfptr,0,card,status); /* delete all the GRPIDn and GRPLCn keywords in the copied HDU */ while(*status == 0) { *status = fits_find_nextkey(mfptr,incList,2,NULL,0,card,status); *status = fits_get_hdrpos(mfptr,&numkeys,&keypos,status); /* SPR 1738 */ *status = fits_read_keyn(mfptr,keypos-1,keyname,value, comment,status); *status = fits_read_record(mfptr,keypos-1,card,status); *status = fits_delete_key(mfptr,keyname,status); } if(*status == KEY_NO_EXIST) *status = 0; if(*status != 0) continue; } /* if the member HDU does not have an EXTNAME keyword then add one with a default value */ if(strlen(extname) == 0) { if(fits_get_hdu_num(tmpfptr,&hdunum) == 1) { strcpy(extname,"PRIMARY"); *status = fits_write_key_str(mfptr,"EXTNAME",extname, "HDU was Formerly a Primary Array", status); } else { strcpy(extname,"DEFAULT"); *status = fits_write_key_str(mfptr,"EXTNAME",extname, "default EXTNAME set by CFITSIO", status); } } /* update the member HDU's EXTVER value (add it if not present) */ fits_get_hdu_num(mfptr,&hdunum); fits_get_hdu_type(mfptr,&hdutype,status); /* set the EXTVER value to 0 for now */ *status = fits_modify_key_lng(mfptr,"EXTVER",0,NULL,status); /* if the EXTVER keyword was not found then add it */ if(*status == KEY_NO_EXIST) { *status = 0; *status = fits_read_key_str(mfptr,"EXTNAME",extname,comment, status); *status = fits_insert_key_lng(mfptr,"EXTVER",0, "Extension version ID",status); } if(*status != 0) continue; /* find the first available EXTVER value for the copied HDU */ for(i = 1; fits_movnam_hdu(mfptr,hdutype,extname,i,status) == 0; ++i); *status = 0; fits_movabs_hdu(mfptr,hdunum,&hdutype,status); /* reset the copied member HDUs EXTVER value */ *status = fits_modify_key_lng(mfptr,"EXTVER",(long)i,NULL,status); /* perform member copy operations that are dependent upon the cpopt parameter value */ switch(cpopt) { case OPT_MCP_ADD: /* add the copied member to the grouping table, leaving the entry for the original member in place */ *status = fits_add_group_member(gfptr,mfptr,0,status); break; case OPT_MCP_NADD: /* nothing to do for this copy option */ break; case OPT_MCP_REPL: /* remove the original member from the grouping table and add the copied member in its place */ *status = fits_remove_member(gfptr,member,OPT_RM_ENTRY,status); *status = fits_add_group_member(gfptr,mfptr,0,status); break; default: *status = BAD_OPTION; ffpmsg("Invalid value specified for the cmopt parameter (ffgmcp)"); break; } }while(0); if(tmpfptr != NULL) { fits_close_file(tmpfptr,status); } return(*status); } /*---------------------------------------------------------------------------*/ int ffgmtf(fitsfile *infptr, /* FITS file pointer to source grouping table */ fitsfile *outfptr, /* FITS file pointer to target grouping table */ long member, /* member ID within source grouping table */ int tfopt, /* code specifying transfer opts: OPT_MCP_ADD (0) ==> copy member to dest. OPT_MCP_MOV (3) ==> move member to dest. */ int *status) /* return status code */ /* transfer a group member from one grouping table to another. The source grouping table must be the CHDU of the fitsfile pointed to by infptr, and the destination grouping table must be the CHDU of the fitsfile to by outfptr. If the tfopt parameter is OPT_MCP_ADD then the member is made a member of the target group and remains a member of the source group. If the tfopt parameter is OPT_MCP_MOV then the member is deleted from the source group after the transfer to the destination group. The member to be transfered is identified by its row number within the source grouping table. */ { fitsfile *mfptr = NULL; if(*status != 0) return(*status); if(tfopt != OPT_MCP_MOV && tfopt != OPT_MCP_ADD) { *status = BAD_OPTION; ffpmsg("Invalid value specified for the tfopt parameter (ffgmtf)"); } else { /* open the member of infptr to be transfered */ *status = fits_open_member(infptr,member,&mfptr,status); /* add the member to the outfptr grouping table */ *status = fits_add_group_member(outfptr,mfptr,0,status); /* close the member HDU */ *status = fits_close_file(mfptr,status); /* if the tfopt is "move member" then remove it from the infptr grouping table */ if(tfopt == OPT_MCP_MOV) *status = fits_remove_member(infptr,member,OPT_RM_ENTRY,status); } return(*status); } /*---------------------------------------------------------------------------*/ int ffgmrm(fitsfile *gfptr, /* FITS file pointer to group table */ long member, /* member ID (row num) in the group */ int rmopt, /* code specifying the delete option: OPT_RM_ENTRY ==> delete the member entry OPT_RM_MBR ==> delete entry and member HDU */ int *status) /* return status code */ /* remove a member HDU from a grouping table. The fitsfile pointer gfptr must be positioned with the grouping table as the CHDU, and the member to delete is identified by its row number in the table (first member == 1). The rmopt parameter determines if the member entry is deleted from the grouping table (in which case GRPIDn and GRPLCn keywords in the member HDU's header shall be updated accordingly) or if the member HDU shall itself be removed from its FITS file. */ { int found = 0; int hdutype = 0; int index = 0; int iomode = 0; long i; long ngroups = 0; long nmembers = 0; long groupExtver = 0; long grpid = 0; char grpLocation1[FLEN_FILENAME]; char grpLocation2[FLEN_FILENAME]; char grpLocation3[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char keyword[FLEN_KEYWORD]; /* SPR 1738 This can now be longer */ char grplc[FLEN_FILENAME]; char *tgrplc; char keyvalue[FLEN_VALUE]; char card[FLEN_CARD]; char *editLocation; fitsfile *mfptr = NULL; if(*status != 0) return(*status); do { /* make sure the grouping table can be modified before proceeding */ fits_file_mode(gfptr,&iomode,status); if(iomode != READWRITE) { ffpmsg("cannot modify grouping table (ffgtam)"); *status = BAD_GROUP_DETACH; continue; } /* open the group member to be deleted and get its IOstatus*/ *status = fits_open_member(gfptr,member,&mfptr,status); *status = fits_file_mode(mfptr,&iomode,status); /* if the member HDU is to be deleted then call fits_unlink_member() to remove it from all groups to which it belongs (including this one) and then delete it. Note that if the member is a grouping table then we have to recursively call fits_remove_member() for each member of the member before we delete the member itself. */ if(rmopt == OPT_RM_MBR) { /* cannot delete a PHDU */ if(fits_get_hdu_num(mfptr,&hdutype) == 1) { *status = BAD_HDU_NUM; continue; } /* determine if the member HDU is itself a grouping table */ *status = fits_read_key_str(mfptr,"EXTNAME",keyvalue,card,status); /* if no EXTNAME is found then the HDU cannot be a grouping table */ if(*status == KEY_NO_EXIST) { keyvalue[0] = 0; *status = 0; } prepare_keyvalue(keyvalue); /* Any other error is a reason to abort */ if(*status != 0) continue; /* if the EXTNAME == GROUPING then the member is a grouping table */ if(strcasecmp(keyvalue,"GROUPING") == 0) { /* remove each of the grouping table members */ *status = fits_get_num_members(mfptr,&nmembers,status); for(i = nmembers; i > 0 && *status == 0; --i) *status = fits_remove_member(mfptr,i,OPT_RM_ENTRY,status); if(*status != 0) continue; } /* unlink the member HDU from all groups that contain it */ *status = ffgmul(mfptr,0,status); if(*status != 0) continue; /* reset the grouping table HDU struct */ fits_set_hdustruc(gfptr,status); /* delete the member HDU */ if(iomode != READONLY) *status = fits_delete_hdu(mfptr,&hdutype,status); } else if(rmopt == OPT_RM_ENTRY) { /* The member HDU is only to be removed as an entry from this grouping table. Actions are (1) find the GRPIDn/GRPLCn keywords that link the member to the grouping table, (2) remove the GRPIDn/GRPLCn keyword from the member HDU header and (3) remove the member entry from the grouping table */ /* there is no need to seach for and remove the GRPIDn/GRPLCn keywords from the member HDU if it has not been opened in READWRITE mode */ if(iomode == READWRITE) { /* determine the group EXTVER value of the grouping table; if the member HDU and grouping table HDU do not reside in the same file then set the groupExtver value to its negative */ *status = fits_read_key_lng(gfptr,"EXTVER",&groupExtver,card, status); if(mfptr->Fptr != gfptr->Fptr) groupExtver = -1*groupExtver; /* retrieve the URLs for the grouping table; note that it is possible that the grouping table file has two URLs, the one used to open it and the "real" one pointing to the actual file being accessed */ *status = fits_get_url(gfptr,grpLocation1,grpLocation2,NULL, NULL,NULL,status); if(*status != 0) continue; /* if either of the group location strings specify a relative file path then convert them into absolute file paths */ *status = fits_get_cwd(cwd,status); if(*grpLocation1 != 0 && *grpLocation1 != '/' && !fits_is_url_absolute(grpLocation1)) { strcpy(grpLocation3,cwd); strcat(grpLocation3,"/"); strcat(grpLocation3,grpLocation1); fits_clean_url(grpLocation3,grpLocation1,status); } if(*grpLocation2 != 0 && *grpLocation2 != '/' && !fits_is_url_absolute(grpLocation2)) { strcpy(grpLocation3,cwd); strcat(grpLocation3,"/"); strcat(grpLocation3,grpLocation2); fits_clean_url(grpLocation3,grpLocation2,status); } /* determine the number of groups to which the member HDU belongs */ *status = fits_get_num_groups(mfptr,&ngroups,status); /* reset the HDU keyword position counter to the beginning */ *status = ffgrec(mfptr,0,card,status); /* loop over all the GRPIDn keywords in the member HDU header and find the appropriate GRPIDn and GRPLCn keywords that identify it as belonging to the group */ for(index = 1, found = 0; index <= ngroups && *status == 0 && !found; ++index) { /* read the next GRPIDn keyword in the series */ sprintf(keyword,"GRPID%d",index); *status = fits_read_key_lng(mfptr,keyword,&grpid,card, status); if(*status != 0) continue; /* grpid value == group EXTVER value then we could have a match */ if(grpid == groupExtver && grpid > 0) { /* if GRPID is positive then its a match because both the member HDU and grouping table HDU reside in the same FITS file */ found = index; } else if(grpid == groupExtver && grpid < 0) { /* have to look at the GRPLCn value to determine a match because the member HDU and grouping table HDU reside in different FITS files */ sprintf(keyword,"GRPLC%d",index); /* SPR 1738 */ *status = fits_read_key_longstr(mfptr,keyword,&tgrplc, card, status); if (0 == *status) { strcpy(grplc,tgrplc); free(tgrplc); } if(*status == KEY_NO_EXIST) { /* no GRPLCn keyword value found ==> grouping convention not followed; nothing we can do about it, so just continue */ sprintf(card,"No GRPLC%d found for GRPID%d", index,index); ffpmsg(card); *status = 0; continue; } else if (*status != 0) continue; /* construct the URL for the GRPLCn value */ prepare_keyvalue(grplc); /* if the grplc value specifies a relative path then turn it into a absolute file path for comparison purposes */ if(*grplc != 0 && !fits_is_url_absolute(grplc) && *grplc != '/') { /* No, wrong, strcpy(grpLocation3,cwd); should be */ *status = fits_file_name(mfptr,grpLocation3,status); /* Remove everything after the last / */ if (NULL != (editLocation = strrchr(grpLocation3,'/'))) { *editLocation = '\0'; } strcat(grpLocation3,"/"); strcat(grpLocation3,grplc); *status = fits_clean_url(grpLocation3,grplc, status); } /* if the absolute value of GRPIDn is equal to the EXTVER value of the grouping table and (one of the possible two) grouping table file URL matches the GRPLCn keyword value then we hava a match */ if(strcmp(grplc,grpLocation1) == 0 || strcmp(grplc,grpLocation2) == 0) found = index; } } /* if found == 0 (false) after the above search then we assume that it is due to an inpromper updating of the GRPIDn and GRPLCn keywords in the member header ==> nothing to delete in the header. Else delete the GRPLCn and GRPIDn keywords that identify the member HDU with the group HDU and re-enumerate the remaining GRPIDn and GRPLCn keywords */ if(found != 0) { sprintf(keyword,"GRPID%d",found); *status = fits_delete_key(mfptr,keyword,status); sprintf(keyword,"GRPLC%d",found); *status = fits_delete_key(mfptr,keyword,status); *status = 0; /* call fits_get_num_groups() to re-enumerate the GRPIDn */ *status = fits_get_num_groups(mfptr,&ngroups,status); } } /* finally, remove the member entry from the current grouping table pointed to by gfptr */ *status = fits_delete_rows(gfptr,member,1,status); } else { *status = BAD_OPTION; ffpmsg("Invalid value specified for the rmopt parameter (ffgmrm)"); } }while(0); if(mfptr != NULL) { fits_close_file(mfptr,status); } return(*status); } /*--------------------------------------------------------------------------- Grouping Table support functions ---------------------------------------------------------------------------*/ int ffgtgc(fitsfile *gfptr, /* pointer to the grouping table */ int *xtensionCol, /* column ID of the MEMBER_XTENSION column */ int *extnameCol, /* column ID of the MEMBER_NAME column */ int *extverCol, /* column ID of the MEMBER_VERSION column */ int *positionCol, /* column ID of the MEMBER_POSITION column */ int *locationCol, /* column ID of the MEMBER_LOCATION column */ int *uriCol, /* column ID of the MEMBER_URI_TYPE column */ int *grptype, /* group structure type code specifying the grouping table columns that are defined: GT_ID_ALL_URI (0) ==> all columns defined GT_ID_REF (1) ==> reference cols only GT_ID_POS (2) ==> position col only GT_ID_ALL (3) ==> ref & pos cols GT_ID_REF_URI (11) ==> ref & loc cols GT_ID_POS_URI (12) ==> pos & loc cols */ int *status) /* return status code */ /* examine the grouping table pointed to by gfptr and determine the column index ID of each possible grouping column. If a column is not found then an index of 0 is returned. the grptype parameter returns the structure of the grouping table ==> what columns are defined. */ { char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; if(*status != 0) return(*status); do { /* if the HDU does not have an extname of "GROUPING" then it is not a grouping table */ *status = fits_read_key_str(gfptr,"EXTNAME",keyvalue,comment,status); if(*status == KEY_NO_EXIST) { *status = NOT_GROUP_TABLE; ffpmsg("Specified HDU is not a Grouping Table (ffgtgc)"); } if(*status != 0) continue; prepare_keyvalue(keyvalue); if(strcasecmp(keyvalue,"GROUPING") != 0) { *status = NOT_GROUP_TABLE; continue; } /* search for the MEMBER_XTENSION, MEMBER_NAME, MEMBER_VERSION, MEMBER_POSITION, MEMBER_LOCATION and MEMBER_URI_TYPE columns and determine their column index ID */ *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_XTENSION",xtensionCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *xtensionCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_NAME",extnameCol,status); if(*status == COL_NOT_FOUND) { *status = 0; *extnameCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_VERSION",extverCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *extverCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_POSITION",positionCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *positionCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_LOCATION",locationCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *locationCol = 0; } if(*status != 0) continue; *status = fits_get_colnum(gfptr,CASESEN,"MEMBER_URI_TYPE",uriCol, status); if(*status == COL_NOT_FOUND) { *status = 0; *uriCol = 0; } if(*status != 0) continue; /* determine the type of grouping table structure used by this grouping table and record it in the grptype parameter */ if(*xtensionCol && *extnameCol && *extverCol && *positionCol && *locationCol && *uriCol) *grptype = GT_ID_ALL_URI; else if(*xtensionCol && *extnameCol && *extverCol && *locationCol && *uriCol) *grptype = GT_ID_REF_URI; else if(*xtensionCol && *extnameCol && *extverCol && *positionCol) *grptype = GT_ID_ALL; else if(*xtensionCol && *extnameCol && *extverCol) *grptype = GT_ID_REF; else if(*positionCol && *locationCol && *uriCol) *grptype = GT_ID_POS_URI; else if(*positionCol) *grptype = GT_ID_POS; else *status = NOT_GROUP_TABLE; }while(0); /* if the table contained more than one column with a reserved name then this cannot be considered a vailid grouping table */ if(*status == COL_NOT_UNIQUE) { *status = NOT_GROUP_TABLE; ffpmsg("Specified HDU has multipule Group table cols defined (ffgtgc)"); } return(*status); } /*****************************************************************************/ int ffgtdc(int grouptype, /* code specifying the type of grouping table information: GT_ID_ALL_URI 0 ==> defualt (all columns) GT_ID_REF 1 ==> ID by reference GT_ID_POS 2 ==> ID by position GT_ID_ALL 3 ==> ID by ref. and position GT_ID_REF_URI 11 ==> (1) + URI info GT_ID_POS_URI 12 ==> (2) + URI info */ int xtensioncol, /* does MEMBER_XTENSION already exist? */ int extnamecol, /* does MEMBER_NAME aleady exist? */ int extvercol, /* does MEMBER_VERSION already exist? */ int positioncol, /* does MEMBER_POSITION already exist? */ int locationcol, /* does MEMBER_LOCATION already exist? */ int uricol, /* does MEMBER_URI_TYPE aleardy exist? */ char *ttype[], /* array of grouping table column TTYPE names to define (if *col var false) */ char *tform[], /* array of grouping table column TFORM values to define (if*col variable false) */ int *ncols, /* number of TTYPE and TFORM values returned */ int *status) /* return status code */ /* create the TTYPE and TFORM values for the grouping table according to the value of the grouptype parameter and the values of the *col flags. The resulting TTYPE and TFORM are returned in ttype[] and tform[] respectively. The number of TTYPE and TFORMs returned is given by ncols. Both the TTYPE[] and TTFORM[] arrays must contain enough pre-allocated strings to hold the returned information. */ { int i = 0; char xtension[] = "MEMBER_XTENSION"; char xtenTform[] = "8A"; char name[] = "MEMBER_NAME"; char nameTform[] = "32A"; char version[] = "MEMBER_VERSION"; char verTform[] = "1J"; char position[] = "MEMBER_POSITION"; char posTform[] = "1J"; char URI[] = "MEMBER_URI_TYPE"; char URITform[] = "3A"; char location[] = "MEMBER_LOCATION"; /* SPR 01720, move from 160A to 256A */ char locTform[] = "256A"; if(*status != 0) return(*status); switch(grouptype) { case GT_ID_ALL_URI: if(xtensioncol == 0) { strcpy(ttype[i],xtension); strcpy(tform[i],xtenTform); ++i; } if(extnamecol == 0) { strcpy(ttype[i],name); strcpy(tform[i],nameTform); ++i; } if(extvercol == 0) { strcpy(ttype[i],version); strcpy(tform[i],verTform); ++i; } if(positioncol == 0) { strcpy(ttype[i],position); strcpy(tform[i],posTform); ++i; } if(locationcol == 0) { strcpy(ttype[i],location); strcpy(tform[i],locTform); ++i; } if(uricol == 0) { strcpy(ttype[i],URI); strcpy(tform[i],URITform); ++i; } break; case GT_ID_REF: if(xtensioncol == 0) { strcpy(ttype[i],xtension); strcpy(tform[i],xtenTform); ++i; } if(extnamecol == 0) { strcpy(ttype[i],name); strcpy(tform[i],nameTform); ++i; } if(extvercol == 0) { strcpy(ttype[i],version); strcpy(tform[i],verTform); ++i; } break; case GT_ID_POS: if(positioncol == 0) { strcpy(ttype[i],position); strcpy(tform[i],posTform); ++i; } break; case GT_ID_ALL: if(xtensioncol == 0) { strcpy(ttype[i],xtension); strcpy(tform[i],xtenTform); ++i; } if(extnamecol == 0) { strcpy(ttype[i],name); strcpy(tform[i],nameTform); ++i; } if(extvercol == 0) { strcpy(ttype[i],version); strcpy(tform[i],verTform); ++i; } if(positioncol == 0) { strcpy(ttype[i],position); strcpy(tform[i], posTform); ++i; } break; case GT_ID_REF_URI: if(xtensioncol == 0) { strcpy(ttype[i],xtension); strcpy(tform[i],xtenTform); ++i; } if(extnamecol == 0) { strcpy(ttype[i],name); strcpy(tform[i],nameTform); ++i; } if(extvercol == 0) { strcpy(ttype[i],version); strcpy(tform[i],verTform); ++i; } if(locationcol == 0) { strcpy(ttype[i],location); strcpy(tform[i],locTform); ++i; } if(uricol == 0) { strcpy(ttype[i],URI); strcpy(tform[i],URITform); ++i; } break; case GT_ID_POS_URI: if(positioncol == 0) { strcpy(ttype[i],position); strcpy(tform[i],posTform); ++i; } if(locationcol == 0) { strcpy(ttype[i],location); strcpy(tform[i],locTform); ++i; } if(uricol == 0) { strcpy(ttype[i],URI); strcpy(tform[i],URITform); ++i; } break; default: *status = BAD_OPTION; ffpmsg("Invalid value specified for the grouptype parameter (ffgtdc)"); break; } *ncols = i; return(*status); } /*****************************************************************************/ int ffgmul(fitsfile *mfptr, /* pointer to the grouping table member HDU */ int rmopt, /* 0 ==> leave GRPIDn/GRPLCn keywords, 1 ==> remove GRPIDn/GRPLCn keywords */ int *status) /* return status code */ /* examine all the GRPIDn and GRPLCn keywords in the member HDUs header and remove the member from the grouping tables referenced; This effectively "unlinks" the member from all of its groups. The rmopt specifies if the GRPIDn/GRPLCn keywords are to be removed from the member HDUs header after the unlinking. */ { int memberPosition = 0; int iomode; long index = 0; long ngroups = 0; long memberExtver = 0; long memberID = 0; char mbrLocation1[FLEN_FILENAME]; char mbrLocation2[FLEN_FILENAME]; char memberHDUtype[FLEN_VALUE]; char memberExtname[FLEN_VALUE]; char keyword[FLEN_KEYWORD]; char card[FLEN_CARD]; fitsfile *gfptr = NULL; if(*status != 0) return(*status); do { /* determine location parameters of the member HDU; note that default values are supplied if the expected keywords are not found */ *status = fits_read_key_str(mfptr,"XTENSION",memberHDUtype,card,status); if(*status == KEY_NO_EXIST) { strcpy(memberHDUtype,"PRIMARY"); *status = 0; } prepare_keyvalue(memberHDUtype); *status = fits_read_key_lng(mfptr,"EXTVER",&memberExtver,card,status); if(*status == KEY_NO_EXIST) { memberExtver = 1; *status = 0; } *status = fits_read_key_str(mfptr,"EXTNAME",memberExtname,card,status); if(*status == KEY_NO_EXIST) { memberExtname[0] = 0; *status = 0; } prepare_keyvalue(memberExtname); fits_get_hdu_num(mfptr,&memberPosition); *status = fits_get_url(mfptr,mbrLocation1,mbrLocation2,NULL,NULL, NULL,status); if(*status != 0) continue; /* open each grouping table linked to this HDU and remove the member from the grouping tables */ *status = fits_get_num_groups(mfptr,&ngroups,status); /* loop over each group linked to the member HDU */ for(index = 1; index <= ngroups && *status == 0; ++index) { /* open the (index)th group linked to the member HDU */ *status = fits_open_group(mfptr,index,&gfptr,status); /* if the group could not be opened then just skip it */ if(*status != 0) { *status = 0; sprintf(card,"Cannot open the %dth group table (ffgmul)", (int)index); ffpmsg(card); continue; } /* make sure the grouping table can be modified before proceeding */ fits_file_mode(gfptr,&iomode,status); if(iomode != READWRITE) { sprintf(card,"The %dth group cannot be modified (ffgtam)", (int)index); ffpmsg(card); continue; } /* try to find the member's row within the grouping table; first try using the member HDU file's "real" URL string then try using its originally opened URL string if either string exist */ memberID = 0; if(strlen(mbrLocation1) != 0) { *status = ffgmf(gfptr,memberHDUtype,memberExtname,memberExtver, memberPosition,mbrLocation1,&memberID,status); } if(*status == MEMBER_NOT_FOUND && strlen(mbrLocation2) != 0) { *status = 0; *status = ffgmf(gfptr,memberHDUtype,memberExtname,memberExtver, memberPosition,mbrLocation2,&memberID,status); } /* if the member was found then delete it from the grouping table */ if(*status == 0) *status = fits_delete_rows(gfptr,memberID,1,status); /* continue the loop over all member groups even if an error was generated */ if(*status == MEMBER_NOT_FOUND) { ffpmsg("cannot locate member's entry in group table (ffgmul)"); } *status = 0; /* close the file pointed to by gfptr if it is non NULL to prepare for the next loop iterration */ if(gfptr != NULL) { fits_close_file(gfptr,status); gfptr = NULL; } } if(*status != 0) continue; /* if rmopt is non-zero then find and delete the GRPIDn/GRPLCn keywords from the member HDU header */ if(rmopt != 0) { fits_file_mode(mfptr,&iomode,status); if(iomode == READONLY) { ffpmsg("Cannot modify member HDU, opened READONLY (ffgmul)"); continue; } /* delete all the GRPIDn/GRPLCn keywords */ for(index = 1; index <= ngroups && *status == 0; ++index) { sprintf(keyword,"GRPID%d",(int)index); fits_delete_key(mfptr,keyword,status); sprintf(keyword,"GRPLC%d",(int)index); fits_delete_key(mfptr,keyword,status); if(*status == KEY_NO_EXIST) *status = 0; } } }while(0); /* make sure the gfptr has been closed */ if(gfptr != NULL) { fits_close_file(gfptr,status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgmf(fitsfile *gfptr, /* pointer to grouping table HDU to search */ char *xtension, /* XTENSION value for member HDU */ char *extname, /* EXTNAME value for member HDU */ int extver, /* EXTVER value for member HDU */ int position, /* HDU position value for member HDU */ char *location, /* FITS file location value for member HDU */ long *member, /* member HDU ID within group table (if found) */ int *status) /* return status code */ /* try to find the entry for the member HDU defined by the xtension, extname, extver, position, and location parameters within the grouping table pointed to by gfptr. If the member HDU is found then its ID (row number) within the grouping table is returned in the member variable; if not found then member is returned with a value of 0 and the status return code will be set to MEMBER_NOT_FOUND. Note that the member HDU postion information is used to obtain a member match only if the grouping table type is GT_ID_POS_URI or GT_ID_POS. This is because the position information can become invalid much more easily then the reference information for a group member. */ { int xtensionCol,extnameCol,extverCol,positionCol,locationCol,uriCol; int mposition = 0; int grptype; int dummy; int i; long nmembers = 0; long mextver = 0; char charBuff1[FLEN_FILENAME]; char charBuff2[FLEN_FILENAME]; char tmpLocation[FLEN_FILENAME]; char mbrLocation1[FLEN_FILENAME]; char mbrLocation2[FLEN_FILENAME]; char mbrLocation3[FLEN_FILENAME]; char grpLocation1[FLEN_FILENAME]; char grpLocation2[FLEN_FILENAME]; char cwd[FLEN_FILENAME]; char nstr[] = {'\0'}; char *tmpPtr[2]; if(*status != 0) return(*status); *member = 0; tmpPtr[0] = charBuff1; tmpPtr[1] = charBuff2; if(*status != 0) return(*status); /* if the passed LOCATION value is not an absolute URL then turn it into an absolute path */ if(location == NULL) { *tmpLocation = 0; } else if(*location == 0) { *tmpLocation = 0; } else if(!fits_is_url_absolute(location)) { fits_path2url(location,tmpLocation,status); if(*tmpLocation != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,tmpLocation); fits_clean_url(cwd,tmpLocation,status); } } else strcpy(tmpLocation,location); /* retrieve the Grouping Convention reserved column positions within the grouping table */ *status = ffgtgc(gfptr,&xtensionCol,&extnameCol,&extverCol,&positionCol, &locationCol,&uriCol,&grptype,status); /* retrieve the number of group members */ *status = fits_get_num_members(gfptr,&nmembers,status); /* loop over all grouping table rows until the member HDU is found */ for(i = 1; i <= nmembers && *member == 0 && *status == 0; ++i) { if(xtensionCol != 0) { fits_read_col_str(gfptr,xtensionCol,i,1,1,nstr,tmpPtr,&dummy,status); if(strcasecmp(tmpPtr[0],xtension) != 0) continue; } if(extnameCol != 0) { fits_read_col_str(gfptr,extnameCol,i,1,1,nstr,tmpPtr,&dummy,status); if(strcasecmp(tmpPtr[0],extname) != 0) continue; } if(extverCol != 0) { fits_read_col_lng(gfptr,extverCol,i,1,1,0, (long*)&mextver,&dummy,status); if(extver != mextver) continue; } /* note we only use postionCol if we have to */ if(positionCol != 0 && (grptype == GT_ID_POS || grptype == GT_ID_POS_URI)) { fits_read_col_int(gfptr,positionCol,i,1,1,0, &mposition,&dummy,status); if(position != mposition) continue; } /* if no location string was passed to the function then assume that the calling application does not wish to use it as a comparision critera ==> if we got this far then we have a match */ if(location == NULL) { ffpmsg("NULL Location string given ==> ingore location (ffgmf)"); *member = i; continue; } /* if the grouping table MEMBER_LOCATION column exists then read the location URL for the member, else set the location string to a zero-length string for subsequent comparisions */ if(locationCol != 0) { fits_read_col_str(gfptr,locationCol,i,1,1,nstr,tmpPtr,&dummy,status); strcpy(mbrLocation1,tmpPtr[0]); *mbrLocation2 = 0; } else *mbrLocation1 = 0; /* if the member location string from the grouping table is zero length (either implicitly or explicitly) then assume that the member HDU is in the same file as the grouping table HDU; retrieve the possible URL values of the grouping table HDU file */ if(*mbrLocation1 == 0) { /* retrieve the possible URLs of the grouping table file */ *status = fits_get_url(gfptr,mbrLocation1,mbrLocation2,NULL,NULL, NULL,status); /* if non-NULL, make sure the first URL is absolute or a full path */ if(*mbrLocation1 != 0 && !fits_is_url_absolute(mbrLocation1) && *mbrLocation1 != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,mbrLocation1); fits_clean_url(cwd,mbrLocation1,status); } /* if non-NULL, make sure the first URL is absolute or a full path */ if(*mbrLocation2 != 0 && !fits_is_url_absolute(mbrLocation2) && *mbrLocation2 != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,mbrLocation2); fits_clean_url(cwd,mbrLocation2,status); } } /* if the member location was specified, then make sure that it is either an absolute URL or specifies a full path */ else if(!fits_is_url_absolute(mbrLocation1) && *mbrLocation1 != '/') { strcpy(mbrLocation2,mbrLocation1); /* get the possible URLs for the grouping table file */ *status = fits_get_url(gfptr,grpLocation1,grpLocation2,NULL,NULL, NULL,status); if(*grpLocation1 != 0) { /* make sure the first grouping table URL is absolute */ if(!fits_is_url_absolute(grpLocation1) && *grpLocation1 != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,grpLocation1); fits_clean_url(cwd,grpLocation1,status); } /* create an absoute URL for the member */ fits_relurl2url(grpLocation1,mbrLocation1,mbrLocation3,status); /* if URL construction succeeded then copy it to the first location string; else set the location string to empty */ if(*status == 0) { strcpy(mbrLocation1,mbrLocation3); } else if(*status == URL_PARSE_ERROR) { *status = 0; *mbrLocation1 = 0; } } else *mbrLocation1 = 0; if(*grpLocation2 != 0) { /* make sure the second grouping table URL is absolute */ if(!fits_is_url_absolute(grpLocation2) && *grpLocation2 != '/') { fits_get_cwd(cwd,status); strcat(cwd,"/"); strcat(cwd,grpLocation2); fits_clean_url(cwd,grpLocation2,status); } /* create an absolute URL for the member */ fits_relurl2url(grpLocation2,mbrLocation2,mbrLocation3,status); /* if URL construction succeeded then copy it to the second location string; else set the location string to empty */ if(*status == 0) { strcpy(mbrLocation2,mbrLocation3); } else if(*status == URL_PARSE_ERROR) { *status = 0; *mbrLocation2 = 0; } } else *mbrLocation2 = 0; } /* compare the passed member HDU file location string with the (possibly two) member location strings to see if there is a match */ if(strcmp(mbrLocation1,tmpLocation) != 0 && strcmp(mbrLocation2,tmpLocation) != 0 ) continue; /* if we made it this far then a match to the member HDU was found */ *member = i; } /* if a match was not found then set the return status code */ if(*member == 0 && *status == 0) { *status = MEMBER_NOT_FOUND; ffpmsg("Cannot find specified member HDU (ffgmf)"); } return(*status); } /*-------------------------------------------------------------------------- Recursive Group Functions --------------------------------------------------------------------------*/ int ffgtrmr(fitsfile *gfptr, /* FITS file pointer to group */ HDUtracker *HDU, /* list of processed HDUs */ int *status) /* return status code */ /* recursively remove a grouping table and all its members. Each member of the grouping table pointed to by gfptr it processed. If the member is itself a grouping table then ffgtrmr() is recursively called to process all of its members. The HDUtracker struct *HDU is used to make sure a member is not processed twice, thus avoiding an infinite loop (e.g., a grouping table contains itself as a member). */ { int i; int hdutype; long nmembers = 0; char keyvalue[FLEN_VALUE]; char comment[FLEN_COMMENT]; fitsfile *mfptr = NULL; if(*status != 0) return(*status); /* get the number of members contained by this grouping table */ *status = fits_get_num_members(gfptr,&nmembers,status); /* loop over all group members and delete them */ for(i = nmembers; i > 0 && *status == 0; --i) { /* open the member HDU */ *status = fits_open_member(gfptr,i,&mfptr,status); /* if the member cannot be opened then just skip it and continue */ if(*status == MEMBER_NOT_FOUND) { *status = 0; continue; } /* Any other error is a reason to abort */ if(*status != 0) continue; /* add the member HDU to the HDUtracker struct */ *status = fftsad(mfptr,HDU,NULL,NULL); /* status == HDU_ALREADY_TRACKED ==> HDU has already been processed */ if(*status == HDU_ALREADY_TRACKED) { *status = 0; fits_close_file(mfptr,status); continue; } else if(*status != 0) continue; /* determine if the member HDU is itself a grouping table */ *status = fits_read_key_str(mfptr,"EXTNAME",keyvalue,comment,status); /* if no EXTNAME is found then the HDU cannot be a grouping table */ if(*status == KEY_NO_EXIST) { *status = 0; keyvalue[0] = 0; } prepare_keyvalue(keyvalue); /* Any other error is a reason to abort */ if(*status != 0) continue; /* if the EXTNAME == GROUPING then the member is a grouping table and we must call ffgtrmr() to process its members */ if(strcasecmp(keyvalue,"GROUPING") == 0) *status = ffgtrmr(mfptr,HDU,status); /* unlink all the grouping tables that contain this HDU as a member and then delete the HDU (if not a PHDU) */ if(fits_get_hdu_num(mfptr,&hdutype) == 1) *status = ffgmul(mfptr,1,status); else { *status = ffgmul(mfptr,0,status); *status = fits_delete_hdu(mfptr,&hdutype,status); } /* close the fitsfile pointer */ fits_close_file(mfptr,status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgtcpr(fitsfile *infptr, /* input FITS file pointer */ fitsfile *outfptr, /* output FITS file pointer */ int cpopt, /* code specifying copy options: OPT_GCP_GPT (0) ==> cp only grouping table OPT_GCP_ALL (2) ==> recusrively copy members and their members (if groups) */ HDUtracker *HDU, /* list of already copied HDUs */ int *status) /* return status code */ /* copy a Group to a new FITS file. If the cpopt parameter is set to OPT_GCP_GPT (copy grouping table only) then the existing members have their GRPIDn and GRPLCn keywords updated to reflect the existance of the new group, since they now belong to another group. If cpopt is set to OPT_GCP_ALL (copy grouping table and members recursively) then the original members are not updated; the new grouping table is modified to include only the copied member HDUs and not the original members. Note that this function is recursive. When copt is OPT_GCP_ALL it will call itself whenever a member HDU of the current grouping table is itself a grouping table (i.e., EXTNAME = 'GROUPING'). */ { int i; int nexclude = 8; int hdutype = 0; int groupHDUnum = 0; int numkeys = 0; int keypos = 0; int startSearch = 0; int newPosition = 0; long nmembers = 0; long tfields = 0; long newTfields = 0; char keyword[FLEN_KEYWORD]; char keyvalue[FLEN_VALUE]; char card[FLEN_CARD]; char comment[FLEN_CARD]; char *tkeyvalue; char *includeList[] = {"*"}; char *excludeList[] = {"EXTNAME","EXTVER","GRPNAME","GRPID#","GRPLC#", "THEAP","TDIM#","T????#"}; fitsfile *mfptr = NULL; if(*status != 0) return(*status); do { /* create a new grouping table in the FITS file pointed to by outptr */ *status = fits_get_num_members(infptr,&nmembers,status); *status = fits_read_key_str(infptr,"GRPNAME",keyvalue,card,status); if(*status == KEY_NO_EXIST) { keyvalue[0] = 0; *status = 0; } prepare_keyvalue(keyvalue); *status = fits_create_group(outfptr,keyvalue,GT_ID_ALL_URI,status); /* save the new grouping table's HDU position for future use */ fits_get_hdu_num(outfptr,&groupHDUnum); /* update the HDUtracker struct with the grouping table's new position */ *status = fftsud(infptr,HDU,groupHDUnum,NULL); /* Now populate the copied grouping table depending upon the copy option parameter value */ switch(cpopt) { /* for the "copy grouping table only" option we only have to add the members of the original grouping table to the new grouping table */ case OPT_GCP_GPT: for(i = 1; i <= nmembers && *status == 0; ++i) { *status = fits_open_member(infptr,i,&mfptr,status); *status = fits_add_group_member(outfptr,mfptr,0,status); fits_close_file(mfptr,status); mfptr = NULL; } break; case OPT_GCP_ALL: /* for the "copy the entire group" option */ /* loop over all the grouping table members */ for(i = 1; i <= nmembers && *status == 0; ++i) { /* open the ith member */ *status = fits_open_member(infptr,i,&mfptr,status); if(*status != 0) continue; /* add it to the HDUtracker struct */ *status = fftsad(mfptr,HDU,&newPosition,NULL); /* if already copied then just add the member to the group */ if(*status == HDU_ALREADY_TRACKED) { *status = 0; *status = fits_add_group_member(outfptr,NULL,newPosition, status); fits_close_file(mfptr,status); mfptr = NULL; continue; } else if(*status != 0) continue; /* see if the member is a grouping table */ *status = fits_read_key_str(mfptr,"EXTNAME",keyvalue,card, status); if(*status == KEY_NO_EXIST) { keyvalue[0] = 0; *status = 0; } prepare_keyvalue(keyvalue); /* if the member is a grouping table then copy it and all of its members using ffgtcpr(), else copy it using fits_copy_member(); the outptr will point to the newly copied member upon return from both functions */ if(strcasecmp(keyvalue,"GROUPING") == 0) *status = ffgtcpr(mfptr,outfptr,OPT_GCP_ALL,HDU,status); else *status = fits_copy_member(infptr,outfptr,i,OPT_MCP_NADD, status); /* retrieve the position of the newly copied member */ fits_get_hdu_num(outfptr,&newPosition); /* update the HDUtracker struct with member's new position */ if(strcasecmp(keyvalue,"GROUPING") != 0) *status = fftsud(mfptr,HDU,newPosition,NULL); /* move the outfptr back to the copied grouping table HDU */ *status = fits_movabs_hdu(outfptr,groupHDUnum,&hdutype,status); /* add the copied member HDU to the copied grouping table */ *status = fits_add_group_member(outfptr,NULL,newPosition,status); /* close the mfptr pointer */ fits_close_file(mfptr,status); mfptr = NULL; } break; default: *status = BAD_OPTION; ffpmsg("Invalid value specified for cmopt parameter (ffgtcpr)"); break; } if(*status != 0) continue; /* reposition the outfptr to the grouping table so that the grouping table is the CHDU upon return to the calling function */ fits_movabs_hdu(outfptr,groupHDUnum,&hdutype,status); /* copy all auxiliary keyword records from the original grouping table to the new grouping table; they are copied in their original order and inserted just before the TTYPE1 keyword record */ *status = fits_read_card(outfptr,"TTYPE1",card,status); *status = fits_get_hdrpos(outfptr,&numkeys,&keypos,status); --keypos; startSearch = 8; while(*status == 0) { ffgrec(infptr,startSearch,card,status); *status = fits_find_nextkey(infptr,includeList,1,excludeList, nexclude,card,status); *status = fits_get_hdrpos(infptr,&numkeys,&startSearch,status); --startSearch; /* SPR 1738 */ if (strncmp(card,"GRPLC",5)) { /* Not going to be a long string so we're ok */ *status = fits_insert_record(outfptr,keypos,card,status); } else { /* We could have a long string */ *status = fits_read_record(infptr,startSearch,card,status); card[9] = '\0'; *status = fits_read_key_longstr(infptr,card,&tkeyvalue,comment, status); if (0 == *status) { fits_insert_key_longstr(outfptr,card,tkeyvalue,comment,status); fits_write_key_longwarn(outfptr,status); free(tkeyvalue); } } ++keypos; } if(*status == KEY_NO_EXIST) *status = 0; else if(*status != 0) continue; /* search all the columns of the original grouping table and copy those to the new grouping table that were not part of the grouping convention. Note that is legal to have additional columns in a grouping table. Also note that the order of the columns may not be the same in the original and copied grouping table. */ /* retrieve the number of columns in the original and new group tables */ *status = fits_read_key_lng(infptr,"TFIELDS",&tfields,card,status); *status = fits_read_key_lng(outfptr,"TFIELDS",&newTfields,card,status); for(i = 1; i <= tfields; ++i) { sprintf(keyword,"TTYPE%d",i); *status = fits_read_key_str(infptr,keyword,keyvalue,card,status); if(*status == KEY_NO_EXIST) { *status = 0; keyvalue[0] = 0; } prepare_keyvalue(keyvalue); if(strcasecmp(keyvalue,"MEMBER_XTENSION") != 0 && strcasecmp(keyvalue,"MEMBER_NAME") != 0 && strcasecmp(keyvalue,"MEMBER_VERSION") != 0 && strcasecmp(keyvalue,"MEMBER_POSITION") != 0 && strcasecmp(keyvalue,"MEMBER_LOCATION") != 0 && strcasecmp(keyvalue,"MEMBER_URI_TYPE") != 0 ) { /* SPR 3956, add at the end of the table */ *status = fits_copy_col(infptr,outfptr,i,newTfields+1,1,status); ++newTfields; } } }while(0); if(mfptr != NULL) { fits_close_file(mfptr,status); } return(*status); } /*-------------------------------------------------------------------------- HDUtracker struct manipulation functions --------------------------------------------------------------------------*/ int fftsad(fitsfile *mfptr, /* pointer to an member HDU */ HDUtracker *HDU, /* pointer to an HDU tracker struct */ int *newPosition, /* new HDU position of the member HDU */ char *newFileName) /* file containing member HDU */ /* add an HDU to the HDUtracker struct pointed to by HDU. The HDU is only added if it does not already reside in the HDUtracker. If it already resides in the HDUtracker then the new HDU postion and file name are returned in newPosition and newFileName (if != NULL) */ { int i; int hdunum; int status = 0; char filename1[FLEN_FILENAME]; char filename2[FLEN_FILENAME]; do { /* retrieve the HDU's position within the FITS file */ fits_get_hdu_num(mfptr,&hdunum); /* retrieve the HDU's file name */ status = fits_file_name(mfptr,filename1,&status); /* parse the file name and construct the "standard" URL for it */ status = ffrtnm(filename1,filename2,&status); /* examine all the existing HDUs in the HDUtracker an see if this HDU has already been registered */ for(i = 0; i < HDU->nHDU && !(HDU->position[i] == hdunum && strcmp(HDU->filename[i],filename2) == 0); ++i); if(i != HDU->nHDU) { status = HDU_ALREADY_TRACKED; if(newPosition != NULL) *newPosition = HDU->newPosition[i]; if(newFileName != NULL) strcpy(newFileName,HDU->newFilename[i]); continue; } if(HDU->nHDU == MAX_HDU_TRACKER) { status = TOO_MANY_HDUS_TRACKED; continue; } HDU->filename[i] = (char*) malloc(FLEN_FILENAME * sizeof(char)); if(HDU->filename[i] == NULL) { status = MEMORY_ALLOCATION; continue; } HDU->newFilename[i] = (char*) malloc(FLEN_FILENAME * sizeof(char)); if(HDU->newFilename[i] == NULL) { status = MEMORY_ALLOCATION; free(HDU->filename[i]); continue; } HDU->position[i] = hdunum; HDU->newPosition[i] = hdunum; strcpy(HDU->filename[i],filename2); strcpy(HDU->newFilename[i],filename2); ++(HDU->nHDU); }while(0); return(status); } /*--------------------------------------------------------------------------*/ int fftsud(fitsfile *mfptr, /* pointer to an member HDU */ HDUtracker *HDU, /* pointer to an HDU tracker struct */ int newPosition, /* new HDU position of the member HDU */ char *newFileName) /* file containing member HDU */ /* update the HDU information in the HDUtracker struct pointed to by HDU. The HDU to update is pointed to by mfptr. If non-zero, the value of newPosition is used to update the HDU->newPosition[] value for the mfptr, and if non-NULL the newFileName value is used to update the HDU->newFilename[] value for mfptr. */ { int i; int hdunum; int status = 0; char filename1[FLEN_FILENAME]; char filename2[FLEN_FILENAME]; /* retrieve the HDU's position within the FITS file */ fits_get_hdu_num(mfptr,&hdunum); /* retrieve the HDU's file name */ status = fits_file_name(mfptr,filename1,&status); /* parse the file name and construct the "standard" URL for it */ status = ffrtnm(filename1,filename2,&status); /* examine all the existing HDUs in the HDUtracker an see if this HDU has already been registered */ for(i = 0; i < HDU->nHDU && !(HDU->position[i] == hdunum && strcmp(HDU->filename[i],filename2) == 0); ++i); /* if previously registered then change newPosition and newFileName */ if(i != HDU->nHDU) { if(newPosition != 0) HDU->newPosition[i] = newPosition; if(newFileName != NULL) { strcpy(HDU->newFilename[i],newFileName); } } else status = MEMBER_NOT_FOUND; return(status); } /*---------------------------------------------------------------------------*/ void prepare_keyvalue(char *keyvalue) /* string containing keyword value */ /* strip off all single quote characters "'" and blank spaces from a keyword value retrieved via fits_read_key*() routines this is necessary so that a standard comparision of keyword values may be made */ { int i; int length; /* strip off any leading or trailing single quotes (`) and (') from the keyword value */ length = strlen(keyvalue) - 1; if(keyvalue[0] == '\'' && keyvalue[length] == '\'') { for(i = 0; i < length - 1; ++i) keyvalue[i] = keyvalue[i+1]; keyvalue[length-1] = 0; } /* strip off any trailing blanks from the keyword value; note that if the keyvalue consists of nothing but blanks then no blanks are stripped */ length = strlen(keyvalue) - 1; for(i = 0; i < length && keyvalue[i] == ' '; ++i); if(i != length) { for(i = length; i >= 0 && keyvalue[i] == ' '; --i) keyvalue[i] = '\0'; } } /*--------------------------------------------------------------------------- Host dependent directory path to/from URL functions --------------------------------------------------------------------------*/ int fits_path2url(char *inpath, /* input file path string */ char *outpath, /* output file path string */ int *status) /* convert a file path into its Unix-style equivelent for URL purposes. Note that this process is platform dependent. This function supports Unix, MSDOS/WIN32, VMS and Macintosh platforms. The plaform dependant code is conditionally compiled depending upon the setting of the appropriate C preprocessor macros. */ { char buff[FLEN_FILENAME]; #if defined(WINNT) || defined(__WINNT__) /* Microsoft Windows NT case. We assume input file paths of the form: //disk/path/filename All path segments may be null, so that a single file name is the simplist case. The leading "//" becomes a single "/" if present. If no "//" is present, then make sure the resulting URL path is relative, i.e., does not begin with a "/". In other words, the only way that an absolute URL file path may be generated is if the drive specification is given. */ if(*status > 0) return(*status); if(inpath[0] == '/') { strcpy(buff,inpath+1); } else { strcpy(buff,inpath); } #elif defined(MSDOS) || defined(__WIN32__) || defined(WIN32) /* MSDOS or Microsoft windows/NT case. The assumed form of the input path is: disk:\path\filename All path segments may be null, so that a single file name is the simplist case. All back-slashes '\' become slashes '/'; if the path starts with a string of the form "X:" then it is replaced with "/X/" */ int i,j,k; int size; if(*status > 0) return(*status); for(i = 0, j = 0, size = strlen(inpath), buff[0] = 0; i < size; j = strlen(buff)) { switch(inpath[i]) { case ':': /* must be a disk desiginator; add a slash '/' at the start of outpath to designate that the path is absolute, then change the colon ':' to a slash '/' */ for(k = j; k >= 0; --k) buff[k+1] = buff[k]; buff[0] = '/'; strcat(buff,"/"); ++i; break; case '\\': /* just replace the '\' with a '/' IF its not the first character */ if(i != 0 && buff[(j == 0 ? 0 : j-1)] != '/') { buff[j] = '/'; buff[j+1] = 0; } ++i; break; default: /* copy the character from inpath to buff as is */ buff[j] = inpath[i]; buff[j+1] = 0; ++i; break; } } #elif defined(VMS) || defined(vms) || defined(__vms) /* VMS case. Assumed format of the input path is: node::disk:[path]filename.ext;version Any part of the file path may be missing, so that in the simplist case a single file name/extension is given. all brackets "[", "]" and dots "." become "/"; dashes "-" become "..", all single colons ":" become ":/", all double colons "::" become "FILE://" */ int i,j,k; int done; int size; if(*status > 0) return(*status); /* see if inpath contains a directory specification */ if(strchr(inpath,']') == NULL) done = 1; else done = 0; for(i = 0, j = 0, size = strlen(inpath), buff[0] = 0; i < size && j < FLEN_FILENAME - 8; j = strlen(buff)) { switch(inpath[i]) { case ':': /* must be a logical/symbol separator or (in the case of a double colon "::") machine node separator */ if(inpath[i+1] == ':') { /* insert a "FILE://" at the start of buff ==> machine given */ for(k = j; k >= 0; --k) buff[k+7] = buff[k]; strncpy(buff,"FILE://",7); i += 2; } else if(strstr(buff,"FILE://") == NULL) { /* insert a "/" at the start of buff ==> absolute path */ for(k = j; k >= 0; --k) buff[k+1] = buff[k]; buff[0] = '/'; ++i; } else ++i; /* a colon always ==> path separator */ strcat(buff,"/"); break; case ']': /* end of directory spec, file name spec begins after this */ done = 1; buff[j] = '/'; buff[j+1] = 0; ++i; break; case '[': /* begin directory specification; add a '/' only if the last char is not '/' */ if(i != 0 && buff[(j == 0 ? 0 : j-1)] != '/') { buff[j] = '/'; buff[j+1] = 0; } ++i; break; case '.': /* directory segment separator or file name/extension separator; we decide which by looking at the value of done */ if(!done) { /* must be a directory segment separator */ if(inpath[i-1] == '[') { strcat(buff,"./"); ++j; } else buff[j] = '/'; } else /* must be a filename/extension separator */ buff[j] = '.'; buff[j+1] = 0; ++i; break; case '-': /* a dash is the same as ".." in Unix speak, but lets make sure that its not part of the file name first! */ if(!done) /* must be part of the directory path specification */ strcat(buff,".."); else { /* the dash is part of the filename, so just copy it as is */ buff[j] = '-'; buff[j+1] = 0; } ++i; break; default: /* nothing special, just copy the character as is */ buff[j] = inpath[i]; buff[j+1] = 0; ++i; break; } } if(j > FLEN_FILENAME - 8) { *status = URL_PARSE_ERROR; ffpmsg("resulting path to URL conversion too big (fits_path2url)"); } #elif defined(macintosh) /* MacOS case. The assumed form of the input path is: disk:path:filename It is assumed that all paths are absolute with disk and path specified, unless no colons ":" are supplied with the string ==> a single file name only. All colons ":" become slashes "/", and if one or more colon is encountered then the path is specified as absolute. */ int i,j,k; int firstColon; int size; if(*status > 0) return(*status); for(i = 0, j = 0, firstColon = 1, size = strlen(inpath), buff[0] = 0; i < size; j = strlen(buff)) { switch(inpath[i]) { case ':': /* colons imply path separators. If its the first colon encountered then assume that its the disk designator and add a slash to the beginning of the buff string */ if(firstColon) { firstColon = 0; for(k = j; k >= 0; --k) buff[k+1] = buff[k]; buff[0] = '/'; } /* all colons become slashes */ strcat(buff,"/"); ++i; break; default: /* copy the character from inpath to buff as is */ buff[j] = inpath[i]; buff[j+1] = 0; ++i; break; } } #else /* Default Unix case. Nothing special to do here except to remove the double or more // and replace them with single / */ int ii = 0; int jj = 0; if(*status > 0) return(*status); while (inpath[ii]) { if (inpath[ii] == '/' && inpath[ii+1] == '/') { /* do nothing */ } else { buff[jj] = inpath[ii]; jj++; } ii++; } buff[jj] = '\0'; /* printf("buff is %s\ninpath is %s\n",buff,inpath); */ /* strcpy(buff,inpath); */ #endif /* encode all "unsafe" and "reserved" URL characters */ *status = fits_encode_url(buff,outpath,status); return(*status); } /*---------------------------------------------------------------------------*/ int fits_url2path(char *inpath, /* input file path string */ char *outpath, /* output file path string */ int *status) /* convert a Unix-style URL into a platform dependent directory path. Note that this process is platform dependent. This function supports Unix, MSDOS/WIN32, VMS and Macintosh platforms. Each platform dependent code segment is conditionally compiled depending upon the setting of the appropriate C preprocesser macros. */ { char buff[FLEN_FILENAME]; int absolute; #if defined(MSDOS) || defined(__WIN32__) || defined(WIN32) char *tmpStr; #elif defined(VMS) || defined(vms) || defined(__vms) int i; char *tmpStr; #elif defined(macintosh) char *tmpStr; #endif if(*status != 0) return(*status); /* make a copy of the inpath so that we can manipulate it */ strcpy(buff,inpath); /* convert any encoded characters to their unencoded values */ *status = fits_unencode_url(inpath,buff,status); /* see if the URL is given as absolute w.r.t. the "local" file system */ if(buff[0] == '/') absolute = 1; else absolute = 0; #if defined(WINNT) || defined(__WINNT__) /* Microsoft Windows NT case. We create output paths of the form //disk/path/filename All path segments but the last may be null, so that a single file name is the simplist case. */ if(absolute) { strcpy(outpath,"/"); strcat(outpath,buff); } else { strcpy(outpath,buff); } #elif defined(MSDOS) || defined(__WIN32__) || defined(WIN32) /* MSDOS or Microsoft windows/NT case. The output path will be of the form disk:\path\filename All path segments but the last may be null, so that a single file name is the simplist case. */ /* separate the URL into tokens at each slash '/' and process until all tokens have been examined */ for(tmpStr = strtok(buff,"/"), outpath[0] = 0; tmpStr != NULL; tmpStr = strtok(NULL,"/")) { strcat(outpath,tmpStr); /* if the absolute flag is set then process the token as a disk specification; else just process it as a directory path or filename */ if(absolute) { strcat(outpath,":\\"); absolute = 0; } else strcat(outpath,"\\"); } /* remove the last "\" from the outpath, it does not belong there */ outpath[strlen(outpath)-1] = 0; #elif defined(VMS) || defined(vms) || defined(__vms) /* VMS case. The output path will be of the form: node::disk:[path]filename.ext;version Any part of the file path may be missing execpt filename.ext, so that in the simplist case a single file name/extension is given. if the path is specified as relative starting with "./" then the first part of the VMS path is "[.". If the path is relative and does not start with "./" (e.g., "a/b/c") then the VMS path is constructed as "[a.b.c]" */ /* separate the URL into tokens at each slash '/' and process until all tokens have been examined */ for(tmpStr = strtok(buff,"/"), outpath[0] = 0; tmpStr != NULL; tmpStr = strtok(NULL,"/")) { if(strcasecmp(tmpStr,"FILE:") == 0) { /* the next token should contain the DECnet machine name */ tmpStr = strtok(NULL,"/"); if(tmpStr == NULL) continue; strcat(outpath,tmpStr); strcat(outpath,"::"); /* set the absolute flag to true for the next token */ absolute = 1; } else if(strcmp(tmpStr,"..") == 0) { /* replace all Unix-like ".." with VMS "-" */ if(strlen(outpath) == 0) strcat(outpath,"["); strcat(outpath,"-."); } else if(strcmp(tmpStr,".") == 0 && strlen(outpath) == 0) { /* must indicate a relative path specifier */ strcat(outpath,"[."); } else if(strchr(tmpStr,'.') != NULL) { /* must be up to the file name; turn the last "." path separator into a "]" and then add the file name to the outpath */ i = strlen(outpath); if(i > 0 && outpath[i-1] == '.') outpath[i-1] = ']'; strcat(outpath,tmpStr); } else { /* process the token as a a directory path segement */ if(absolute) { /* treat the token as a disk specifier */ absolute = 0; strcat(outpath,tmpStr); strcat(outpath,":["); } else if(strlen(outpath) == 0) { /* treat the token as the first directory path specifier */ strcat(outpath,"["); strcat(outpath,tmpStr); strcat(outpath,"."); } else { /* treat the token as an imtermediate path specifier */ strcat(outpath,tmpStr); strcat(outpath,"."); } } } #elif defined(macintosh) /* MacOS case. The output path will be of the form disk:path:filename All path segments but the last may be null, so that a single file name is the simplist case. */ /* separate the URL into tokens at each slash '/' and process until all tokens have been examined */ for(tmpStr = strtok(buff,"/"), outpath[0] = 0; tmpStr != NULL; tmpStr = strtok(NULL,"/")) { strcat(outpath,tmpStr); strcat(outpath,":"); } /* remove the last ":" from the outpath, it does not belong there */ outpath[strlen(outpath)-1] = 0; #else /* Default Unix case. Nothing special to do here */ strcpy(outpath,buff); #endif return(*status); } /****************************************************************************/ int fits_get_cwd(char *cwd, /* IO current working directory string */ int *status) /* retrieve the string containing the current working directory absolute path in Unix-like URL standard notation. It is assumed that the CWD string has a size of at least FLEN_FILENAME. Note that this process is platform dependent. This function supports Unix, MSDOS/WIN32, VMS and Macintosh platforms. Each platform dependent code segment is conditionally compiled depending upon the setting of the appropriate C preprocesser macros. */ { char buff[FLEN_FILENAME]; if(*status != 0) return(*status); #if defined(macintosh) /* MacOS case. Currently unknown !!!! */ *buff = 0; #else /* Good old getcwd() seems to work with all other platforms */ getcwd(buff,FLEN_FILENAME); #endif /* convert the cwd string to a URL standard path string */ fits_path2url(buff,cwd,status); return(*status); } /*---------------------------------------------------------------------------*/ int fits_get_url(fitsfile *fptr, /* I ptr to FITS file to evaluate */ char *realURL, /* O URL of real FITS file */ char *startURL, /* O URL of starting FITS file */ char *realAccess, /* O true access method of FITS file */ char *startAccess,/* O "official" access of FITS file */ int *iostate, /* O can this file be modified? */ int *status) /* For grouping convention purposes, determine the URL of the FITS file associated with the fitsfile pointer fptr. The true access type (file://, mem://, shmem://, root://), starting "official" access type, and iostate (0 ==> readonly, 1 ==> readwrite) are also returned. It is assumed that the url string has enough room to hold the resulting URL, and the the accessType string has enough room to hold the access type. */ { int i; int tmpIOstate = 0; char infile[FLEN_FILENAME]; char outfile[FLEN_FILENAME]; char tmpStr1[FLEN_FILENAME]; char tmpStr2[FLEN_FILENAME]; char tmpStr3[FLEN_FILENAME]; char tmpStr4[FLEN_FILENAME]; char *tmpPtr; if(*status != 0) return(*status); do { /* retrieve the member HDU's file name as opened by ffopen() and parse it into its constitutent pieces; get the currently active driver token too */ *tmpStr1 = *tmpStr2 = *tmpStr3 = *tmpStr4 = 0; *status = fits_file_name(fptr,tmpStr1,status); *status = ffiurl(tmpStr1,NULL,infile,outfile,NULL,tmpStr2,tmpStr3, tmpStr4,status); if((*tmpStr2) || (*tmpStr3) || (*tmpStr4)) tmpIOstate = -1; *status = ffurlt(fptr,tmpStr3,status); strcpy(tmpStr4,tmpStr3); *status = ffrtnm(tmpStr1,tmpStr2,status); strcpy(tmpStr1,tmpStr2); /* for grouping convention purposes (only) determine the URL of the actual FITS file being used for the given fptr, its true access type (file://, mem://, shmem://, root://) and its iostate (0 ==> read only, 1 ==> readwrite) */ /* The first set of access types are "simple" in that they do not use any redirection to temporary memory or outfiles */ /* standard disk file driver is in use */ if(strcasecmp(tmpStr3,"file://") == 0) { tmpIOstate = 1; if(strlen(outfile)) strcpy(tmpStr1,outfile); else *tmpStr2 = 0; /* make sure no FILE:// specifier is given in the tmpStr1 or tmpStr2 strings; the convention calls for local files to have no access specification */ if((tmpPtr = strstr(tmpStr1,"://")) != NULL) { strcpy(infile,tmpPtr+3); strcpy(tmpStr1,infile); } if((tmpPtr = strstr(tmpStr2,"://")) != NULL) { strcpy(infile,tmpPtr+3); strcpy(tmpStr2,infile); } } /* file stored in conventional memory */ else if(strcasecmp(tmpStr3,"mem://") == 0) { if(tmpIOstate < 0) { /* file is a temp mem file only */ ffpmsg("cannot make URL from temp MEM:// file (fits_get_url)"); *status = URL_PARSE_ERROR; } else { /* file is a "perminate" mem file for this process */ tmpIOstate = 1; *tmpStr2 = 0; } } /* file stored in conventional memory */ else if(strcasecmp(tmpStr3,"memkeep://") == 0) { strcpy(tmpStr3,"mem://"); *tmpStr4 = 0; *tmpStr2 = 0; tmpIOstate = 1; } /* file residing in shared memory */ else if(strcasecmp(tmpStr3,"shmem://") == 0) { *tmpStr4 = 0; *tmpStr2 = 0; tmpIOstate = 1; } /* file accessed via the ROOT network protocol */ else if(strcasecmp(tmpStr3,"root://") == 0) { *tmpStr4 = 0; *tmpStr2 = 0; tmpIOstate = 1; } /* the next set of access types redirect the contents of the original file to an special outfile because the original could not be directly modified (i.e., resides on the network, was compressed). In these cases the URL string takes on the value of the OUTFILE, the access type becomes file://, and the iostate is set to 1 (can read/write to the file). */ /* compressed file uncompressed and written to disk */ else if(strcasecmp(tmpStr3,"compressfile://") == 0) { strcpy(tmpStr1,outfile); strcpy(tmpStr2,infile); strcpy(tmpStr3,"file://"); strcpy(tmpStr4,"file://"); tmpIOstate = 1; } /* HTTP accessed file written locally to disk */ else if(strcasecmp(tmpStr3,"httpfile://") == 0) { strcpy(tmpStr1,outfile); strcpy(tmpStr3,"file://"); strcpy(tmpStr4,"http://"); tmpIOstate = 1; } /* FTP accessd file written locally to disk */ else if(strcasecmp(tmpStr3,"ftpfile://") == 0) { strcpy(tmpStr1,outfile); strcpy(tmpStr3,"file://"); strcpy(tmpStr4,"ftp://"); tmpIOstate = 1; } /* file from STDIN written to disk */ else if(strcasecmp(tmpStr3,"stdinfile://") == 0) { strcpy(tmpStr1,outfile); strcpy(tmpStr3,"file://"); strcpy(tmpStr4,"stdin://"); tmpIOstate = 1; } /* the following access types use memory resident files as temporary storage; they cannot be modified or be made group members for grouping conventions purposes, but their original files can be. Thus, their tmpStr3s are reset to mem://, their iostate values are set to 0 (for no-modification), and their URL string values remain set to their original values */ /* compressed disk file uncompressed into memory */ else if(strcasecmp(tmpStr3,"compress://") == 0) { *tmpStr1 = 0; strcpy(tmpStr2,infile); strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"file://"); tmpIOstate = 0; } /* HTTP accessed file transferred into memory */ else if(strcasecmp(tmpStr3,"http://") == 0) { *tmpStr1 = 0; strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"http://"); tmpIOstate = 0; } /* HTTP accessed compressed file transferred into memory */ else if(strcasecmp(tmpStr3,"httpcompress://") == 0) { *tmpStr1 = 0; strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"http://"); tmpIOstate = 0; } /* FTP accessed file transferred into memory */ else if(strcasecmp(tmpStr3,"ftp://") == 0) { *tmpStr1 = 0; strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"ftp://"); tmpIOstate = 0; } /* FTP accessed compressed file transferred into memory */ else if(strcasecmp(tmpStr3,"ftpcompress://") == 0) { *tmpStr1 = 0; strcpy(tmpStr3,"mem://"); strcpy(tmpStr4,"ftp://"); tmpIOstate = 0; } /* The last set of access types cannot be used to make a meaningful URL strings from; thus an error is generated */ else if(strcasecmp(tmpStr3,"stdin://") == 0) { *status = URL_PARSE_ERROR; ffpmsg("cannot make vaild URL from stdin:// (fits_get_url)"); *tmpStr1 = *tmpStr2 = 0; } else if(strcasecmp(tmpStr3,"stdout://") == 0) { *status = URL_PARSE_ERROR; ffpmsg("cannot make vaild URL from stdout:// (fits_get_url)"); *tmpStr1 = *tmpStr2 = 0; } else if(strcasecmp(tmpStr3,"irafmem://") == 0) { *status = URL_PARSE_ERROR; ffpmsg("cannot make vaild URL from irafmem:// (fits_get_url)"); *tmpStr1 = *tmpStr2 = 0; } if(*status != 0) continue; /* assign values to the calling parameters if they are non-NULL */ if(realURL != NULL) { if(strlen(tmpStr1) == 0) *realURL = 0; else { if((tmpPtr = strstr(tmpStr1,"://")) != NULL) { tmpPtr += 3; i = (long)tmpPtr - (long)tmpStr1; strncpy(realURL,tmpStr1,i); } else { tmpPtr = tmpStr1; i = 0; } *status = fits_path2url(tmpPtr,realURL+i,status); } } if(startURL != NULL) { if(strlen(tmpStr2) == 0) *startURL = 0; else { if((tmpPtr = strstr(tmpStr2,"://")) != NULL) { tmpPtr += 3; i = (long)tmpPtr - (long)tmpStr2; strncpy(startURL,tmpStr2,i); } else { tmpPtr = tmpStr2; i = 0; } *status = fits_path2url(tmpPtr,startURL+i,status); } } if(realAccess != NULL) strcpy(realAccess,tmpStr3); if(startAccess != NULL) strcpy(startAccess,tmpStr4); if(iostate != NULL) *iostate = tmpIOstate; }while(0); return(*status); } /*-------------------------------------------------------------------------- URL parse support functions --------------------------------------------------------------------------*/ /* simple push/pop/shift/unshift string stack for use by fits_clean_url */ typedef char* grp_stack_data; /* type of data held by grp_stack */ typedef struct grp_stack_item_struct { grp_stack_data data; /* value of this stack item */ struct grp_stack_item_struct* next; /* next stack item */ struct grp_stack_item_struct* prev; /* previous stack item */ } grp_stack_item; typedef struct grp_stack_struct { size_t stack_size; /* number of items on stack */ grp_stack_item* top; /* top item */ } grp_stack; static char* grp_stack_default = NULL; /* initial value for new instances of grp_stack_data */ /* the following functions implement the group string stack grp_stack */ static void delete_grp_stack(grp_stack** mystack); static grp_stack_item* grp_stack_append( grp_stack_item* last, grp_stack_data data ); static grp_stack_data grp_stack_remove(grp_stack_item* last); static grp_stack* new_grp_stack(void); static grp_stack_data pop_grp_stack(grp_stack* mystack); static void push_grp_stack(grp_stack* mystack, grp_stack_data data); static grp_stack_data shift_grp_stack(grp_stack* mystack); /* static void unshift_grp_stack(grp_stack* mystack, grp_stack_data data); */ int fits_clean_url(char *inURL, /* I input URL string */ char *outURL, /* O output URL string */ int *status) /* clean the URL by eliminating any ".." or "." specifiers in the inURL string, and write the output to the outURL string. Note that this function must have a valid Unix-style URL as input; platform dependent path strings are not allowed. */ { grp_stack* mystack; /* stack to hold pieces of URL */ char* tmp; if(*status) return *status; mystack = new_grp_stack(); *outURL = 0; do { /* handle URL scheme and domain if they exist */ tmp = strstr(inURL, "://"); if(tmp) { /* there is a URL scheme, so look for the end of the domain too */ tmp = strchr(tmp + 3, '/'); if(tmp) { /* tmp is now the end of the domain, so * copy URL scheme and domain as is, and terminate by hand */ size_t string_size = (size_t) (tmp - inURL); strncpy(outURL, inURL, string_size); outURL[string_size] = 0; /* now advance the input pointer to just after the domain and go on */ inURL = tmp; } else { /* '/' was not found, which means there are no path-like * portions, so copy whole inURL to outURL and we're done */ strcpy(outURL, inURL); continue; /* while(0) */ } } /* explicitly copy a leading / (absolute path) */ if('/' == *inURL) strcat(outURL, "/"); /* now clean the remainder of the inURL. push URL segments onto * stack, dealing with .. and . as we go */ tmp = strtok(inURL, "/"); /* finds first / */ while(tmp) { if(!strcmp(tmp, "..")) { /* discard previous URL segment, if there was one. if not, * add the .. to the stack if this is *not* an absolute path * (for absolute paths, leading .. has no effect, so skip it) */ if(0 < mystack->stack_size) pop_grp_stack(mystack); else if('/' != *inURL) push_grp_stack(mystack, tmp); } else { /* always just skip ., but otherwise add segment to stack */ if(strcmp(tmp, ".")) push_grp_stack(mystack, tmp); } tmp = strtok(NULL, "/"); /* get the next segment */ } /* stack now has pieces of cleaned URL, so just catenate them * onto output string until stack is empty */ while(0 < mystack->stack_size) { tmp = shift_grp_stack(mystack); strcat(outURL, tmp); strcat(outURL, "/"); } outURL[strlen(outURL) - 1] = 0; /* blank out trailing / */ } while(0); delete_grp_stack(&mystack); return *status; } /* free all stack contents using pop_grp_stack before freeing the * grp_stack itself */ static void delete_grp_stack(grp_stack** mystack) { if(!mystack || !*mystack) return; while((*mystack)->stack_size) pop_grp_stack(*mystack); free(*mystack); *mystack = NULL; } /* append an item to the stack, handling the special case of the first * item appended */ static grp_stack_item* grp_stack_append( grp_stack_item* last, grp_stack_data data ) { /* first create a new stack item, and copy data to it */ grp_stack_item* new_item = (grp_stack_item*) malloc(sizeof(grp_stack_item)); new_item->data = data; if(last) { /* attach this item between the "last" item and its "next" item */ new_item->next = last->next; new_item->prev = last; last->next->prev = new_item; last->next = new_item; } else { /* stack is empty, so "next" and "previous" both point back to it */ new_item->next = new_item; new_item->prev = new_item; } return new_item; } /* remove an item from the stack, handling the special case of the last * item removed */ static grp_stack_data grp_stack_remove(grp_stack_item* last) { grp_stack_data retval = last->data; last->prev->next = last->next; last->next->prev = last->prev; free(last); return retval; } /* create new stack dynamically, and give it valid initial values */ static grp_stack* new_grp_stack(void) { grp_stack* retval = (grp_stack*) malloc(sizeof(grp_stack)); if(retval) { retval->stack_size = 0; retval->top = NULL; } return retval; } /* return the value at the top of the stack and remove it, updating * stack_size. top->prev becomes the new "top" */ static grp_stack_data pop_grp_stack(grp_stack* mystack) { grp_stack_data retval = grp_stack_default; if(mystack && mystack->top) { grp_stack_item* newtop = mystack->top->prev; retval = grp_stack_remove(mystack->top); mystack->top = newtop; if(0 == --mystack->stack_size) mystack->top = NULL; } return retval; } /* add to the stack after the top element. the added element becomes * the new "top" */ static void push_grp_stack(grp_stack* mystack, grp_stack_data data) { if(!mystack) return; mystack->top = grp_stack_append(mystack->top, data); ++mystack->stack_size; return; } /* return the value at the bottom of the stack and remove it, updating * stack_size. "top" pointer is unaffected */ static grp_stack_data shift_grp_stack(grp_stack* mystack) { grp_stack_data retval = grp_stack_default; if(mystack && mystack->top) { retval = grp_stack_remove(mystack->top->next); /* top->next == bottom */ if(0 == --mystack->stack_size) mystack->top = NULL; } return retval; } /* add to the stack after the top element. "top" is unaffected, except * in the special case of an initially empty stack */ /* static void unshift_grp_stack(grp_stack* mystack, grp_stack_data data) { if(!mystack) return; if(mystack->top) grp_stack_append(mystack->top, data); else mystack->top = grp_stack_append(NULL, data); ++mystack->stack_size; return; } */ /*--------------------------------------------------------------------------*/ int fits_url2relurl(char *refURL, /* I reference URL string */ char *absURL, /* I absoulute URL string to process */ char *relURL, /* O resulting relative URL string */ int *status) /* create a relative URL to the file referenced by absURL with respect to the reference URL refURL. The relative URL is returned in relURL. Both refURL and absURL must be absolute URL strings; i.e. either begin with an access method specification "XXX://" or with a '/' character signifiying that they are absolute file paths. Note that it is possible to make a relative URL from two input URLs (absURL and refURL) that are not compatable. This function does not check to see if the resulting relative URL makes any sence. For instance, it is impossible to make a relative URL from the following two inputs: absURL = ftp://a.b.c.com/x/y/z/foo.fits refURL = /a/b/c/ttt.fits The resulting relURL will be: ../../../ftp://a.b.c.com/x/y/z/foo.fits Which is syntically correct but meaningless. The problem is that a file with an access method of ftp:// cannot be expressed a a relative URL to a local disk file. */ { int i,j; int refcount,abscount; int refsize,abssize; int done; if(*status != 0) return(*status); do { /* refURL and absURL must be absolute to process */ if(!(fits_is_url_absolute(refURL) || *refURL == '/') || !(fits_is_url_absolute(absURL) || *absURL == '/')) { *status = URL_PARSE_ERROR; ffpmsg("Cannot make rel. URL from non abs. URLs (fits_url2relurl)"); continue; } /* determine the size of the refURL and absURL strings */ refsize = strlen(refURL); abssize = strlen(absURL); /* process the two URL strings and build the relative URL between them */ for(done = 0, refcount = 0, abscount = 0; !done && refcount < refsize && abscount < abssize; ++refcount, ++abscount) { for(; abscount < abssize && absURL[abscount] == '/'; ++abscount); for(; refcount < refsize && refURL[refcount] == '/'; ++refcount); /* find the next path segment in absURL */ for(i = abscount; absURL[i] != '/' && i < abssize; ++i); /* find the next path segment in refURL */ for(j = refcount; refURL[j] != '/' && j < refsize; ++j); /* do the two path segments match? */ if(i == j && strncmp(absURL+abscount, refURL+refcount,i-refcount) == 0) { /* they match, so ignore them and continue */ abscount = i; refcount = j; continue; } /* we found a difference in the paths in refURL and absURL */ /* initialize the relative URL string */ relURL[0] = 0; /* for every path segment remaining in the refURL string, append a "../" path segment to the relataive URL relURL */ for(j = refcount; j < refsize; ++j) if(refURL[j] == '/') strcat(relURL,"../"); /* copy all remaining characters of absURL to the output relURL */ strcat(relURL,absURL+abscount); /* we are done building the relative URL */ done = 1; } }while(0); return(*status); } /*--------------------------------------------------------------------------*/ int fits_relurl2url(char *refURL, /* I reference URL string */ char *relURL, /* I relative URL string to process */ char *absURL, /* O absolute URL string */ int *status) /* create an absolute URL from a relative url and a reference URL. The reference URL is given by the FITS file pointed to by fptr. The construction of the absolute URL from the partial and reference URl is performed using the rules set forth in: http://www.w3.org/Addressing/URL/URL_TOC.html and http://www.w3.org/Addressing/URL/4_3_Partial.html Note that the relative URL string relURL must conform to the Unix-like URL syntax; host dependent partial URL strings are not allowed. */ { int i; char tmpStr[FLEN_FILENAME]; char *tmpStr1, *tmpStr2; if(*status != 0) return(*status); do { /* make a copy of the reference URL string refURL for parsing purposes */ strcpy(tmpStr,refURL); /* if the reference file has an access method of mem:// or shmem:// then we cannot use it as the basis of an absolute URL construction for a partial URL */ if(strncasecmp(tmpStr,"MEM:",4) == 0 || strncasecmp(tmpStr,"SHMEM:",6) == 0) { ffpmsg("ref URL has access mem:// or shmem:// (fits_relurl2url)"); ffpmsg(" cannot construct full URL from a partial URL and "); ffpmsg(" MEM/SHMEM base URL"); *status = URL_PARSE_ERROR; continue; } if(relURL[0] != '/') { /* just append the relative URL string to the reference URL string (minus the reference URL file name) to form the absolute URL string */ tmpStr1 = strrchr(tmpStr,'/'); if(tmpStr1 != NULL) tmpStr1[1] = 0; else tmpStr[0] = 0; strcat(tmpStr,relURL); } else { /* have to parse the refURL string for the first occurnace of the same number of '/' characters as contained in the beginning of location that is not followed by a greater number of consective '/' charaters (yes, that is a confusing statement); this is the location in the refURL string where the relURL string is to be appended to form the new absolute URL string */ /* first, build up a slash pattern string that has one more slash in it than the starting slash pattern of the relURL string */ strcpy(absURL,"/"); for(i = 0; relURL[i] == '/'; ++i) strcat(absURL,"/"); /* loop over the refURL string until the slash pattern stored in absURL is no longer found */ for(tmpStr1 = tmpStr, i = strlen(absURL); (tmpStr2 = strstr(tmpStr1,absURL)) != NULL; tmpStr1 = tmpStr2 + i); /* reduce the slash pattern string by one slash */ absURL[i-1] = 0; /* search for the slash pattern in the remaining portion of the refURL string */ tmpStr2 = strstr(tmpStr1,absURL); /* if no slash pattern match was found */ if(tmpStr2 == NULL) { /* just strip off the file name from the refURL */ tmpStr2 = strrchr(tmpStr1,'/'); if(tmpStr2 != NULL) tmpStr2[0] = 0; else tmpStr[0] = 0; } else { /* set a string terminator at the slash pattern match */ *tmpStr2 = 0; } /* conatenate the relURL string to the refURL string to form the absURL */ strcat(tmpStr,relURL); } /* normalize the absURL by removing any ".." or "." specifiers in the string */ *status = fits_clean_url(tmpStr,absURL,status); }while(0); return(*status); } /*--------------------------------------------------------------------------*/ int fits_encode_url(char *inpath, /* I URL to be encoded */ char *outpath, /* O output encoded URL */ int *status) /* encode all URL "unsafe" and "reserved" characters using the "%XX" convention, where XX stand for the two hexidecimal digits of the encode character's ASCII code. Note that the output path is at least as large as, if not larger than the input path, so that OUTPATH should be passed to this function with room for growth. If not a runtime error could result. It is assumed that OUTPATH has been allocated with enough room to hold the resulting encoded URL. This function was adopted from code in the libwww.a library available via the W3 consortium */ { unsigned char a; char *p; char *q; char *hex = "0123456789ABCDEF"; unsigned const char isAcceptable[96] = {/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xA 0xB 0xC 0xD 0xE 0xF */ 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xF,0xE,0x0,0xF,0xF,0xC, /* 2x !"#$%&'()*+,-./ */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0x8,0x0,0x0,0x0,0x0,0x0, /* 3x 0123456789:;<=>? */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF, /* 4x @ABCDEFGHIJKLMNO */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0x0,0x0,0x0,0x0,0xF, /* 5X PQRSTUVWXYZ[\]^_ */ 0x0,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF, /* 6x `abcdefghijklmno */ 0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0xF,0x0,0x0,0x0,0x0,0x0 /* 7X pqrstuvwxyz{\}~DEL */ }; if(*status != 0) return(*status); /* loop over all characters in inpath until '\0' is encountered */ for(q = outpath, p = inpath; *p; p++) { a = (unsigned char)*p; /* if the charcter requires encoding then process it */ if(!( a>=32 && a<128 && (isAcceptable[a-32]))) { /* add a '%' character to the outpath */ *q++ = HEX_ESCAPE; /* add the most significant ASCII code hex value */ *q++ = hex[a >> 4]; /* add the least significant ASCII code hex value */ *q++ = hex[a & 15]; } /* else just copy the character as is */ else *q++ = *p; } /* null terminate the outpath string */ *q++ = 0; return(*status); } /*---------------------------------------------------------------------------*/ int fits_unencode_url(char *inpath, /* I input URL with encoding */ char *outpath, /* O unencoded URL */ int *status) /* unencode all URL "unsafe" and "reserved" characters to their actual ASCII representation. All tokens of the form "%XX" where XX is the hexidecimal code for an ASCII character, are searched for and translated into the actuall ASCII character (so three chars become 1 char). It is assumed that OUTPATH has enough room to hold the unencoded URL. This function was adopted from code in the libwww.a library available via the W3 consortium */ { char *p; char *q; char c; if(*status != 0) return(*status); p = inpath; q = outpath; /* loop over all characters in the inpath looking for the '%' escape character; if found the process the escape sequence */ while(*p != 0) { /* if the character is '%' then unencode the sequence, else just copy the character from inpath to outpath */ if (*p == HEX_ESCAPE) { if((c = *(++p)) != 0) { *q = ( (c >= '0' && c <= '9') ? (c - '0') : ((c >= 'A' && c <= 'F') ? (c - 'A' + 10) : (c - 'a' + 10)) )*16; if((c = *(++p)) != 0) { *q = *q + ( (c >= '0' && c <= '9') ? (c - '0') : ((c >= 'A' && c <= 'F') ? (c - 'A' + 10) : (c - 'a' + 10)) ); p++, q++; } } } else *q++ = *p++; } /* terminate the outpath */ *q = 0; return(*status); } /*---------------------------------------------------------------------------*/ int fits_is_url_absolute(char *url) /* Return a True (1) or False (0) value indicating whether or not the passed URL string contains an access method specifier or not. Note that this is a boolean function and it neither reads nor returns the standard error status parameter */ { char *tmpStr1, *tmpStr2; char reserved[] = {':',';','/','?','@','&','=','+','$',','}; /* The rule for determing if an URL is relative or absolute is that it (1) must have a colon ":" and (2) that the colon must appear before any other reserved URL character in the URL string. We first see if a colon exists, get its position in the string, and then check to see if any of the other reserved characters exists and if their position in the string is greater than that of the colons. */ if( (tmpStr1 = strchr(url,reserved[0])) != NULL && ((tmpStr2 = strchr(url,reserved[1])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[2])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[3])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[4])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[5])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[6])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[7])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[8])) == NULL || tmpStr2 > tmpStr1) && ((tmpStr2 = strchr(url,reserved[9])) == NULL || tmpStr2 > tmpStr1) ) { return(1); } else { return(0); } } indi-0.5/src/cfitsio/grparser.c0000644000175000017500000013154710610474375014353 0ustar jrjr/* T E M P L A T E P A R S E R ============================= by Jerzy.Borkowski@obs.unige.ch Integral Science Data Center ch. d'Ecogia 16 1290 Versoix Switzerland 14-Oct-98: initial release 16-Oct-98: code cleanup, #include included, now gcc -Wall prints no warnings during compilation. Bugfix: now one can specify additional columns in group HDU. Autoindexing also works in this situation (colunms are number from 7 however). 17-Oct-98: bugfix: complex keywords were incorrectly written (was TCOMPLEX should be TDBLCOMPLEX). 20-Oct-98: bugfix: parser was writing EXTNAME twice, when first HDU in template is defined with XTENSION IMAGE then parser creates now dummy PHDU, SIMPLE T is now allowed only at most once and in first HDU only. WARNING: one should not define EXTNAME keyword for GROUP HDUs, as they have them already defined by parser (EXTNAME = GROUPING). Parser accepts EXTNAME oin GROUP HDU definition, but in this case multiple EXTNAME keywords will present in HDU header. 23-Oct-98: bugfix: unnecessary space was written to FITS file for blank keywords. 24-Oct-98: syntax change: empty lines and lines with only whitespaces are written to FITS files as blank keywords (if inside group/hdu definition). Previously lines had to have at least 8 spaces. Please note, that due to pecularities of CFITSIO if the last keyword(s) defined for given HDU are blank keywords consisting of only 80 spaces, then (some of) those keywords may be silently deleted by CFITSIO. 13-Nov-98: bugfix: parser was writing GRPNAME twice. Parser still creates GRPNAME keywords for GROUP HDU's which do not specify them. However, values (of form DEFAULT_GROUP_XXX) are assigned not necessarily in order HDUs appear in template file, but rather in order parser completes their creation in FITS file. Also, when including files, if fopen fails, parser tries to open file with a name = directory_of_top_level file + name of file to be included, as long as name of file to be included does not specify absolute pathname. 16-Nov-98: bugfix to bugfix from 13-Nov-98 19-Nov-98: EXTVER keyword is now automatically assigned value by parser. 17-Dev-98: 2 new things added: 1st: CFITSIO_INCLUDE_FILES environment variable can contain a colon separated list of directories to look for when looking for template include files (and master template also). 2nd: it is now possible to append template to nonempty FITS. file. fitsfile *ff no longer needs to point to an empty FITS file with 0 HDUs in it. All data written by parser will simple be appended at the end of file. 22-Jan-99: changes to parser: when in append mode parser initially scans all existing HDUs to built a list of already used EXTNAME/EXTVERs 22-Jan-99: Bruce O'Neel, bugfix : TLONG should always reference long type variable on OSF/Alpha and on 64-bit archs in general 20-Jun-2002 Wm Pence, added support for the HIERARCH keyword convention in which keyword names can effectively be longer than 8 characters. Example: HIERARCH LongKeywordName = 'value' / comment 30-Jan-2003 Wm Pence, bugfix: ngp_read_xtension was testing for "ASCIITABLE" instead of "TABLE" as the XTENSION value of an ASCII table, and it did not allow for optional trailing spaces in the "IMAGE" or "TABLE" string. 16-Dec-2003 James Peachey: ngp_keyword_all_write was modified to apply comments from the template file to the output file in the case of reserved keywords (e.g. tform#, ttype# etcetera). */ #include #include #ifdef sparc #include #include #endif #include #include "fitsio2.h" #include "grparser.h" NGP_RAW_LINE ngp_curline = { NULL, NULL, NULL, NGP_TTYPE_UNKNOWN, NULL, NGP_FORMAT_OK, 0 }; NGP_RAW_LINE ngp_prevline = { NULL, NULL, NULL, NGP_TTYPE_UNKNOWN, NULL, NGP_FORMAT_OK, 0 }; int ngp_inclevel = 0; /* number of included files, 1 - means mean file */ int ngp_grplevel = 0; /* group nesting level, 0 - means no grouping */ FILE *ngp_fp[NGP_MAX_INCLUDE]; /* stack of included file handles */ int ngp_keyidx = NGP_TOKEN_UNKNOWN; /* index of token in current line */ NGP_TOKEN ngp_linkey; /* keyword after line analyze */ char ngp_master_dir[NGP_MAX_FNAME]; /* directory of top level include file */ NGP_TKDEF ngp_tkdef[] = /* tokens recognized by parser */ { { "\\INCLUDE", NGP_TOKEN_INCLUDE }, { "\\GROUP", NGP_TOKEN_GROUP }, { "\\END", NGP_TOKEN_END }, { "XTENSION", NGP_TOKEN_XTENSION }, { "SIMPLE", NGP_TOKEN_SIMPLE }, { NULL, NGP_TOKEN_UNKNOWN } }; int master_grp_idx = 1; /* current unnamed group in object */ int ngp_extver_tab_size = 0; NGP_EXTVER_TAB *ngp_extver_tab = NULL; int ngp_get_extver(char *extname, int *version) { NGP_EXTVER_TAB *p; char *p2; int i; if ((NULL == extname) || (NULL == version)) return(NGP_BAD_ARG); if ((NULL == ngp_extver_tab) && (ngp_extver_tab_size > 0)) return(NGP_BAD_ARG); if ((NULL != ngp_extver_tab) && (ngp_extver_tab_size <= 0)) return(NGP_BAD_ARG); for (i=0; i 0)) return(NGP_BAD_ARG); if ((NULL != ngp_extver_tab) && (ngp_extver_tab_size <= 0)) return(NGP_BAD_ARG); for (i=0; i ngp_extver_tab[i].version) ngp_extver_tab[i].version = version; return(NGP_OK); } } if (NULL == ngp_extver_tab) { p = (NGP_EXTVER_TAB *)ngp_alloc(sizeof(NGP_EXTVER_TAB)); } else { p = (NGP_EXTVER_TAB *)ngp_realloc(ngp_extver_tab, (ngp_extver_tab_size + 1) * sizeof(NGP_EXTVER_TAB)); } if (NULL == p) return(NGP_NO_MEMORY); p2 = ngp_alloc(strlen(extname) + 1); if (NULL == p2) { ngp_free(p); return(NGP_NO_MEMORY); } strcpy(p2, extname); ngp_extver_tab = p; ngp_extver_tab[ngp_extver_tab_size].extname = p2; ngp_extver_tab[ngp_extver_tab_size].version = version; ngp_extver_tab_size++; return(NGP_OK); } int ngp_delete_extver_tab(void) { int i; if ((NULL == ngp_extver_tab) && (ngp_extver_tab_size > 0)) return(NGP_BAD_ARG); if ((NULL != ngp_extver_tab) && (ngp_extver_tab_size <= 0)) return(NGP_BAD_ARG); if ((NULL == ngp_extver_tab) && (0 == ngp_extver_tab_size)) return(NGP_OK); for (i=0; i= 'a') && (c1 <= 'z')) c1 += ('A' - 'a'); c2 = *p2; if ((c2 >= 'a') && (c2 <= 'z')) c2 += ('A' - 'a'); if (c1 < c2) return(-1); if (c1 > c2) return(1); if (0 == c1) return(0); p1++; p2++; } } int ngp_strcasencmp(char *p1, char *p2, int n) { char c1, c2; int ii; for (ii=0;ii= 'a') && (c1 <= 'z')) c1 += ('A' - 'a'); c2 = *p2; if ((c2 >= 'a') && (c2 <= 'z')) c2 += ('A' - 'a'); if (c1 < c2) return(-1); if (c1 > c2) return(1); if (0 == c1) return(0); p1++; p2++; } return(0); } /* read one line from file */ int ngp_line_from_file(FILE *fp, char **p) { int c, r, llen, allocsize, alen; char *p2; if (NULL == fp) return(NGP_NUL_PTR); /* check for stupid args */ if (NULL == p) return(NGP_NUL_PTR); /* more foolproof checks */ r = NGP_OK; /* initialize stuff, reset err code */ llen = 0; /* 0 characters read so far */ *p = (char *)ngp_alloc(1); /* preallocate 1 byte */ allocsize = 1; /* signal that we have allocated 1 byte */ if (NULL == *p) return(NGP_NO_MEMORY); /* if this failed, system is in dire straits */ for (;;) { c = getc(fp); /* get next character */ if (EOF == c) /* EOF signalled ? */ { if (ferror(fp)) r = NGP_READ_ERR; /* was it real error or simply EOF ? */ if (0 == llen) return(NGP_EOF); /* signal EOF only if 0 characters read so far */ break; } if ('\n' == c) break; /* end of line character ? */ llen++; /* we have new character, make room for it */ alen = ((llen + NGP_ALLOCCHUNK) / NGP_ALLOCCHUNK) * NGP_ALLOCCHUNK; if (alen > allocsize) { p2 = (char *)ngp_realloc(*p, alen); /* realloc buffer, if there is need */ if (NULL == p2) { r = NGP_NO_MEMORY; break; } *p = p2; allocsize = alen; } (*p)[llen - 1] = c; /* copy character to buffer */ } llen++; /* place for terminating \0 */ if (llen != allocsize) { p2 = (char *)ngp_realloc(*p, llen); if (NULL == p2) r = NGP_NO_MEMORY; else { *p = p2; (*p)[llen - 1] = 0; /* copy \0 to buffer */ } } else { (*p)[llen - 1] = 0; /* necessary when line read was empty */ } if ((NGP_EOF != r) && (NGP_OK != r)) /* in case of errors free resources */ { ngp_free(*p); *p = NULL; } return(r); /* return status code */ } /* free current line structure */ int ngp_free_line(void) { if (NULL != ngp_curline.line) { ngp_free(ngp_curline.line); ngp_curline.line = NULL; ngp_curline.name = NULL; ngp_curline.value = NULL; ngp_curline.comment = NULL; ngp_curline.type = NGP_TTYPE_UNKNOWN; ngp_curline.format = NGP_FORMAT_OK; ngp_curline.flags = 0; } return(NGP_OK); } /* free cached line structure */ int ngp_free_prevline(void) { if (NULL != ngp_prevline.line) { ngp_free(ngp_prevline.line); ngp_prevline.line = NULL; ngp_prevline.name = NULL; ngp_prevline.value = NULL; ngp_prevline.comment = NULL; ngp_prevline.type = NGP_TTYPE_UNKNOWN; ngp_prevline.format = NGP_FORMAT_OK; ngp_prevline.flags = 0; } return(NGP_OK); } /* read one line */ int ngp_read_line_buffered(FILE *fp) { ngp_free_line(); /* first free current line (if any) */ if (NULL != ngp_prevline.line) /* if cached, return cached line */ { ngp_curline = ngp_prevline; ngp_prevline.line = NULL; ngp_prevline.name = NULL; ngp_prevline.value = NULL; ngp_prevline.comment = NULL; ngp_prevline.type = NGP_TTYPE_UNKNOWN; ngp_prevline.format = NGP_FORMAT_OK; ngp_prevline.flags = 0; ngp_curline.flags = NGP_LINE_REREAD; return(NGP_OK); } ngp_curline.flags = 0; /* if not cached really read line from file */ return(ngp_line_from_file(fp, &(ngp_curline.line))); } /* unread line */ int ngp_unread_line(void) { if (NULL == ngp_curline.line) /* nothing to unread */ return(NGP_EMPTY_CURLINE); if (NULL != ngp_prevline.line) /* we cannot unread line twice */ return(NGP_UNREAD_QUEUE_FULL); ngp_prevline = ngp_curline; ngp_curline.line = NULL; return(NGP_OK); } /* a first guess line decomposition */ int ngp_extract_tokens(NGP_RAW_LINE *cl) { char *p, *s; int cl_flags, i; p = cl->line; /* start from beginning of line */ if (NULL == p) return(NGP_NUL_PTR); cl->name = cl->value = cl->comment = NULL; cl->type = NGP_TTYPE_UNKNOWN; cl->format = NGP_FORMAT_OK; cl_flags = 0; for (i=0;; i++) /* if 8 spaces at beginning then line is comment */ { if ((0 == *p) || ('\n' == *p)) { /* if line has only blanks -> write blank keyword */ cl->line[0] = 0; /* create empty name (0 length string) */ cl->comment = cl->name = cl->line; cl->type = NGP_TTYPE_RAW; /* signal write unformatted to FITS file */ return(NGP_OK); } if ((' ' != *p) && ('\t' != *p)) break; if (i >= 7) { cl->comment = p + 1; for (s = cl->comment;; s++) /* filter out any EOS characters in comment */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } cl->line[0] = 0; /* create empty name (0 length string) */ cl->name = cl->line; cl->type = NGP_TTYPE_RAW; return(NGP_OK); } p++; } cl->name = p; for (;;) /* we need to find 1st whitespace */ { if ((0 == *p) || ('\n' == *p)) { *p = 0; break; } /* from Richard Mathar, 2002-05-03, add 10 lines: if upper/lowercase HIERARCH followed also by an equal sign... */ if( strncasecmp("HIERARCH",p,strlen("HIERARCH")) == 0 ) { char * const eqsi=strchr(p,'=') ; if( eqsi ) { cl_flags |= NGP_FOUND_EQUAL_SIGN ; p=eqsi ; break ; } } if ((' ' == *p) || ('\t' == *p)) break; if ('=' == *p) { cl_flags |= NGP_FOUND_EQUAL_SIGN; break; } p++; } if (*p) *(p++) = 0; /* found end of keyname so terminate string with zero */ if ((!ngp_strcasecmp("HISTORY", cl->name)) || (!ngp_strcasecmp("COMMENT", cl->name)) || (!ngp_strcasecmp("CONTINUE", cl->name))) { cl->comment = p; for (s = cl->comment;; s++) /* filter out any EOS characters in comment */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } cl->type = NGP_TTYPE_RAW; return(NGP_OK); } if (!ngp_strcasecmp("\\INCLUDE", cl->name)) { for (;; p++) if ((' ' != *p) && ('\t' != *p)) break; /* skip whitespace */ cl->value = p; for (s = cl->value;; s++) /* filter out any EOS characters */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } cl->type = NGP_TTYPE_UNKNOWN; return(NGP_OK); } for (;; p++) { if ((0 == *p) || ('\n' == *p)) return(NGP_OK); /* test if at end of string */ if ((' ' == *p) || ('\t' == *p)) continue; /* skip whitespace */ if (cl_flags & NGP_FOUND_EQUAL_SIGN) break; if ('=' != *p) break; /* ignore initial equal sign */ cl_flags |= NGP_FOUND_EQUAL_SIGN; } if ('/' == *p) /* no value specified, comment only */ { p++; if ((' ' == *p) || ('\t' == *p)) p++; cl->comment = p; for (s = cl->comment;; s++) /* filter out any EOS characters in comment */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } return(NGP_OK); } if ('\'' == *p) /* we have found string within quotes */ { cl->value = s = ++p; /* set pointer to beginning of that string */ cl->type = NGP_TTYPE_STRING; /* signal that it is of string type */ for (;;) /* analyze it */ { if ((0 == *p) || ('\n' == *p)) /* end of line -> end of string */ { *s = 0; return(NGP_OK); } if ('\'' == *p) /* we have found doublequote */ { if ((0 == p[1]) || ('\n' == p[1]))/* doublequote is the last character in line */ { *s = 0; return(NGP_OK); } if (('\t' == p[1]) || (' ' == p[1])) /* duoblequote was string terminator */ { *s = 0; p++; break; } if ('\'' == p[1]) p++; /* doublequote is inside string, convert "" -> " */ } *(s++) = *(p++); /* compact string in place, necess. by "" -> " conversion */ } } else /* regular token */ { cl->value = p; /* set pointer to token */ cl->type = NGP_TTYPE_UNKNOWN; /* we dont know type at the moment */ for (;; p++) /* we need to find 1st whitespace */ { if ((0 == *p) || ('\n' == *p)) { *p = 0; return(NGP_OK); } if ((' ' == *p) || ('\t' == *p)) break; } if (*p) *(p++) = 0; /* found so terminate string with zero */ } for (;; p++) { if ((0 == *p) || ('\n' == *p)) return(NGP_OK); /* test if at end of string */ if ((' ' != *p) && ('\t' != *p)) break; /* skip whitespace */ } if ('/' == *p) /* no value specified, comment only */ { p++; if ((' ' == *p) || ('\t' == *p)) p++; cl->comment = p; for (s = cl->comment;; s++) /* filter out any EOS characters in comment */ { if ('\n' == *s) *s = 0; if (0 == *s) break; } return(NGP_OK); } cl->format = NGP_FORMAT_ERROR; return(NGP_OK); /* too many tokens ... */ } /* try to open include file. If open fails and fname does not specify absolute pathname, try to open fname in any directory specified in CFITSIO_INCLUDE_FILES environment variable. Finally try to open fname relative to ngp_master_dir, which is directory of top level include file */ int ngp_include_file(char *fname) /* try to open include file */ { char *p, *p2, *cp, *envar, envfiles[NGP_MAX_ENVFILES]; if (NULL == fname) return(NGP_NUL_PTR); if (ngp_inclevel >= NGP_MAX_INCLUDE) /* too many include files */ return(NGP_INC_NESTING); if (NULL == (ngp_fp[ngp_inclevel] = fopen(fname, "r"))) { /* if simple open failed .. */ envar = getenv("CFITSIO_INCLUDE_FILES"); /* scan env. variable, and retry to open */ if (NULL != envar) /* is env. variable defined ? */ { strncpy(envfiles, envar, NGP_MAX_ENVFILES - 1); envfiles[NGP_MAX_ENVFILES - 1] = 0; /* copy search path to local variable, env. is fragile */ for (p2 = strtok(envfiles, ":"); NULL != p2; p2 = strtok(NULL, ":")) { cp = (char *)ngp_alloc(strlen(fname) + strlen(p2) + 2); if (NULL == cp) return(NGP_NO_MEMORY); strcpy(cp, p2); #ifdef MSDOS strcat(cp, "\\"); /* abs. pathname for MSDOS */ #else strcat(cp, "/"); /* and for unix */ #endif strcat(cp, fname); ngp_fp[ngp_inclevel] = fopen(cp, "r"); ngp_free(cp); if (NULL != ngp_fp[ngp_inclevel]) break; } } if (NULL == ngp_fp[ngp_inclevel]) /* finally try to open relative to top level */ { #ifdef MSDOS if ('\\' == fname[0]) return(NGP_ERR_FOPEN); /* abs. pathname for MSDOS, does not support C:\\PATH */ #else if ('/' == fname[0]) return(NGP_ERR_FOPEN); /* and for unix */ #endif if (0 == ngp_master_dir[0]) return(NGP_ERR_FOPEN); p = ngp_alloc(strlen(fname) + strlen(ngp_master_dir) + 1); if (NULL == p) return(NGP_NO_MEMORY); strcpy(p, ngp_master_dir); /* construct composite pathname */ strcat(p, fname); /* comp = master + fname */ ngp_fp[ngp_inclevel] = fopen(p, "r");/* try to open composite */ ngp_free(p); /* we don't need buffer anymore */ if (NULL == ngp_fp[ngp_inclevel]) return(NGP_ERR_FOPEN); /* fail if error */ } } ngp_inclevel++; return(NGP_OK); } /* read line in the intelligent way. All \INCLUDE directives are handled, empty and comment line skipped. If this function returns NGP_OK, than decomposed line (name, type, value in proper type and comment) are stored in ngp_linkey structure. ignore_blank_lines parameter is zero when parser is inside GROUP or HDU definition. Nonzero otherwise. */ int ngp_read_line(int ignore_blank_lines) { int r, nc; unsigned k; if (ngp_inclevel <= 0) /* do some sanity checking first */ { ngp_keyidx = NGP_TOKEN_EOF; /* no parents, so report error */ return(NGP_OK); } if (ngp_inclevel > NGP_MAX_INCLUDE) return(NGP_INC_NESTING); if (NULL == ngp_fp[ngp_inclevel - 1]) return(NGP_NUL_PTR); for (;;) { switch (r = ngp_read_line_buffered(ngp_fp[ngp_inclevel - 1])) { case NGP_EOF: ngp_inclevel--; /* end of file, revert to parent */ if (ngp_fp[ngp_inclevel]) /* we can close old file */ fclose(ngp_fp[ngp_inclevel]); ngp_fp[ngp_inclevel] = NULL; if (ngp_inclevel <= 0) { ngp_keyidx = NGP_TOKEN_EOF; /* no parents, so report error */ return(NGP_OK); } continue; case NGP_OK: if (ngp_curline.flags & NGP_LINE_REREAD) return(r); break; default: return(r); } switch (ngp_curline.line[0]) { case 0: if (0 == ignore_blank_lines) break; /* ignore empty lines if told so */ case '#': continue; /* ignore comment lines */ } r = ngp_extract_tokens(&ngp_curline); /* analyse line, extract tokens and comment */ if (NGP_OK != r) return(r); if (NULL == ngp_curline.name) continue; /* skip lines consisting only of whitespaces */ for (k = 0; k < strlen(ngp_curline.name); k++) { if ((ngp_curline.name[k] >= 'a') && (ngp_curline.name[k] <= 'z')) ngp_curline.name[k] += 'A' - 'a'; /* force keyword to be upper case */ if (k == 7) break; /* only first 8 chars are required to be upper case */ } for (k=0;; k++) /* find index of keyword in keyword table */ { if (NGP_TOKEN_UNKNOWN == ngp_tkdef[k].code) break; if (0 == strcmp(ngp_curline.name, ngp_tkdef[k].name)) break; } ngp_keyidx = ngp_tkdef[k].code; /* save this index, grammar parser will need this */ if (NGP_TOKEN_INCLUDE == ngp_keyidx) /* if this is \INCLUDE keyword, try to include file */ { if (NGP_OK != (r = ngp_include_file(ngp_curline.value))) return(r); continue; /* and read next line */ } ngp_linkey.type = NGP_TTYPE_UNKNOWN; /* now, get the keyword type, it's a long story ... */ if (NULL != ngp_curline.value) /* if no value given signal it */ { if (NGP_TTYPE_STRING == ngp_curline.type) /* string type test */ { ngp_linkey.type = NGP_TTYPE_STRING; ngp_linkey.value.s = ngp_curline.value; } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* bool type test */ { if ((!ngp_strcasecmp("T", ngp_curline.value)) || (!ngp_strcasecmp("F", ngp_curline.value))) { ngp_linkey.type = NGP_TTYPE_BOOL; ngp_linkey.value.b = (ngp_strcasecmp("T", ngp_curline.value) ? 0 : 1); } } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* complex type test */ { if (2 == sscanf(ngp_curline.value, "(%lg,%lg)%n", &(ngp_linkey.value.c.re), &(ngp_linkey.value.c.im), &nc)) { if ((' ' == ngp_curline.value[nc]) || ('\t' == ngp_curline.value[nc]) || ('\n' == ngp_curline.value[nc]) || (0 == ngp_curline.value[nc])) { ngp_linkey.type = NGP_TTYPE_COMPLEX; } } } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* real type test */ { if (strchr(ngp_curline.value, '.') && (1 == sscanf(ngp_curline.value, "%lg%n", &(ngp_linkey.value.d), &nc))) { if ((' ' == ngp_curline.value[nc]) || ('\t' == ngp_curline.value[nc]) || ('\n' == ngp_curline.value[nc]) || (0 == ngp_curline.value[nc])) { ngp_linkey.type = NGP_TTYPE_REAL; } } } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* integer type test */ { if (1 == sscanf(ngp_curline.value, "%d%n", &(ngp_linkey.value.i), &nc)) { if ((' ' == ngp_curline.value[nc]) || ('\t' == ngp_curline.value[nc]) || ('\n' == ngp_curline.value[nc]) || (0 == ngp_curline.value[nc])) { ngp_linkey.type = NGP_TTYPE_INT; } } } if (NGP_TTYPE_UNKNOWN == ngp_linkey.type) /* force string type */ { ngp_linkey.type = NGP_TTYPE_STRING; ngp_linkey.value.s = ngp_curline.value; } } else { if (NGP_TTYPE_RAW == ngp_curline.type) ngp_linkey.type = NGP_TTYPE_RAW; else ngp_linkey.type = NGP_TTYPE_NULL; } if (NULL != ngp_curline.comment) { strncpy(ngp_linkey.comment, ngp_curline.comment, NGP_MAX_COMMENT); /* store comment */ ngp_linkey.comment[NGP_MAX_COMMENT - 1] = 0; } else { ngp_linkey.comment[0] = 0; } strncpy(ngp_linkey.name, ngp_curline.name, NGP_MAX_NAME); /* and keyword's name */ ngp_linkey.name[NGP_MAX_NAME - 1] = 0; if (strlen(ngp_linkey.name) > FLEN_KEYWORD) /* WDP: 20-Jun-2002: mod to support HIERARCH */ { return(NGP_BAD_ARG); /* cfitsio does not allow names > 8 chars */ } return(NGP_OK); /* we have valid non empty line, so return success */ } } /* check whether keyword can be written as is */ int ngp_keyword_is_write(NGP_TOKEN *ngp_tok) { int i, j, r, l, spc; /* indexed variables not to write */ static char *nm[] = { "NAXIS", "TFORM", "TTYPE", NULL } ; /* non indexed variables not allowed to write */ static char *nmni[] = { "SIMPLE", "XTENSION", "BITPIX", "NAXIS", "PCOUNT", "GCOUNT", "TFIELDS", "THEAP", "EXTEND", "EXTVER", NULL } ; if (NULL == ngp_tok) return(NGP_NUL_PTR); r = NGP_OK; for (j = 0; ; j++) /* first check non indexed */ { if (NULL == nmni[j]) break; if (0 == strcmp(nmni[j], ngp_tok->name)) return(NGP_BAD_ARG); } for (j = 0; ; j++) /* now check indexed */ { if (NULL == nm[j]) return(NGP_OK); l = strlen(nm[j]); if ((l < 1) || (l > 5)) continue; if (0 == strncmp(nm[j], ngp_tok->name, l)) break; } if ((ngp_tok->name[l] < '1') || (ngp_tok->name[l] > '9')) return(NGP_OK); spc = 0; for (i = l + 1; i < 8; i++) { if (spc) { if (' ' != ngp_tok->name[i]) return(NGP_OK); } else { if ((ngp_tok->name[i] >= '0') || (ngp_tok->name[i] <= '9')) continue; if (' ' == ngp_tok->name[i]) { spc = 1; continue; } if (0 == ngp_tok->name[i]) break; return(NGP_OK); } } return(NGP_BAD_ARG); } /* write (almost) all keywords from given HDU to disk */ int ngp_keyword_all_write(NGP_HDU *ngph, fitsfile *ffp, int mode) { int i, r, ib; char buf[200]; long l; if (NULL == ngph) return(NGP_NUL_PTR); if (NULL == ffp) return(NGP_NUL_PTR); r = NGP_OK; for (i=0; itokcnt; i++) { r = ngp_keyword_is_write(&(ngph->tok[i])); if ((NGP_REALLY_ALL & mode) || (NGP_OK == r)) { switch (ngph->tok[i].type) { case NGP_TTYPE_BOOL: ib = ngph->tok[i].value.b; fits_write_key(ffp, TLOGICAL, ngph->tok[i].name, &ib, ngph->tok[i].comment, &r); break; case NGP_TTYPE_STRING: fits_write_key_longstr(ffp, ngph->tok[i].name, ngph->tok[i].value.s, ngph->tok[i].comment, &r); break; case NGP_TTYPE_INT: l = ngph->tok[i].value.i; /* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */ fits_write_key(ffp, TLONG, ngph->tok[i].name, &l, ngph->tok[i].comment, &r); break; case NGP_TTYPE_REAL: fits_write_key(ffp, TDOUBLE, ngph->tok[i].name, &(ngph->tok[i].value.d), ngph->tok[i].comment, &r); break; case NGP_TTYPE_COMPLEX: fits_write_key(ffp, TDBLCOMPLEX, ngph->tok[i].name, &(ngph->tok[i].value.c), ngph->tok[i].comment, &r); break; case NGP_TTYPE_NULL: fits_write_key_null(ffp, ngph->tok[i].name, ngph->tok[i].comment, &r); break; case NGP_TTYPE_RAW: if (0 == strcmp("HISTORY", ngph->tok[i].name)) { fits_write_history(ffp, ngph->tok[i].comment, &r); break; } if (0 == strcmp("COMMENT", ngph->tok[i].name)) { fits_write_comment(ffp, ngph->tok[i].comment, &r); break; } sprintf(buf, "%-8.8s%s", ngph->tok[i].name, ngph->tok[i].comment); fits_write_record(ffp, buf, &r); break; } } else if (NGP_BAD_ARG == r) /* enhancement 10 dec 2003, James Peachey: template comments replace defaults */ { r = NGP_OK; /* update comments of special keywords like TFORM */ if (ngph->tok[i].comment && *ngph->tok[i].comment) /* do not update with a blank comment */ { fits_modify_comment(ffp, ngph->tok[i].name, ngph->tok[i].comment, &r); } } else /* other problem, typically a blank token */ { r = NGP_OK; /* skip this token, but continue */ } if (r) return(r); } fits_set_hdustruc(ffp, &r); /* resync cfitsio */ return(r); } /* init HDU structure */ int ngp_hdu_init(NGP_HDU *ngph) { if (NULL == ngph) return(NGP_NUL_PTR); ngph->tok = NULL; ngph->tokcnt = 0; return(NGP_OK); } /* clear HDU structure */ int ngp_hdu_clear(NGP_HDU *ngph) { int i; if (NULL == ngph) return(NGP_NUL_PTR); for (i=0; itokcnt; i++) { if (NGP_TTYPE_STRING == ngph->tok[i].type) if (NULL != ngph->tok[i].value.s) { ngp_free(ngph->tok[i].value.s); ngph->tok[i].value.s = NULL; } } if (NULL != ngph->tok) ngp_free(ngph->tok); ngph->tok = NULL; ngph->tokcnt = 0; return(NGP_OK); } /* insert new token to HDU structure */ int ngp_hdu_insert_token(NGP_HDU *ngph, NGP_TOKEN *newtok) { NGP_TOKEN *tkp; if (NULL == ngph) return(NGP_NUL_PTR); if (NULL == newtok) return(NGP_NUL_PTR); if (0 == ngph->tokcnt) tkp = (NGP_TOKEN *)ngp_alloc((ngph->tokcnt + 1) * sizeof(NGP_TOKEN)); else tkp = (NGP_TOKEN *)ngp_realloc(ngph->tok, (ngph->tokcnt + 1) * sizeof(NGP_TOKEN)); if (NULL == tkp) return(NGP_NO_MEMORY); ngph->tok = tkp; ngph->tok[ngph->tokcnt] = *newtok; if (NGP_TTYPE_STRING == newtok->type) { if (NULL != newtok->value.s) { ngph->tok[ngph->tokcnt].value.s = (char *)ngp_alloc(1 + strlen(newtok->value.s)); if (NULL == ngph->tok[ngph->tokcnt].value.s) return(NGP_NO_MEMORY); strcpy(ngph->tok[ngph->tokcnt].value.s, newtok->value.s); } } ngph->tokcnt++; return(NGP_OK); } int ngp_append_columns(fitsfile *ff, NGP_HDU *ngph, int aftercol) { int r, i, j, exitflg, ngph_i; char *my_tform, *my_ttype; char ngph_ctmp; if (NULL == ff) return(NGP_NUL_PTR); if (NULL == ngph) return(NGP_NUL_PTR); if (0 == ngph->tokcnt) return(NGP_OK); /* nothing to do ! */ r = NGP_OK; exitflg = 0; for (j=aftercol; jtok[i].name, "TFORM%d%c", &ngph_i, &ngph_ctmp)) { if ((NGP_TTYPE_STRING == ngph->tok[i].type) && (ngph_i == (j + 1))) { my_tform = ngph->tok[i].value.s; } } else if (1 == sscanf(ngph->tok[i].name, "TTYPE%d%c", &ngph_i, &ngph_ctmp)) { if ((NGP_TTYPE_STRING == ngph->tok[i].type) && (ngph_i == (j + 1))) { my_ttype = ngph->tok[i].value.s; } } if ((NULL != my_tform) && (my_ttype[0])) break; if (i < (ngph->tokcnt - 1)) continue; exitflg = 1; break; } if ((NGP_OK == r) && (NULL != my_tform)) fits_insert_col(ff, j + 1, my_ttype, my_tform, &r); if ((NGP_OK != r) || exitflg) break; } return(r); } /* read complete HDU */ int ngp_read_xtension(fitsfile *ff, int parent_hn, int simple_mode) { int r, exflg, l, my_hn, tmp0, incrementor_index, i, j; int ngph_dim, ngph_bitpix, ngph_node_type, my_version; char incrementor_name[NGP_MAX_STRING], ngph_ctmp; char *ngph_extname = 0; long ngph_size[NGP_MAX_ARRAY_DIM]; NGP_HDU ngph; long lv; incrementor_name[0] = 0; /* signal no keyword+'#' found yet */ incrementor_index = 0; if (NGP_OK != (r = ngp_hdu_init(&ngph))) return(r); if (NGP_OK != (r = ngp_read_line(0))) return(r); /* EOF always means error here */ switch (NGP_XTENSION_SIMPLE & simple_mode) { case 0: if (NGP_TOKEN_XTENSION != ngp_keyidx) return(NGP_TOKEN_NOT_EXPECT); break; default: if (NGP_TOKEN_SIMPLE != ngp_keyidx) return(NGP_TOKEN_NOT_EXPECT); break; } if (NGP_OK != (r = ngp_hdu_insert_token(&ngph, &ngp_linkey))) return(r); for (;;) { if (NGP_OK != (r = ngp_read_line(0))) return(r); /* EOF always means error here */ exflg = 0; switch (ngp_keyidx) { case NGP_TOKEN_SIMPLE: r = NGP_TOKEN_NOT_EXPECT; break; case NGP_TOKEN_END: case NGP_TOKEN_XTENSION: case NGP_TOKEN_GROUP: r = ngp_unread_line(); /* WARNING - not break here .... */ case NGP_TOKEN_EOF: exflg = 1; break; default: l = strlen(ngp_linkey.name); if ((l >= 2) && (l <= 6)) { if ('#' == ngp_linkey.name[l - 1]) { if (0 == incrementor_name[0]) { memcpy(incrementor_name, ngp_linkey.name, l - 1); incrementor_name[l - 1] = 0; } if (((l - 1) == (int)strlen(incrementor_name)) && (0 == memcmp(incrementor_name, ngp_linkey.name, l - 1))) { incrementor_index++; } sprintf(ngp_linkey.name + l - 1, "%d", incrementor_index); } } r = ngp_hdu_insert_token(&ngph, &ngp_linkey); break; } if ((NGP_OK != r) || exflg) break; } if (NGP_OK == r) { /* we should scan keywords, and calculate HDU's */ /* structure ourselves .... */ ngph_node_type = NGP_NODE_INVALID; /* init variables */ ngph_bitpix = 0; ngph_extname = NULL; for (i=0; i=1) && (j <= NGP_MAX_ARRAY_DIM)) { ngph_size[j - 1] = ngph.tok[i].value.i; } } } switch (ngph_node_type) { case NGP_NODE_IMAGE: if (NGP_XTENSION_FIRST == ((NGP_XTENSION_FIRST | NGP_XTENSION_SIMPLE) & simple_mode)) { /* if caller signals that this is 1st HDU in file */ /* and it is IMAGE defined with XTENSION, then we */ /* need create dummy Primary HDU */ fits_create_img(ff, 16, 0, NULL, &r); } /* create image */ fits_create_img(ff, ngph_bitpix, ngph_dim, ngph_size, &r); /* update keywords */ if (NGP_OK == r) r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY); break; case NGP_NODE_ATABLE: case NGP_NODE_BTABLE: /* create table, 0 rows and 0 columns for the moment */ fits_create_tbl(ff, ((NGP_NODE_ATABLE == ngph_node_type) ? ASCII_TBL : BINARY_TBL), 0, 0, NULL, NULL, NULL, NULL, &r); if (NGP_OK != r) break; /* add columns ... */ r = ngp_append_columns(ff, &ngph, 0); if (NGP_OK != r) break; /* add remaining keywords */ r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY); if (NGP_OK != r) break; /* if requested add rows */ if (ngph_size[1] > 0) fits_insert_rows(ff, 0, ngph_size[1], &r); break; default: r = NGP_BAD_ARG; break; } } if ((NGP_OK == r) && (NULL != ngph_extname)) { r = ngp_get_extver(ngph_extname, &my_version); /* write correct ext version number */ lv = my_version; /* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */ fits_write_key(ff, TLONG, "EXTVER", &lv, "auto assigned by template parser", &r); } if (NGP_OK == r) { if (parent_hn > 0) { fits_get_hdu_num(ff, &my_hn); fits_movabs_hdu(ff, parent_hn, &tmp0, &r); /* link us to parent */ fits_add_group_member(ff, NULL, my_hn, &r); fits_movabs_hdu(ff, my_hn, &tmp0, &r); if (NGP_OK != r) return(r); } } if (NGP_OK != r) /* in case of error - delete hdu */ { tmp0 = 0; fits_delete_hdu(ff, NULL, &tmp0); } ngp_hdu_clear(&ngph); return(r); } /* read complete GROUP */ int ngp_read_group(fitsfile *ff, char *grpname, int parent_hn) { int r, exitflg, l, my_hn, tmp0, incrementor_index; char grnm[NGP_MAX_STRING]; /* keyword holding group name */ char incrementor_name[NGP_MAX_STRING]; NGP_HDU ngph; incrementor_name[0] = 0; /* signal no keyword+'#' found yet */ incrementor_index = 6; /* first 6 cols are used by group */ ngp_grplevel++; if (NGP_OK != (r = ngp_hdu_init(&ngph))) return(r); r = NGP_OK; if (NGP_OK != (r = fits_create_group(ff, grpname, GT_ID_ALL_URI, &r))) return(r); fits_get_hdu_num(ff, &my_hn); if (parent_hn > 0) { fits_movabs_hdu(ff, parent_hn, &tmp0, &r); /* link us to parent */ fits_add_group_member(ff, NULL, my_hn, &r); fits_movabs_hdu(ff, my_hn, &tmp0, &r); if (NGP_OK != r) return(r); } for (exitflg = 0; 0 == exitflg;) { if (NGP_OK != (r = ngp_read_line(0))) break; /* EOF always means error here */ switch (ngp_keyidx) { case NGP_TOKEN_SIMPLE: case NGP_TOKEN_EOF: r = NGP_TOKEN_NOT_EXPECT; break; case NGP_TOKEN_END: ngp_grplevel--; exitflg = 1; break; case NGP_TOKEN_GROUP: if (NGP_TTYPE_STRING == ngp_linkey.type) { strncpy(grnm, ngp_linkey.value.s, NGP_MAX_STRING); } else { sprintf(grnm, "DEFAULT_GROUP_%d", master_grp_idx++); } grnm[NGP_MAX_STRING - 1] = 0; r = ngp_read_group(ff, grnm, my_hn); break; /* we can have many subsequent GROUP defs */ case NGP_TOKEN_XTENSION: r = ngp_unread_line(); if (NGP_OK != r) break; r = ngp_read_xtension(ff, my_hn, 0); break; /* we can have many subsequent HDU defs */ default: l = strlen(ngp_linkey.name); if ((l >= 2) && (l <= 6)) { if ('#' == ngp_linkey.name[l - 1]) { if (0 == incrementor_name[0]) { memcpy(incrementor_name, ngp_linkey.name, l - 1); incrementor_name[l - 1] = 0; } if (((l - 1) == (int)strlen(incrementor_name)) && (0 == memcmp(incrementor_name, ngp_linkey.name, l - 1))) { incrementor_index++; } sprintf(ngp_linkey.name + l - 1, "%d", incrementor_index); } } r = ngp_hdu_insert_token(&ngph, &ngp_linkey); break; /* here we can add keyword */ } if (NGP_OK != r) break; } fits_movabs_hdu(ff, my_hn, &tmp0, &r); /* back to our HDU */ if (NGP_OK == r) /* create additional columns, if requested */ r = ngp_append_columns(ff, &ngph, 6); if (NGP_OK == r) /* and write keywords */ r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY); if (NGP_OK != r) /* delete group in case of error */ { tmp0 = 0; fits_remove_group(ff, OPT_RM_GPT, &tmp0); } ngp_hdu_clear(&ngph); /* we are done with this HDU, so delete it */ return(r); } /* top level API functions */ /* read whole template. ff should point to the opened empty fits file. */ int fits_execute_template(fitsfile *ff, char *ngp_template, int *status) { int r, exit_flg, first_extension, i, my_hn, tmp0, keys_exist, more_keys, used_ver; char grnm[NGP_MAX_STRING], used_name[NGP_MAX_STRING]; long luv; if (NULL == status) return(NGP_NUL_PTR); if (NGP_OK != *status) return(*status); if ((NULL == ff) || (NULL == ngp_template)) { *status = NGP_NUL_PTR; return(*status); } ngp_inclevel = 0; /* initialize things, not all should be zero */ ngp_grplevel = 0; master_grp_idx = 1; exit_flg = 0; ngp_master_dir[0] = 0; /* this should be before 1st call to ngp_include_file */ first_extension = 1; /* we need to create PHDU */ if (NGP_OK != (r = ngp_delete_extver_tab())) { *status = r; return(r); } fits_get_hdu_num(ff, &my_hn); /* our HDU position */ if (my_hn <= 1) /* check whether we really need to create PHDU */ { fits_movabs_hdu(ff, 1, &tmp0, status); fits_get_hdrspace(ff, &keys_exist, &more_keys, status); fits_movabs_hdu(ff, my_hn, &tmp0, status); if (NGP_OK != *status) return(*status); /* error here means file is corrupted */ if (keys_exist > 0) first_extension = 0; /* if keywords exist assume PHDU already exist */ } else { first_extension = 0; /* PHDU (followed by 1+ extensions) exist */ for (i = 2; i<= my_hn; i++) { *status = NGP_OK; fits_movabs_hdu(ff, 1, &tmp0, status); if (NGP_OK != *status) break; fits_read_key(ff, TSTRING, "EXTNAME", used_name, NULL, status); if (NGP_OK != *status) continue; fits_read_key(ff, TLONG, "EXTVER", &luv, NULL, status); used_ver = luv; /* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */ if (VALUE_UNDEFINED == *status) { used_ver = 1; *status = NGP_OK; } if (NGP_OK == *status) *status = ngp_set_extver(used_name, used_ver); } fits_movabs_hdu(ff, my_hn, &tmp0, status); } if (NGP_OK != *status) return(*status); if (NGP_OK != (*status = ngp_include_file(ngp_template))) return(*status); for (i = strlen(ngp_template) - 1; i >= 0; i--) /* strlen is > 0, otherwise fopen failed */ { #ifdef MSDOS if ('\\' == ngp_template[i]) break; #else if ('/' == ngp_template[i]) break; #endif } i++; if (i > (NGP_MAX_FNAME - 1)) i = NGP_MAX_FNAME - 1; if (i > 0) { memcpy(ngp_master_dir, ngp_template, i); ngp_master_dir[i] = 0; } for (;;) { if (NGP_OK != (r = ngp_read_line(1))) break; /* EOF always means error here */ switch (ngp_keyidx) { case NGP_TOKEN_SIMPLE: if (0 == first_extension) /* simple only allowed in first HDU */ { r = NGP_TOKEN_NOT_EXPECT; break; } if (NGP_OK != (r = ngp_unread_line())) break; r = ngp_read_xtension(ff, 0, NGP_XTENSION_SIMPLE | NGP_XTENSION_FIRST); first_extension = 0; break; case NGP_TOKEN_XTENSION: if (NGP_OK != (r = ngp_unread_line())) break; r = ngp_read_xtension(ff, 0, (first_extension ? NGP_XTENSION_FIRST : 0)); first_extension = 0; break; case NGP_TOKEN_GROUP: if (NGP_TTYPE_STRING == ngp_linkey.type) { strncpy(grnm, ngp_linkey.value.s, NGP_MAX_STRING); } else { sprintf(grnm, "DEFAULT_GROUP_%d", master_grp_idx++); } grnm[NGP_MAX_STRING - 1] = 0; r = ngp_read_group(ff, grnm, 0); first_extension = 0; break; case NGP_TOKEN_EOF: exit_flg = 1; break; default: r = NGP_TOKEN_NOT_EXPECT; break; } if (exit_flg || (NGP_OK != r)) break; } /* all top level HDUs up to faulty one are left intact in case of i/o error. It is up to the caller to call fits_close_file or fits_delete_file when this function returns error. */ ngp_free_line(); /* deallocate last line (if any) */ ngp_free_prevline(); /* deallocate cached line (if any) */ ngp_delete_extver_tab(); /* delete extver table (if present), error ignored */ *status = r; return(r); } indi-0.5/src/cfitsio/Makefile.in0000644000175000017500000004535110610536734014422 0ustar jrjr# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/cfitsio DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcfitsio_la_LIBADD = am_libcfitsio_la_OBJECTS = buffers.lo cfileio.lo checksum.lo \ compress.lo drvrfile.lo drvrmem.lo drvrnet.lo drvrsmem.lo \ editcol.lo edithdu.lo eval_l.lo eval_y.lo eval_f.lo \ fitscore.lo getcol.lo getcolb.lo getcold.lo getcole.lo \ getcoli.lo getcolj.lo getcolk.lo getcoll.lo getcols.lo \ getcolsb.lo getcoluk.lo getcolui.lo getcoluj.lo getkey.lo \ group.lo grparser.lo histo.lo iraffits.lo modkey.lo putcol.lo \ putcolb.lo putcold.lo putcole.lo putcoli.lo putcolj.lo \ putcolk.lo putcoluk.lo putcoll.lo putcols.lo putcolsb.lo \ putcolu.lo putcolui.lo putcoluj.lo putkey.lo region.lo \ scalnull.lo swapproc.lo wcssub.lo wcsutil.lo imcompress.lo \ quantize.lo ricecomp.lo pliocomp.lo fits_hcompress.lo \ fits_hdecompress.lo libcfitsio_la_OBJECTS = $(am_libcfitsio_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libcfitsio_la_SOURCES) DIST_SOURCES = $(libcfitsio_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BSD_FALSE = @BSD_FALSE@ BSD_TRUE = @BSD_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_SUBDIR = @EXTRA_SUBDIR@ F77 = @F77@ FFLAGS = @FFLAGS@ GREP = @GREP@ HAVE_LIBSBIGUDRV_FALSE = @HAVE_LIBSBIGUDRV_FALSE@ HAVE_LIBSBIGUDRV_TRUE = @HAVE_LIBSBIGUDRV_TRUE@ HAVE_LIBUSB_FALSE = @HAVE_LIBUSB_FALSE@ HAVE_LIBUSB_TRUE = @HAVE_LIBUSB_TRUE@ HAVE_V4L2_FALSE = @HAVE_V4L2_FALSE@ HAVE_V4L2_TRUE = @HAVE_V4L2_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBCFITSIO = @LIBCFITSIO@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSBIGUDRV = @LIBSBIGUDRV@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LINUX_FALSE = @LINUX_FALSE@ LINUX_TRUE = @LINUX_TRUE@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ NULL_FALSE = @NULL_FALSE@ NULL_TRUE = @NULL_TRUE@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_F77 = @ac_ct_F77@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ noinst_LTLIBRARIES = libcfitsio.la libcfitsio_la_SOURCES = buffers.c cfileio.c checksum.c compress.c drvrfile.c drvrmem.c \ drvrnet.c drvrsmem.c editcol.c edithdu.c eval_l.c eval_y.c \ eval_f.c fitscore.c getcol.c getcolb.c getcold.c getcole.c \ getcoli.c getcolj.c getcolk.c getcoll.c getcols.c getcolsb.c \ getcoluk.c getcolui.c getcoluj.c getkey.c group.c grparser.c \ histo.c iraffits.c \ modkey.c putcol.c putcolb.c putcold.c putcole.c putcoli.c \ putcolj.c putcolk.c putcoluk.c putcoll.c putcols.c putcolsb.c \ putcolu.c putcolui.c putcoluj.c putkey.c region.c scalnull.c \ swapproc.c wcssub.c wcsutil.c imcompress.c quantize.c ricecomp.c \ pliocomp.c fits_hcompress.c fits_hdecompress.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/cfitsio/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/cfitsio/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libcfitsio.la: $(libcfitsio_la_OBJECTS) $(libcfitsio_la_DEPENDENCIES) $(LINK) $(libcfitsio_la_LDFLAGS) $(libcfitsio_la_OBJECTS) $(libcfitsio_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfileio.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checksum.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compress.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drvrfile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drvrmem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drvrnet.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drvrsmem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/editcol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edithdu.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval_f.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval_l.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval_y.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fits_hcompress.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fits_hdecompress.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fitscore.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcolb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcold.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcole.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcoli.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcolj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcolk.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcoll.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcols.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcolsb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcolui.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcoluj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcoluk.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getkey.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/group.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grparser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/histo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imcompress.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iraffits.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modkey.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pliocomp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcolb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcold.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcole.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcoli.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcolj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcolk.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcoll.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcols.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcolsb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcolu.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcolui.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcoluj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putcoluk.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/putkey.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quantize.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/region.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ricecomp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scalnull.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/swapproc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wcssub.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wcsutil.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: indi-0.5/src/cfitsio/editcol.c0000644000175000017500000023723510610474374014151 0ustar jrjr/* This file, editcol.c, contains the set of FITSIO routines that */ /* insert or delete rows or columns in a table or resize an image */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffrsim(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ long *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* resize an existing primary array or IMAGE extension. */ { LONGLONG tnaxes[99]; int ii; if (*status > 0) return(*status); for (ii = 0; (ii < naxis) && (ii < 99); ii++) tnaxes[ii] = naxes[ii]; ffrsimll(fptr, bitpix, naxis, tnaxes, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffrsimll(fitsfile *fptr, /* I - FITS file pointer */ int bitpix, /* I - bits per pixel */ int naxis, /* I - number of axes in the array */ LONGLONG *naxes, /* I - size of each axis */ int *status) /* IO - error status */ /* resize an existing primary array or IMAGE extension. */ { int ii, simple, obitpix, onaxis, extend, nmodify; long nblocks, longval; long pcount, gcount, longbitpix; LONGLONG onaxes[99], newsize, oldsize; char comment[FLEN_COMMENT], keyname[FLEN_KEYWORD], message[FLEN_ERRMSG]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* get current image size parameters */ if (ffghprll(fptr, 99, &simple, &obitpix, &onaxis, onaxes, &pcount, &gcount, &extend, status) > 0) return(*status); longbitpix = bitpix; /* test for the 2 special cases that represent unsigned integers */ if (longbitpix == USHORT_IMG) longbitpix = SHORT_IMG; else if (longbitpix == ULONG_IMG) longbitpix = LONG_IMG; /* test that the new values are legal */ if (longbitpix != BYTE_IMG && longbitpix != SHORT_IMG && longbitpix != LONG_IMG && longbitpix != LONGLONG_IMG && longbitpix != FLOAT_IMG && longbitpix != DOUBLE_IMG) { sprintf(message, "Illegal value for BITPIX keyword: %d", bitpix); ffpmsg(message); return(*status = BAD_BITPIX); } if (naxis < 0 || naxis > 999) { sprintf(message, "Illegal value for NAXIS keyword: %d", naxis); ffpmsg(message); return(*status = BAD_NAXIS); } if (naxis == 0) newsize = 0; else newsize = 1; for (ii = 0; ii < naxis; ii++) { if (naxes[ii] < 0) { sprintf(message, "Illegal value for NAXIS%d keyword: %.0f", ii + 1, (double) (naxes[ii])); ffpmsg(message); return(*status = BAD_NAXES); } newsize *= naxes[ii]; /* compute new image size, in pixels */ } /* compute size of old image, in bytes */ if (onaxis == 0) oldsize = 0; else { oldsize = 1; for (ii = 0; ii < onaxis; ii++) oldsize *= onaxes[ii]; oldsize = (oldsize + pcount) * gcount * (abs(obitpix) / 8); } oldsize = (oldsize + 2879) / 2880; /* old size, in blocks */ newsize = (newsize + pcount) * gcount * (abs(longbitpix) / 8); newsize = (newsize + 2879) / 2880; /* new size, in blocks */ if (newsize > oldsize) /* have to insert new blocks for image */ { nblocks = (long) (newsize - oldsize); if (ffiblk(fptr, nblocks, 1, status) > 0) return(*status); } else if (oldsize > newsize) /* have to delete blocks from image */ { nblocks = (long) (oldsize - newsize); if (ffdblk(fptr, nblocks, status) > 0) return(*status); } /* now update the header keywords */ strcpy(comment,"&"); /* special value to leave comments unchanged */ if (longbitpix != obitpix) { /* update BITPIX value */ ffmkyj(fptr, "BITPIX", longbitpix, comment, status); } if (naxis != onaxis) { /* update NAXIS value */ longval = naxis; ffmkyj(fptr, "NAXIS", longval, comment, status); } /* modify the existing NAXISn keywords */ nmodify = minvalue(naxis, onaxis); for (ii = 0; ii < nmodify; ii++) { ffkeyn("NAXIS", ii+1, keyname, status); ffmkyj(fptr, keyname, naxes[ii], comment, status); } if (naxis > onaxis) /* insert additional NAXISn keywords */ { strcpy(comment,"length of data axis"); for (ii = onaxis; ii < naxis; ii++) { ffkeyn("NAXIS", ii+1, keyname, status); ffikyj(fptr, keyname, naxes[ii], comment, status); } } else if (onaxis > naxis) /* delete old NAXISn keywords */ { for (ii = naxis; ii < onaxis; ii++) { ffkeyn("NAXIS", ii+1, keyname, status); ffdkey(fptr, keyname, status); } } /* Update the BSCALE and BZERO keywords, if an unsigned integer image */ if (bitpix == USHORT_IMG) { strcpy(comment, "offset data range to that of unsigned short"); ffukyg(fptr, "BZERO", 32768., 0, comment, status); strcpy(comment, "default scaling factor"); ffukyg(fptr, "BSCALE", 1.0, 0, comment, status); } else if (bitpix == ULONG_IMG) { strcpy(comment, "offset data range to that of unsigned long"); ffukyg(fptr, "BZERO", 2147483648., 0, comment, status); strcpy(comment, "default scaling factor"); ffukyg(fptr, "BSCALE", 1.0, 0, comment, status); } /* re-read the header, to make sure structures are updated */ ffrdef(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffirow(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstrow, /* I - insert space AFTER this row */ /* 0 = insert space at beginning of table */ LONGLONG nrows, /* I - number of rows to insert */ int *status) /* IO - error status */ /* insert NROWS blank rows immediated after row firstrow (1 = first row). Set firstrow = 0 to insert space at the beginning of the table. */ { int tstatus; LONGLONG naxis1, naxis2; LONGLONG datasize, firstbyte, nshift, nbytes; LONGLONG freespace; long nblock; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only add rows to TABLE or BINTABLE extension (ffirow)"); return(*status = NOT_TABLE); } if (nrows < 0 ) return(*status = NEG_BYTES); else if (nrows == 0) return(*status); /* no op, so just return */ /* get the current size of the table */ /* use internal structure since NAXIS2 keyword may not be up to date */ naxis1 = (fptr->Fptr)->rowlength; naxis2 = (fptr->Fptr)->numrows; if (firstrow > naxis2) { ffpmsg( "Insert position greater than the number of rows in the table (ffirow)"); return(*status = BAD_ROW_NUM); } else if (firstrow < 0) { ffpmsg("Insert position is less than 0 (ffirow)"); return(*status = BAD_ROW_NUM); } /* current data size */ datasize = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ( ( (datasize + 2879) / 2880) * 2880) - datasize; nshift = naxis1 * nrows; /* no. of bytes to add to table */ if ( (freespace - nshift) < 0) /* not enough existing space? */ { nblock = (long) ((nshift - freespace + 2879) / 2880); /* number of blocks */ ffiblk(fptr, nblock, 1, status); /* insert the blocks */ } firstbyte = naxis1 * firstrow; /* relative insert position */ nbytes = datasize - firstbyte; /* no. of bytes to shift down */ firstbyte += ((fptr->Fptr)->datastart); /* absolute insert position */ ffshft(fptr, firstbyte, nbytes, nshift, status); /* shift rows and heap */ /* update the heap starting address */ (fptr->Fptr)->heapstart += nshift; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (fptr->Fptr)->heapstart, "&", &tstatus); /* update the NAXIS2 keyword */ ffmkyj(fptr, "NAXIS2", naxis2 + nrows, "&", status); ((fptr->Fptr)->numrows) += nrows; ((fptr->Fptr)->origrows) += nrows; return(*status); } /*--------------------------------------------------------------------------*/ int ffdrow(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstrow, /* I - first row to delete (1 = first) */ LONGLONG nrows, /* I - number of rows to delete */ int *status) /* IO - error status */ /* delete NROWS rows from table starting with firstrow (1 = first row of table). */ { int tstatus; LONGLONG naxis1, naxis2; LONGLONG datasize, firstbyte, nbytes, nshift; LONGLONG freespace; long nblock; char comm[FLEN_COMMENT]; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only delete rows in TABLE or BINTABLE extension (ffdrow)"); return(*status = NOT_TABLE); } if (nrows < 0 ) return(*status = NEG_BYTES); else if (nrows == 0) return(*status); /* no op, so just return */ ffgkyjj(fptr, "NAXIS1", &naxis1, comm, status); /* get the current */ /* ffgkyj(fptr, "NAXIS2", &naxis2, comm, status);*/ /* size of the table */ /* the NAXIS2 keyword may not be up to date, so use the structure value */ naxis2 = (fptr->Fptr)->numrows; if (firstrow > naxis2) { ffpmsg( "Delete position greater than the number of rows in the table (ffdrow)"); return(*status = BAD_ROW_NUM); } else if (firstrow < 1) { ffpmsg("Delete position is less than 1 (ffdrow)"); return(*status = BAD_ROW_NUM); } else if (firstrow + nrows - 1 > naxis2) { ffpmsg("No. of rows to delete exceeds size of table (ffdrow)"); return(*status = BAD_ROW_NUM); } nshift = naxis1 * nrows; /* no. of bytes to delete from table */ /* cur size of data */ datasize = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; firstbyte = naxis1 * (firstrow + nrows - 1); /* relative del pos */ nbytes = datasize - firstbyte; /* no. of bytes to shift up */ firstbyte += ((fptr->Fptr)->datastart); /* absolute delete position */ ffshft(fptr, firstbyte, nbytes, nshift * (-1), status); /* shift data */ freespace = ( ( (datasize + 2879) / 2880) * 2880) - datasize; nblock = (long) ((nshift + freespace) / 2880); /* number of blocks */ /* delete integral number blocks */ if (nblock > 0) ffdblk(fptr, nblock, status); /* update the heap starting address */ (fptr->Fptr)->heapstart -= nshift; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (long)(fptr->Fptr)->heapstart, "&", &tstatus); /* update the NAXIS2 keyword */ ffmkyj(fptr, "NAXIS2", naxis2 - nrows, "&", status); ((fptr->Fptr)->numrows) -= nrows; ((fptr->Fptr)->origrows) -= nrows; /* Update the heap data, if any. This will remove any orphaned data */ /* that was only pointed to by the rows that have been deleted */ ffcmph(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffdrrg(fitsfile *fptr, /* I - FITS file pointer to table */ char *ranges, /* I - ranges of rows to delete (1 = first) */ int *status) /* IO - error status */ /* delete the ranges of rows from the table (1 = first row of table). The 'ranges' parameter typically looks like: '10-20, 30 - 40, 55' or '50-' and gives a list of rows or row ranges separated by commas. */ { char *cptr; int nranges, nranges2, ii; long *minrow, *maxrow, nrows, *rowarray, jj, kk; LONGLONG naxis2; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only delete rows in TABLE or BINTABLE extension (ffdrrg)"); return(*status = NOT_TABLE); } /* the NAXIS2 keyword may not be up to date, so use the structure value */ naxis2 = (fptr->Fptr)->numrows; /* find how many ranges were specified ( = no. of commas in string + 1) */ cptr = ranges; for (nranges = 1; (cptr = strchr(cptr, ',')); nranges++) cptr++; minrow = calloc(nranges, sizeof(long)); maxrow = calloc(nranges, sizeof(long)); if (!minrow || !maxrow) { *status = MEMORY_ALLOCATION; ffpmsg("failed to allocate memory for row ranges (ffdrrg)"); if (maxrow) free(maxrow); if (minrow) free(minrow); return(*status); } /* parse range list into array of range min and max values */ ffrwrg(ranges, naxis2, nranges, &nranges2, minrow, maxrow, status); if (*status > 0 || nranges2 == 0) { free(maxrow); free(minrow); return(*status); } /* determine total number or rows to delete */ nrows = 0; for (ii = 0; ii < nranges2; ii++) { nrows = nrows + maxrow[ii] - minrow[ii] + 1; } rowarray = calloc(nrows, sizeof(long)); if (!rowarray) { *status = MEMORY_ALLOCATION; ffpmsg("failed to allocate memory for row array (ffdrrg)"); return(*status); } for (kk = 0, ii = 0; ii < nranges2; ii++) { for (jj = minrow[ii]; jj <= maxrow[ii]; jj++) { rowarray[kk] = jj; kk++; } } /* delete the rows */ ffdrws(fptr, rowarray, nrows, status); free(rowarray); free(maxrow); free(minrow); return(*status); } /*--------------------------------------------------------------------------*/ int ffdrws(fitsfile *fptr, /* I - FITS file pointer */ long *rownum, /* I - list of rows to delete (1 = first) */ long nrows, /* I - number of rows to delete */ int *status) /* IO - error status */ /* delete the list of rows from the table (1 = first row of table). */ { LONGLONG naxis1, naxis2, insertpos, nextrowpos; long ii, nextrow; char comm[FLEN_COMMENT]; unsigned char *buffer; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only delete rows in TABLE or BINTABLE extension (ffdrws)"); return(*status = NOT_TABLE); } if (nrows < 0 ) return(*status = NEG_BYTES); else if (nrows == 0) return(*status); /* no op, so just return */ ffgkyjj(fptr, "NAXIS1", &naxis1, comm, status); /* row width */ ffgkyjj(fptr, "NAXIS2", &naxis2, comm, status); /* number of rows */ /* check that input row list is in ascending order */ for (ii = 1; ii < nrows; ii++) { if (rownum[ii - 1] >= rownum[ii]) { ffpmsg("row numbers are not in increasing order (ffdrws)"); return(*status = BAD_ROW_NUM); } } if (rownum[0] < 1) { ffpmsg("first row to delete is less than 1 (ffdrws)"); return(*status = BAD_ROW_NUM); } else if (rownum[nrows - 1] > naxis2) { ffpmsg("last row to delete exceeds size of table (ffdrws)"); return(*status = BAD_ROW_NUM); } buffer = (unsigned char *) malloc( (size_t) naxis1); /* buffer for one row */ if (!buffer) { ffpmsg("malloc failed (ffdrws)"); return(*status = MEMORY_ALLOCATION); } /* byte location to start of first row to delete, and the next row */ insertpos = (fptr->Fptr)->datastart + ((rownum[0] - 1) * naxis1); nextrowpos = insertpos + naxis1; nextrow = rownum[0] + 1; /* work through the list of rows to delete */ for (ii = 1; ii < nrows; nextrow++, nextrowpos += naxis1) { if (nextrow < rownum[ii]) { /* keep this row, so copy it to the new position */ ffmbyt(fptr, nextrowpos, REPORT_EOF, status); ffgbyt(fptr, naxis1, buffer, status); /* read the bytes */ ffmbyt(fptr, insertpos, IGNORE_EOF, status); ffpbyt(fptr, naxis1, buffer, status); /* write the bytes */ if (*status > 0) { ffpmsg("error while copying good rows in table (ffdrws)"); free(buffer); return(*status); } insertpos += naxis1; } else { /* skip over this row since it is in the list */ ii++; } } /* finished with all the rows to delete; copy remaining rows */ while(nextrow <= naxis2) { ffmbyt(fptr, nextrowpos, REPORT_EOF, status); ffgbyt(fptr, naxis1, buffer, status); /* read the bytes */ ffmbyt(fptr, insertpos, IGNORE_EOF, status); ffpbyt(fptr, naxis1, buffer, status); /* write the bytes */ if (*status > 0) { ffpmsg("failed to copy remaining rows in table (ffdrws)"); free(buffer); return(*status); } insertpos += naxis1; nextrowpos += naxis1; nextrow++; } free(buffer); /* now delete the empty rows at the end of the table */ ffdrow(fptr, naxis2 - nrows + 1, nrows, status); /* Update the heap data, if any. This will remove any orphaned data */ /* that was only pointed to by the rows that have been deleted */ ffcmph(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffdrwsll(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *rownum, /* I - list of rows to delete (1 = first) */ LONGLONG nrows, /* I - number of rows to delete */ int *status) /* IO - error status */ /* delete the list of rows from the table (1 = first row of table). */ { LONGLONG insertpos, nextrowpos; LONGLONG naxis1, naxis2, ii, nextrow; char comm[FLEN_COMMENT]; unsigned char *buffer; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only delete rows in TABLE or BINTABLE extension (ffdrws)"); return(*status = NOT_TABLE); } if (nrows < 0 ) return(*status = NEG_BYTES); else if (nrows == 0) return(*status); /* no op, so just return */ ffgkyjj(fptr, "NAXIS1", &naxis1, comm, status); /* row width */ ffgkyjj(fptr, "NAXIS2", &naxis2, comm, status); /* number of rows */ /* check that input row list is in ascending order */ for (ii = 1; ii < nrows; ii++) { if (rownum[ii - 1] >= rownum[ii]) { ffpmsg("row numbers are not in increasing order (ffdrws)"); return(*status = BAD_ROW_NUM); } } if (rownum[0] < 1) { ffpmsg("first row to delete is less than 1 (ffdrws)"); return(*status = BAD_ROW_NUM); } else if (rownum[nrows - 1] > naxis2) { ffpmsg("last row to delete exceeds size of table (ffdrws)"); return(*status = BAD_ROW_NUM); } buffer = (unsigned char *) malloc( (size_t) naxis1); /* buffer for one row */ if (!buffer) { ffpmsg("malloc failed (ffdrwsll)"); return(*status = MEMORY_ALLOCATION); } /* byte location to start of first row to delete, and the next row */ insertpos = (fptr->Fptr)->datastart + ((rownum[0] - 1) * naxis1); nextrowpos = insertpos + naxis1; nextrow = rownum[0] + 1; /* work through the list of rows to delete */ for (ii = 1; ii < nrows; nextrow++, nextrowpos += naxis1) { if (nextrow < rownum[ii]) { /* keep this row, so copy it to the new position */ ffmbyt(fptr, nextrowpos, REPORT_EOF, status); ffgbyt(fptr, naxis1, buffer, status); /* read the bytes */ ffmbyt(fptr, insertpos, IGNORE_EOF, status); ffpbyt(fptr, naxis1, buffer, status); /* write the bytes */ if (*status > 0) { ffpmsg("error while copying good rows in table (ffdrws)"); free(buffer); return(*status); } insertpos += naxis1; } else { /* skip over this row since it is in the list */ ii++; } } /* finished with all the rows to delete; copy remaining rows */ while(nextrow <= naxis2) { ffmbyt(fptr, nextrowpos, REPORT_EOF, status); ffgbyt(fptr, naxis1, buffer, status); /* read the bytes */ ffmbyt(fptr, insertpos, IGNORE_EOF, status); ffpbyt(fptr, naxis1, buffer, status); /* write the bytes */ if (*status > 0) { ffpmsg("failed to copy remaining rows in table (ffdrws)"); free(buffer); return(*status); } insertpos += naxis1; nextrowpos += naxis1; nextrow++; } free(buffer); /* now delete the empty rows at the end of the table */ ffdrow(fptr, naxis2 - nrows + 1, nrows, status); /* Update the heap data, if any. This will remove any orphaned data */ /* that was only pointed to by the rows that have been deleted */ ffcmph(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffrwrg( char *rowlist, /* I - list of rows and row ranges */ LONGLONG maxrows, /* I - number of rows in the table */ int maxranges, /* I - max number of ranges to be returned */ int *numranges, /* O - number ranges returned */ long *minrow, /* O - first row in each range */ long *maxrow, /* O - last row in each range */ int *status) /* IO - status value */ { /* parse the input list of row ranges, returning the number of ranges, and the min and max row value in each range. The only characters allowed in the input rowlist are decimal digits, minus sign, and comma (and non-significant spaces) Example: list = "10-20, 30-35,50" would return numranges = 3, minrow[] = {10, 30, 50}, maxrow[] = {20, 35, 50} error is returned if min value of range is > max value of range or if the ranges are not monotonically increasing. */ char *next; long minval, maxval; if (*status > 0) return(*status); if (maxrows <= 0 ) { *status = RANGE_PARSE_ERROR; ffpmsg("Input maximum range value is <= 0 (fits_parse_ranges)"); return(*status); } next = rowlist; *numranges = 0; while (*next == ' ')next++; /* skip spaces */ while (*next != '\0') { /* find min value of next range; *next must be '-' or a digit */ if (*next == '-') { minval = 1; /* implied minrow value = 1 */ } else if ( isdigit((int) *next) ) { minval = strtol(next, &next, 10); } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } while (*next == ' ')next++; /* skip spaces */ /* find max value of next range; *next must be '-', or ',' */ if (*next == '-') { next++; while (*next == ' ')next++; /* skip spaces */ if ( isdigit((int) *next) ) { maxval = strtol(next, &next, 10); } else if (*next == ',' || *next == '\0') { maxval = (long) maxrows; /* implied max value */ } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } } else if (*next == ',' || *next == '\0') { maxval = minval; /* only a single integer in this range */ } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } if (*numranges + 1 > maxranges) { *status = RANGE_PARSE_ERROR; ffpmsg("Overflowed maximum number of ranges (fits_parse_ranges)"); return(*status); } if (minval < 1 ) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list: row number < 1"); ffpmsg(rowlist); return(*status); } if (maxval < minval) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list: min > max"); ffpmsg(rowlist); return(*status); } if (*numranges > 0) { if (minval <= maxrow[(*numranges) - 1]) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list. Range minimum is"); ffpmsg(" less than or equal to previous range maximum"); ffpmsg(rowlist); return(*status); } } if (minval <= maxrows) { /* ignore range if greater than maxrows */ if (maxval > maxrows) maxval = (long) maxrows; minrow[*numranges] = minval; maxrow[*numranges] = maxval; (*numranges)++; } while (*next == ' ')next++; /* skip spaces */ if (*next == ',') { next++; while (*next == ' ')next++; /* skip more spaces */ } } if (*numranges == 0) { /* a null string was entered */ minrow[0] = 1; maxrow[0] = (long) maxrows; *numranges = 1; } return(*status); } /*--------------------------------------------------------------------------*/ int ffrwrgll( char *rowlist, /* I - list of rows and row ranges */ LONGLONG maxrows, /* I - number of rows in the list */ int maxranges, /* I - max number of ranges to be returned */ int *numranges, /* O - number ranges returned */ LONGLONG *minrow, /* O - first row in each range */ LONGLONG *maxrow, /* O - last row in each range */ int *status) /* IO - status value */ { /* parse the input list of row ranges, returning the number of ranges, and the min and max row value in each range. The only characters allowed in the input rowlist are decimal digits, minus sign, and comma (and non-significant spaces) Example: list = "10-20, 30-35,50" would return numranges = 3, minrow[] = {10, 30, 50}, maxrow[] = {20, 35, 50} error is returned if min value of range is > max value of range or if the ranges are not monotonically increasing. */ char *next; LONGLONG minval, maxval; double dvalue; if (*status > 0) return(*status); if (maxrows <= 0 ) { *status = RANGE_PARSE_ERROR; ffpmsg("Input maximum range value is <= 0 (fits_parse_ranges)"); return(*status); } next = rowlist; *numranges = 0; while (*next == ' ')next++; /* skip spaces */ while (*next != '\0') { /* find min value of next range; *next must be '-' or a digit */ if (*next == '-') { minval = 1; /* implied minrow value = 1 */ } else if ( isdigit((int) *next) ) { /* read as a double, because the string to LONGLONG function */ /* is platform dependent (strtoll, strtol, _atoI64) */ dvalue = strtod(next, &next); minval = (LONGLONG) (dvalue + 0.1); } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } while (*next == ' ')next++; /* skip spaces */ /* find max value of next range; *next must be '-', or ',' */ if (*next == '-') { next++; while (*next == ' ')next++; /* skip spaces */ if ( isdigit((int) *next) ) { /* read as a double, because the string to LONGLONG function */ /* is platform dependent (strtoll, strtol, _atoI64) */ dvalue = strtod(next, &next); maxval = (LONGLONG) (dvalue + 0.1); } else if (*next == ',' || *next == '\0') { maxval = maxrows; /* implied max value */ } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } } else if (*next == ',' || *next == '\0') { maxval = minval; /* only a single integer in this range */ } else { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list:"); ffpmsg(rowlist); return(*status); } if (*numranges + 1 > maxranges) { *status = RANGE_PARSE_ERROR; ffpmsg("Overflowed maximum number of ranges (fits_parse_ranges)"); return(*status); } if (minval < 1 ) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list: row number < 1"); ffpmsg(rowlist); return(*status); } if (maxval < minval) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list: min > max"); ffpmsg(rowlist); return(*status); } if (*numranges > 0) { if (minval <= maxrow[(*numranges) - 1]) { *status = RANGE_PARSE_ERROR; ffpmsg("Syntax error in this row range list. Range minimum is"); ffpmsg(" less than or equal to previous range maximum"); ffpmsg(rowlist); return(*status); } } if (minval <= maxrows) { /* ignore range if greater than maxrows */ if (maxval > maxrows) maxval = maxrows; minrow[*numranges] = minval; maxrow[*numranges] = maxval; (*numranges)++; } while (*next == ' ')next++; /* skip spaces */ if (*next == ',') { next++; while (*next == ' ')next++; /* skip more spaces */ } } if (*numranges == 0) { /* a null string was entered */ minrow[0] = 1; maxrow[0] = maxrows; *numranges = 1; } return(*status); } /*--------------------------------------------------------------------------*/ int fficol(fitsfile *fptr, /* I - FITS file pointer */ int numcol, /* I - position for new col. (1 = 1st) */ char *ttype, /* I - name of column (TTYPE keyword) */ char *tform, /* I - format of column (TFORM keyword) */ int *status) /* IO - error status */ /* Insert a new column into an existing table at position numcol. If numcol is greater than the number of existing columns in the table then the new column will be appended as the last column in the table. */ { char *name, *format; name = ttype; format = tform; fficls(fptr, numcol, 1, &name, &format, status); return(*status); } /*--------------------------------------------------------------------------*/ int fficls(fitsfile *fptr, /* I - FITS file pointer */ int fstcol, /* I - position for first new col. (1 = 1st) */ int ncols, /* I - number of columns to insert */ char **ttype, /* I - array of column names(TTYPE keywords) */ char **tform, /* I - array of formats of column (TFORM) */ int *status) /* IO - error status */ /* Insert 1 or more new columns into an existing table at position numcol. If fstcol is greater than the number of existing columns in the table then the new column will be appended as the last column in the table. */ { int colnum, datacode, decims, tfields, tstatus, ii; LONGLONG datasize, firstbyte, nbytes, nadd, naxis1, naxis2, freespace; LONGLONG tbcol, firstcol, delbyte; long nblock, width, repeat; char tfm[FLEN_VALUE], keyname[FLEN_KEYWORD], comm[FLEN_COMMENT], *cptr; tcolumn *colptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg("Can only add columns to TABLE or BINTABLE extension (fficol)"); return(*status = NOT_TABLE); } /* is the column number valid? */ tfields = (fptr->Fptr)->tfield; if (fstcol < 1 ) return(*status = BAD_COL_NUM); else if (fstcol > tfields) colnum = tfields + 1; /* append as last column */ else colnum = fstcol; /* parse the tform value and calc number of bytes to add to each row */ delbyte = 0; for (ii = 0; ii < ncols; ii++) { strcpy(tfm, tform[ii]); ffupch(tfm); /* make sure format is in upper case */ if ((fptr->Fptr)->hdutype == ASCII_TBL) { ffasfm(tfm, &datacode, &width, &decims, status); delbyte += width + 1; /* add one space between the columns */ } else { ffbnfm(tfm, &datacode, &repeat, &width, status); if (datacode < 0) /* variable length array column */ delbyte += 8; else if (datacode == 1) /* bit column; round up */ delbyte += (repeat + 7) / 8; /* to multiple of 8 bits */ else if (datacode == 16) /* ASCII string column */ delbyte += repeat; else /* numerical data type */ delbyte += (datacode / 10) * repeat; } } if (*status > 0) return(*status); /* get the current size of the table */ /* use internal structure since NAXIS2 keyword may not be up to date */ naxis1 = (fptr->Fptr)->rowlength; naxis2 = (fptr->Fptr)->numrows; /* current size of data */ datasize = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ( ( (datasize + 2879) / 2880) * 2880) - datasize; nadd = delbyte * naxis2; /* no. of bytes to add to table */ if ( (freespace - nadd) < 0) /* not enough existing space? */ { nblock = (long) ((nadd - freespace + 2879) / 2880); /* number of blocks */ if (ffiblk(fptr, nblock, 1, status) > 0) /* insert the blocks */ return(*status); } /* shift heap down (if it exists) */ if ((fptr->Fptr)->heapsize > 0) { nbytes = (fptr->Fptr)->heapsize; /* no. of bytes to shift down */ /* absolute heap pos */ firstbyte = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; if (ffshft(fptr, firstbyte, nbytes, nadd, status) > 0) /* move heap */ return(*status); } /* update the heap starting address */ (fptr->Fptr)->heapstart += nadd; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (fptr->Fptr)->heapstart, "&", &tstatus); /* calculate byte position in the row where to insert the new column */ if (colnum > tfields) firstcol = naxis1; else { colptr = (fptr->Fptr)->tableptr; colptr += (colnum - 1); firstcol = colptr->tbcol; } /* insert delbyte bytes in every row, at byte position firstcol */ ffcins(fptr, naxis1, naxis2, delbyte, firstcol, status); if ((fptr->Fptr)->hdutype == ASCII_TBL) { /* adjust the TBCOL values of the existing columns */ for(ii = 0; ii < tfields; ii++) { ffkeyn("TBCOL", ii + 1, keyname, status); ffgkyjj(fptr, keyname, &tbcol, comm, status); if (tbcol > firstcol) { tbcol += delbyte; ffmkyj(fptr, keyname, tbcol, "&", status); } } } /* update the mandatory keywords */ ffmkyj(fptr, "TFIELDS", tfields + ncols, "&", status); ffmkyj(fptr, "NAXIS1", naxis1 + delbyte, "&", status); /* increment the index value on any existing column keywords */ if(colnum <= tfields) ffkshf(fptr, colnum, tfields, ncols, status); /* add the required keywords for the new columns */ for (ii = 0; ii < ncols; ii++, colnum++) { strcpy(comm, "label for field"); ffkeyn("TTYPE", colnum, keyname, status); ffpkys(fptr, keyname, ttype[ii], comm, status); strcpy(comm, "format of field"); strcpy(tfm, tform[ii]); ffupch(tfm); /* make sure format is in upper case */ ffkeyn("TFORM", colnum, keyname, status); if (abs(datacode) == TSBYTE) { /* Replace the 'S' with an 'B' in the TFORMn code */ cptr = tfm; while (*cptr != 'S') cptr++; *cptr = 'B'; ffpkys(fptr, keyname, tfm, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", colnum, keyname, status); strcpy(comm, "offset for signed bytes"); ffpkyg(fptr, keyname, -128., 0, comm, status); ffkeyn("TSCAL", colnum, keyname, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, keyname, 1., 0, comm, status); } else if (abs(datacode) == TUSHORT) { /* Replace the 'U' with an 'I' in the TFORMn code */ cptr = tfm; while (*cptr != 'U') cptr++; *cptr = 'I'; ffpkys(fptr, keyname, tfm, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", colnum, keyname, status); strcpy(comm, "offset for unsigned integers"); ffpkyg(fptr, keyname, 32768., 0, comm, status); ffkeyn("TSCAL", colnum, keyname, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, keyname, 1., 0, comm, status); } else if (abs(datacode) == TULONG) { /* Replace the 'V' with an 'J' in the TFORMn code */ cptr = tfm; while (*cptr != 'V') cptr++; *cptr = 'J'; ffpkys(fptr, keyname, tfm, comm, status); /* write the TZEROn and TSCALn keywords */ ffkeyn("TZERO", colnum, keyname, status); strcpy(comm, "offset for unsigned integers"); ffpkyg(fptr, keyname, 2147483648., 0, comm, status); ffkeyn("TSCAL", colnum, keyname, status); strcpy(comm, "data are not scaled"); ffpkyg(fptr, keyname, 1., 0, comm, status); } else { ffpkys(fptr, keyname, tfm, comm, status); } if ((fptr->Fptr)->hdutype == ASCII_TBL) /* write the TBCOL keyword */ { if (colnum == tfields + 1) tbcol = firstcol + 2; /* allow space between preceding col */ else tbcol = firstcol + 1; strcpy(comm, "beginning column of field"); ffkeyn("TBCOL", colnum, keyname, status); ffpkyj(fptr, keyname, tbcol, comm, status); /* increment the column starting position for the next column */ ffasfm(tfm, &datacode, &width, &decims, status); firstcol += width + 1; /* add one space between the columns */ } } ffrdef(fptr, status); /* initialize the new table structure */ return(*status); } /*--------------------------------------------------------------------------*/ int ffmvec(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - position of col to be modified */ LONGLONG newveclen, /* I - new vector length of column (TFORM) */ int *status) /* IO - error status */ /* Modify the vector length of a column in a binary table, larger or smaller. E.g., change a column from TFORMn = '1E' to '20E'. */ { int datacode, tfields, tstatus; LONGLONG datasize, size, firstbyte, nbytes, nadd, ndelete; LONGLONG naxis1, naxis2, firstcol, freespace; LONGLONG width, delbyte, repeat; long nblock; char tfm[FLEN_VALUE], keyname[FLEN_KEYWORD], tcode[2]; tcolumn *colptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype != BINARY_TBL) { ffpmsg( "Can only change vector length of a column in BINTABLE extension (ffmvec)"); return(*status = NOT_TABLE); } /* is the column number valid? */ tfields = (fptr->Fptr)->tfield; if (colnum < 1 || colnum > tfields) return(*status = BAD_COL_NUM); /* look up the current vector length and element width */ colptr = (fptr->Fptr)->tableptr; colptr += (colnum - 1); datacode = colptr->tdatatype; /* datatype of the column */ repeat = colptr->trepeat; /* field repeat count */ width = colptr->twidth; /* width of a single element in chars */ if (datacode < 0) { ffpmsg( "Can't modify vector length of variable length column (ffmvec)"); return(*status = BAD_TFORM); } if (repeat == newveclen) return(*status); /* column already has the desired vector length */ if (datacode == TSTRING) width = 1; /* width was equal to width of unit string */ naxis1 = (fptr->Fptr)->rowlength; /* current width of the table */ naxis2 = (fptr->Fptr)->numrows; delbyte = (newveclen - repeat) * width; /* no. of bytes to insert */ if (datacode == TBIT) /* BIT column is a special case */ delbyte = ((newveclen + 1) / 8) - ((repeat + 1) / 8); if (delbyte > 0) /* insert space for more elements */ { /* current size of data */ datasize = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ( ( (datasize + 2879) / 2880) * 2880) - datasize; nadd = (LONGLONG)delbyte * naxis2; /* no. of bytes to add to table */ if ( (freespace - nadd) < 0) /* not enough existing space? */ { nblock = (long) ((nadd - freespace + 2879) / 2880); /* number of blocks */ if (ffiblk(fptr, nblock, 1, status) > 0) /* insert the blocks */ return(*status); } /* shift heap down (if it exists) */ if ((fptr->Fptr)->heapsize > 0) { nbytes = (fptr->Fptr)->heapsize; /* no. of bytes to shift down */ /* absolute heap pos */ firstbyte = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; if (ffshft(fptr, firstbyte, nbytes, nadd, status) > 0) /* move heap */ return(*status); } /* update the heap starting address */ (fptr->Fptr)->heapstart += nadd; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (fptr->Fptr)->heapstart, "&", &tstatus); firstcol = colptr->tbcol + (repeat * width); /* insert position */ /* insert delbyte bytes in every row, at byte position firstcol */ ffcins(fptr, naxis1, naxis2, delbyte, firstcol, status); } else if (delbyte < 0) { /* current size of table */ size = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ((size + 2879) / 2880) * 2880 - size - ((LONGLONG)delbyte * naxis2); nblock = (long) (freespace / 2880); /* number of empty blocks to delete */ firstcol = colptr->tbcol + (newveclen * width); /* delete position */ /* delete elements from the vector */ ffcdel(fptr, naxis1, naxis2, -delbyte, firstcol, status); /* abs heap pos */ firstbyte = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; ndelete = (LONGLONG)delbyte * naxis2; /* size of shift (negative) */ /* shift heap up (if it exists) */ if ((fptr->Fptr)->heapsize > 0) { nbytes = (fptr->Fptr)->heapsize; /* no. of bytes to shift up */ if (ffshft(fptr, firstbyte, nbytes, ndelete, status) > 0) return(*status); } /* delete the empty blocks at the end of the HDU */ if (nblock > 0) ffdblk(fptr, nblock, status); /* update the heap starting address */ (fptr->Fptr)->heapstart += ndelete; /* ndelete is negative */ /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (fptr->Fptr)->heapstart, "&", &tstatus); } /* construct the new TFORM keyword for the column */ if (datacode == TBIT) strcpy(tcode,"X"); else if (datacode == TBYTE) strcpy(tcode,"B"); else if (datacode == TLOGICAL) strcpy(tcode,"L"); else if (datacode == TSTRING) strcpy(tcode,"A"); else if (datacode == TSHORT) strcpy(tcode,"I"); else if (datacode == TLONG) strcpy(tcode,"J"); else if (datacode == TLONGLONG) strcpy(tcode,"K"); else if (datacode == TFLOAT) strcpy(tcode,"E"); else if (datacode == TDOUBLE) strcpy(tcode,"D"); else if (datacode == TCOMPLEX) strcpy(tcode,"C"); else if (datacode == TDBLCOMPLEX) strcpy(tcode,"M"); /* write as a double value because the LONGLONG conversion */ /* character in sprintf is platform dependent ( %lld, %ld, %I64d ) */ sprintf(tfm,"%.0f%s",(double) newveclen, tcode); ffkeyn("TFORM", colnum, keyname, status); /* Keyword name */ ffmkys(fptr, keyname, tfm, "&", status); /* modify TFORM keyword */ ffmkyj(fptr, "NAXIS1", naxis1 + delbyte, "&", status); /* modify NAXIS1 */ ffrdef(fptr, status); /* reinitialize the new table structure */ return(*status); } /*--------------------------------------------------------------------------*/ int ffcpcl(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int incol, /* I - number of input column */ int outcol, /* I - number for output column */ int create_col, /* I - create new col if TRUE, else overwrite */ int *status) /* IO - error status */ /* copy a column from infptr and insert it in the outfptr table. */ { int tstatus, colnum, typecode, anynull; long tfields, repeat, width, nrows, outrows; long inloop, outloop, maxloop, ndone, ntodo, npixels; long firstrow, firstelem, ii; char keyname[FLEN_KEYWORD], ttype[FLEN_VALUE], tform[FLEN_VALUE]; char ttype_comm[FLEN_COMMENT],tform_comm[FLEN_COMMENT]; char *lvalues = 0, nullflag, **strarray = 0; char nulstr[] = {'\5', '\0'}; /* unique null string value */ double dnull = 0.l, *dvalues = 0; float fnull = 0., *fvalues = 0; if (*status > 0) return(*status); if (infptr->HDUposition != (infptr->Fptr)->curhdu) { ffmahd(infptr, (infptr->HDUposition) + 1, NULL, status); } else if ((infptr->Fptr)->datastart == DATA_UNDEFINED) ffrdef(infptr, status); /* rescan header */ if (outfptr->HDUposition != (outfptr->Fptr)->curhdu) { ffmahd(outfptr, (outfptr->HDUposition) + 1, NULL, status); } else if ((outfptr->Fptr)->datastart == DATA_UNDEFINED) ffrdef(outfptr, status); /* rescan header */ if (*status > 0) return(*status); if ((infptr->Fptr)->hdutype == IMAGE_HDU || (outfptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg ("Can not copy columns to or from IMAGE HDUs (ffcpcl)"); return(*status = NOT_TABLE); } if ( (infptr->Fptr)->hdutype == BINARY_TBL && (outfptr->Fptr)->hdutype == ASCII_TBL) { ffpmsg ("Copying from Binary table to ASCII table is not supported (ffcpcl)"); return(*status = NOT_BTABLE); } /* get the datatype and vector repeat length of the column */ ffgtcl(infptr, incol, &typecode, &repeat, &width, status); if (typecode < 0) { ffpmsg("Variable-length columns are not supported (ffcpcl)"); return(*status = BAD_TFORM); } if (create_col) /* insert new column in output table? */ { tstatus = 0; ffkeyn("TTYPE", incol, keyname, &tstatus); ffgkys(infptr, keyname, ttype, ttype_comm, &tstatus); ffkeyn("TFORM", incol, keyname, &tstatus); if (ffgkys(infptr, keyname, tform, tform_comm, &tstatus) ) { ffpmsg ("Could not find TTYPE and TFORM keywords in input table (ffcpcl)"); return(*status = NO_TFORM); } if ((infptr->Fptr)->hdutype == ASCII_TBL && (outfptr->Fptr)->hdutype == BINARY_TBL) { /* convert from ASCII table to BINARY table format string */ if (typecode == TSTRING) ffnkey(width, "A", tform, status); else if (typecode == TLONG) strcpy(tform, "1J"); else if (typecode == TSHORT) strcpy(tform, "1I"); else if (typecode == TFLOAT) strcpy(tform,"1E"); else if (typecode == TDOUBLE) strcpy(tform,"1D"); } if (ffgkyj(outfptr, "TFIELDS", &tfields, 0, &tstatus)) { ffpmsg ("Could not read TFIELDS keyword in output table (ffcpcl)"); return(*status = NO_TFIELDS); } colnum = minvalue((int) tfields + 1, outcol); /* output col. number */ /* create the empty column */ if (fficol(outfptr, colnum, ttype, tform, status) > 0) { ffpmsg ("Could not append new column to output file (ffcpcl)"); return(*status); } /* copy the comment strings from the input file for TTYPE and TFORM */ tstatus = 0; ffkeyn("TTYPE", colnum, keyname, &tstatus); ffmcom(outfptr, keyname, ttype_comm, &tstatus); ffkeyn("TFORM", colnum, keyname, &tstatus); ffmcom(outfptr, keyname, tform_comm, &tstatus); /* copy other column-related keywords if they exist */ ffcpky(infptr, outfptr, incol, colnum, "TUNIT", status); ffcpky(infptr, outfptr, incol, colnum, "TSCAL", status); ffcpky(infptr, outfptr, incol, colnum, "TZERO", status); ffcpky(infptr, outfptr, incol, colnum, "TDISP", status); ffcpky(infptr, outfptr, incol, colnum, "TLMIN", status); ffcpky(infptr, outfptr, incol, colnum, "TLMAX", status); ffcpky(infptr, outfptr, incol, colnum, "TDIM", status); /* WCS keywords */ ffcpky(infptr, outfptr, incol, colnum, "TCTYP", status); ffcpky(infptr, outfptr, incol, colnum, "TCUNI", status); ffcpky(infptr, outfptr, incol, colnum, "TCRVL", status); ffcpky(infptr, outfptr, incol, colnum, "TCRPX", status); ffcpky(infptr, outfptr, incol, colnum, "TCDLT", status); ffcpky(infptr, outfptr, incol, colnum, "TCROT", status); if ((infptr->Fptr)->hdutype == ASCII_TBL && (outfptr->Fptr)->hdutype == BINARY_TBL) { /* binary tables only have TNULLn keyword for integer columns */ if (typecode == TLONG || typecode == TSHORT) { /* check if null string is defined; replace with integer */ ffkeyn("TNULL", incol, keyname, &tstatus); if (ffgkys(infptr, keyname, ttype, 0, &tstatus) <= 0) { ffkeyn("TNULL", colnum, keyname, &tstatus); if (typecode == TLONG) ffpkyj(outfptr, keyname, -9999999L, "Null value", status); else ffpkyj(outfptr, keyname, -32768L, "Null value", status); } } } else { ffcpky(infptr, outfptr, incol, colnum, "TNULL", status); } /* rescan header to recognize the new keywords */ if (ffrdef(outfptr, status) ) return(*status); } else { colnum = outcol; } ffgkyj(infptr, "NAXIS2", &nrows, 0, status); /* no. of input rows */ ffgkyj(outfptr, "NAXIS2", &outrows, 0, status); /* no. of output rows */ nrows = minvalue(nrows, outrows); if (typecode == TBIT) repeat = (repeat - 1) / 8 + 1; /* convert from bits to bytes */ else if (typecode == TSTRING && (infptr->Fptr)->hdutype == BINARY_TBL) repeat = repeat / width; /* convert from chars to unit strings */ /* get optimum number of rows to copy at one time */ ffgrsz(infptr, &inloop, status); ffgrsz(outfptr, &outloop, status); /* adjust optimum number, since 2 tables are open at once */ maxloop = minvalue(inloop, outloop); /* smallest of the 2 tables */ maxloop = maxvalue(1, maxloop / 2); /* at least 1 row */ maxloop = minvalue(maxloop, nrows); /* max = nrows to be copied */ maxloop *= repeat; /* mult by no of elements in a row */ /* allocate memory for arrays */ if (typecode == TLOGICAL) { lvalues = (char *) calloc(maxloop, sizeof(char) ); if (!lvalues) { ffpmsg ("malloc failed to get memory for logicals (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } } else if (typecode == TSTRING) { /* allocate array of pointers */ strarray = (char **) calloc(maxloop, sizeof(strarray)); /* allocate space for each string */ for (ii = 0; ii < maxloop; ii++) strarray[ii] = (char *) calloc(width+1, sizeof(char)); } else if (typecode == TCOMPLEX) { fvalues = (float *) calloc(maxloop * 2, sizeof(float) ); if (!fvalues) { ffpmsg ("malloc failed to get memory for complex (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } fnull = 0.; } else if (typecode == TDBLCOMPLEX) { dvalues = (double *) calloc(maxloop * 2, sizeof(double) ); if (!dvalues) { ffpmsg ("malloc failed to get memory for dbl complex (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } dnull = 0.; } else /* numerical datatype; read them all as doubles */ { dvalues = (double *) calloc(maxloop, sizeof(double) ); if (!dvalues) { ffpmsg ("malloc failed to get memory for doubles (ffcpcl)"); return(*status = ARRAY_TOO_BIG); } dnull = -9.99991999E31; /* use an unlikely value for nulls */ } npixels = nrows * repeat; /* total no. of pixels to copy */ ntodo = minvalue(npixels, maxloop); /* no. to copy per iteration */ ndone = 0; /* total no. of pixels that have been copied */ while (ntodo) /* iterate through the table */ { firstrow = ndone / repeat + 1; firstelem = ndone - ((firstrow - 1) * repeat) + 1; /* read from input table */ if (typecode == TLOGICAL) ffgcl(infptr, incol, firstrow, firstelem, ntodo, lvalues, status); else if (typecode == TSTRING) ffgcvs(infptr, incol, firstrow, firstelem, ntodo, nulstr, strarray, &anynull, status); else if (typecode == TCOMPLEX) ffgcvc(infptr, incol, firstrow, firstelem, ntodo, fnull, fvalues, &anynull, status); else if (typecode == TDBLCOMPLEX) ffgcvm(infptr, incol, firstrow, firstelem, ntodo, dnull, dvalues, &anynull, status); else /* all numerical types */ ffgcvd(infptr, incol, firstrow, firstelem, ntodo, dnull, dvalues, &anynull, status); if (*status > 0) { ffpmsg("Error reading input copy of column (ffcpcl)"); break; } /* write to output table */ if (typecode == TLOGICAL) { nullflag = 2; ffpcnl(outfptr, colnum, firstrow, firstelem, ntodo, lvalues, nullflag, status); } else if (typecode == TSTRING) { if (anynull) ffpcns(outfptr, colnum, firstrow, firstelem, ntodo, strarray, nulstr, status); else ffpcls(outfptr, colnum, firstrow, firstelem, ntodo, strarray, status); } else if (typecode == TCOMPLEX) { /* doesn't support writing nulls */ ffpclc(outfptr, colnum, firstrow, firstelem, ntodo, fvalues, status); } else if (typecode == TDBLCOMPLEX) { /* doesn't support writing nulls */ ffpclm(outfptr, colnum, firstrow, firstelem, ntodo, dvalues, status); } else /* all other numerical types */ { if (anynull) ffpcnd(outfptr, colnum, firstrow, firstelem, ntodo, dvalues, dnull, status); else ffpcld(outfptr, colnum, firstrow, firstelem, ntodo, dvalues, status); } if (*status > 0) { ffpmsg("Error writing output copy of column (ffcpcl)"); break; } npixels -= ntodo; ndone += ntodo; ntodo = minvalue(npixels, maxloop); } /* free the previously allocated memory */ if (typecode == TLOGICAL) { free(lvalues); } else if (typecode == TSTRING) { for (ii = 0; ii < maxloop; ii++) free(strarray[ii]); free(strarray); } else { if (fvalues) free(fvalues); if (dvalues) free(dvalues); } return(*status); } /*--------------------------------------------------------------------------*/ int ffcpky(fitsfile *infptr, /* I - FITS file pointer to input file */ fitsfile *outfptr, /* I - FITS file pointer to output file */ int incol, /* I - input index number */ int outcol, /* I - output index number */ char *rootname, /* I - root name of the keyword to be copied */ int *status) /* IO - error status */ /* copy an indexed keyword from infptr to outfptr. */ { int tstatus = 0; char keyname[FLEN_KEYWORD]; char value[FLEN_VALUE], comment[FLEN_COMMENT], card[FLEN_CARD]; ffkeyn(rootname, incol, keyname, &tstatus); if (ffgkey(infptr, keyname, value, comment, &tstatus) <= 0) { ffkeyn(rootname, outcol, keyname, &tstatus); ffmkky(keyname, value, comment, card, status); ffprec(outfptr, card, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffdcol(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column to delete (1 = 1st) */ int *status) /* IO - error status */ /* Delete a column from a table. */ { int ii, tstatus; LONGLONG firstbyte, size, ndelete, nbytes, naxis1, naxis2, firstcol, delbyte, freespace; LONGLONG tbcol; long nblock, nspace; char keyname[FLEN_KEYWORD], comm[FLEN_COMMENT]; tcolumn *colptr, *nextcol; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffpmsg ("Can only delete column from TABLE or BINTABLE extension (ffdcol)"); return(*status = NOT_TABLE); } if (colnum < 1 || colnum > (fptr->Fptr)->tfield ) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; colptr += (colnum - 1); firstcol = colptr->tbcol; /* starting byte position of the column */ /* use column width to determine how many bytes to delete in each row */ if ((fptr->Fptr)->hdutype == ASCII_TBL) { delbyte = colptr->twidth; /* width of ASCII column */ if (colnum < (fptr->Fptr)->tfield) /* check for space between next column */ { nextcol = colptr + 1; nspace = (long) ((nextcol->tbcol) - (colptr->tbcol) - delbyte); if (nspace > 0) delbyte++; } else if (colnum > 1) /* check for space between last 2 columns */ { nextcol = colptr - 1; nspace = (long) ((colptr->tbcol) - (nextcol->tbcol) - (nextcol->twidth)); if (nspace > 0) { delbyte++; firstcol--; /* delete the leading space */ } } } else /* a binary table */ { if (colnum < (fptr->Fptr)->tfield) { nextcol = colptr + 1; delbyte = (nextcol->tbcol) - (colptr->tbcol); } else { delbyte = ((fptr->Fptr)->rowlength) - (colptr->tbcol); } } naxis1 = (fptr->Fptr)->rowlength; /* current width of the table */ naxis2 = (fptr->Fptr)->numrows; /* current size of table */ size = (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; freespace = ((LONGLONG)delbyte * naxis2) + ((size + 2879) / 2880) * 2880 - size; nblock = (long) (freespace / 2880); /* number of empty blocks to delete */ ffcdel(fptr, naxis1, naxis2, delbyte, firstcol, status); /* delete col */ /* absolute heap position */ firstbyte = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; ndelete = (LONGLONG)delbyte * naxis2; /* size of shift */ /* shift heap up (if it exists) */ if ((fptr->Fptr)->heapsize > 0) { nbytes = (fptr->Fptr)->heapsize; /* no. of bytes to shift up */ if (ffshft(fptr, firstbyte, nbytes, -ndelete, status) > 0) /* mv heap */ return(*status); } /* delete the empty blocks at the end of the HDU */ if (nblock > 0) ffdblk(fptr, nblock, status); /* update the heap starting address */ (fptr->Fptr)->heapstart -= ndelete; /* update the THEAP keyword if it exists */ tstatus = 0; ffmkyj(fptr, "THEAP", (long)(fptr->Fptr)->heapstart, "&", &tstatus); if ((fptr->Fptr)->hdutype == ASCII_TBL) { /* adjust the TBCOL values of the remaining columns */ for (ii = 1; ii <= (fptr->Fptr)->tfield; ii++) { ffkeyn("TBCOL", ii, keyname, status); ffgkyjj(fptr, keyname, &tbcol, comm, status); if (tbcol > firstcol) { tbcol = tbcol - delbyte; ffmkyj(fptr, keyname, tbcol, "&", status); } } } /* update the mandatory keywords */ ffmkyj(fptr, "TFIELDS", ((fptr->Fptr)->tfield) - 1, "&", status); ffmkyj(fptr, "NAXIS1", naxis1 - delbyte, "&", status); /* delete the index keywords starting with 'T' associated with the deleted column and subtract 1 from index of all higher keywords */ ffkshf(fptr, colnum, (fptr->Fptr)->tfield, -1, status); ffrdef(fptr, status); /* initialize the new table structure */ return(*status); } /*--------------------------------------------------------------------------*/ int ffcins(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis1, /* I - width of the table, in bytes */ LONGLONG naxis2, /* I - number of rows in the table */ LONGLONG ninsert, /* I - number of bytes to insert in each row */ LONGLONG bytepos, /* I - rel. position in row to insert bytes */ int *status) /* IO - error status */ /* Insert 'ninsert' bytes into each row of the table at position 'bytepos'. */ { unsigned char buffer[10000], cfill; LONGLONG newlen, fbyte, nbytes, irow, nseg, ii; if (*status > 0) return(*status); if (naxis2 == 0) return(*status); /* just return if there are 0 rows in the table */ /* select appropriate fill value */ if ((fptr->Fptr)->hdutype == ASCII_TBL) cfill = 32; /* ASCII tables use blank fill */ else cfill = 0; /* primary array and binary tables use zero fill */ newlen = naxis1 + ninsert; if (newlen <= 10000) { /******************************************************************* CASE #1: optimal case where whole new row fits in the work buffer *******************************************************************/ for (ii = 0; ii < ninsert; ii++) buffer[ii] = cfill; /* initialize buffer with fill value */ /* first move the trailing bytes (if any) in the last row */ fbyte = bytepos + 1; nbytes = naxis1 - bytepos; ffgtbb(fptr, naxis2, fbyte, nbytes, &buffer[ninsert], status); (fptr->Fptr)->rowlength = newlen; /* new row length */ /* write the row (with leading fill bytes) in the new place */ nbytes += ninsert; ffptbb(fptr, naxis2, fbyte, nbytes, buffer, status); (fptr->Fptr)->rowlength = naxis1; /* reset to orig. value */ /* now move the rest of the rows */ for (irow = naxis2 - 1; irow > 0; irow--) { /* read the row to be shifted (work backwards thru the table) */ ffgtbb(fptr, irow, fbyte, naxis1, &buffer[ninsert], status); (fptr->Fptr)->rowlength = newlen; /* new row length */ /* write the row (with the leading fill bytes) in the new place */ ffptbb(fptr, irow, fbyte, newlen, buffer, status); (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ } } else { /***************************************************************** CASE #2: whole row doesn't fit in work buffer; move row in pieces ****************************************************************** first copy the data, then go back and write fill into the new column start by copying the trailing bytes (if any) in the last row. */ nbytes = naxis1 - bytepos; nseg = (nbytes + 9999) / 10000; fbyte = (nseg - 1) * 10000 + bytepos + 1; nbytes = naxis1 - fbyte + 1; for (ii = 0; ii < nseg; ii++) { ffgtbb(fptr, naxis2, fbyte, nbytes, buffer, status); (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, naxis2, fbyte + ninsert, nbytes, buffer, status); (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ fbyte -= 10000; nbytes = 10000; } /* now move the rest of the rows */ nseg = (naxis1 + 9999) / 10000; for (irow = naxis2 - 1; irow > 0; irow--) { fbyte = (nseg - 1) * 10000 + bytepos + 1; nbytes = naxis1 - (nseg - 1) * 10000; for (ii = 0; ii < nseg; ii++) { /* read the row to be shifted (work backwards thru the table) */ ffgtbb(fptr, irow, fbyte, nbytes, buffer, status); (fptr->Fptr)->rowlength = newlen; /* new row length */ /* write the row in the new place */ ffptbb(fptr, irow, fbyte + ninsert, nbytes, buffer, status); (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ fbyte -= 10000; nbytes = 10000; } } /* now write the fill values into the new column */ nbytes = minvalue(ninsert, 10000); memset(buffer, cfill, (size_t) nbytes); /* initialize with fill value */ nseg = (ninsert + 9999) / 10000; (fptr->Fptr)->rowlength = newlen; /* new row length */ for (irow = 1; irow <= naxis2; irow++) { fbyte = bytepos + 1; nbytes = ninsert - ((nseg - 1) * 10000); for (ii = 0; ii < nseg; ii++) { ffptbb(fptr, irow, fbyte, nbytes, buffer, status); fbyte += nbytes; nbytes = 10000; } } (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffcdel(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG naxis1, /* I - width of the table, in bytes */ LONGLONG naxis2, /* I - number of rows in the table */ LONGLONG ndelete, /* I - number of bytes to delete in each row */ LONGLONG bytepos, /* I - rel. position in row to delete bytes */ int *status) /* IO - error status */ /* delete 'ndelete' bytes from each row of the table at position 'bytepos'. */ { unsigned char buffer[10000]; LONGLONG i1, i2, ii, irow, nseg; LONGLONG newlen, remain, nbytes; if (*status > 0) return(*status); if (naxis2 == 0) return(*status); /* just return if there are 0 rows in the table */ newlen = naxis1 - ndelete; if (newlen <= 10000) { /******************************************************************* CASE #1: optimal case where whole new row fits in the work buffer *******************************************************************/ i1 = bytepos + 1; i2 = i1 + ndelete; for (irow = 1; irow < naxis2; irow++) { ffgtbb(fptr, irow, i2, newlen, buffer, status); /* read row */ (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, irow, i1, newlen, buffer, status); /* write row */ (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ } /* now do the last row */ remain = naxis1 - (bytepos + ndelete); if (remain > 0) { ffgtbb(fptr, naxis2, i2, remain, buffer, status); /* read row */ (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, naxis2, i1, remain, buffer, status); /* write row */ (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ } } else { /***************************************************************** CASE #2: whole row doesn't fit in work buffer; move row in pieces ******************************************************************/ nseg = (newlen + 9999) / 10000; for (irow = 1; irow < naxis2; irow++) { i1 = bytepos + 1; i2 = i1 + ndelete; nbytes = newlen - (nseg - 1) * 10000; for (ii = 0; ii < nseg; ii++) { ffgtbb(fptr, irow, i2, nbytes, buffer, status); /* read bytes */ (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, irow, i1, nbytes, buffer, status); /* rewrite bytes */ (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ i1 += nbytes; i2 += nbytes; nbytes = 10000; } } /* now do the last row */ remain = naxis1 - (bytepos + ndelete); if (remain > 0) { nseg = (remain + 9999) / 10000; i1 = bytepos + 1; i2 = i1 + ndelete; nbytes = remain - (nseg - 1) * 10000; for (ii = 0; ii < nseg; ii++) { ffgtbb(fptr, naxis2, i2, nbytes, buffer, status); (fptr->Fptr)->rowlength = newlen; /* new row length */ ffptbb(fptr, naxis2, i1, nbytes, buffer, status); /* write row */ (fptr->Fptr)->rowlength = naxis1; /* reset to orig value */ i1 += nbytes; i2 += nbytes; nbytes = 10000; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffkshf(fitsfile *fptr, /* I - FITS file pointer */ int colmin, /* I - starting col. to be incremented; 1 = 1st */ int colmax, /* I - last column to be incremented */ int incre, /* I - shift index number by this amount */ int *status) /* IO - error status */ /* shift the index value on any existing column keywords This routine will modify the name of any keyword that begins with 'T' and has an index number in the range COLMIN - COLMAX, inclusive. if incre is positive, then the index values will be incremented. if incre is negative, then the kewords with index = COLMIN will be deleted and the index of higher numbered keywords will be decremented. */ { int nkeys, nmore, nrec, tstatus, i1; long ivalue; char rec[FLEN_CARD], q[FLEN_KEYWORD], newkey[FLEN_KEYWORD]; ffghsp(fptr, &nkeys, &nmore, status); /* get number of keywords */ /* go thru header starting with the 9th keyword looking for 'TxxxxNNN' */ for (nrec = 9; nrec <= nkeys; nrec++) { ffgrec(fptr, nrec, rec, status); if (rec[0] == 'T') { i1 = 0; strncpy(q, &rec[1], 4); if (!strncmp(q, "BCOL", 4) || !strncmp(q, "FORM", 4) || !strncmp(q, "TYPE", 4) || !strncmp(q, "SCAL", 4) || !strncmp(q, "UNIT", 4) || !strncmp(q, "NULL", 4) || !strncmp(q, "ZERO", 4) || !strncmp(q, "DISP", 4) || !strncmp(q, "LMIN", 4) || !strncmp(q, "LMAX", 4) || !strncmp(q, "DMIN", 4) || !strncmp(q, "DMAX", 4) || !strncmp(q, "CTYP", 4) || !strncmp(q, "CRPX", 4) || !strncmp(q, "CRVL", 4) || !strncmp(q, "CDLT", 4) || !strncmp(q, "CROT", 4) || !strncmp(q, "CUNI", 4) ) i1 = 5; else if (!strncmp(rec, "TDIM", 4) ) i1 = 4; if (i1) { /* try reading the index number suffix */ q[0] = '\0'; strncat(q, &rec[i1], 8 - i1); tstatus = 0; ffc2ii(q, &ivalue, &tstatus); if (tstatus == 0 && ivalue >= colmin && ivalue <= colmax) { if (incre <= 0 && ivalue == colmin) { ffdrec(fptr, nrec, status); /* delete keyword */ nkeys = nkeys - 1; nrec = nrec - 1; } else { ivalue = ivalue + incre; q[0] = '\0'; strncat(q, rec, i1); ffkeyn(q, ivalue, newkey, status); strncpy(rec, " ", 8); /* erase old keyword name */ i1 = strlen(newkey); strncpy(rec, newkey, i1); /* overwrite new keyword name */ ffmrec(fptr, nrec, rec, status); /* modify the record */ } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffshft(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstbyte, /* I - position of first byte in block to shift */ LONGLONG nbytes, /* I - size of block of bytes to shift */ LONGLONG nshift, /* I - size of shift in bytes (+ or -) */ int *status) /* IO - error status */ /* Shift block of bytes by nshift bytes (positive or negative). A positive nshift value moves the block down further in the file, while a negative value shifts the block towards the beginning of the file. */ { #define shftbuffsize 100000 long ntomov; LONGLONG ptr, ntodo; char buffer[shftbuffsize]; if (*status > 0) return(*status); ntodo = nbytes; /* total number of bytes to shift */ if (nshift > 0) /* start at the end of the block and work backwards */ ptr = firstbyte + nbytes; else /* start at the beginning of the block working forwards */ ptr = firstbyte; while (ntodo) { /* number of bytes to move at one time */ ntomov = (long) (minvalue(ntodo, shftbuffsize)); if (nshift > 0) /* if moving block down ... */ ptr -= ntomov; /* move to position and read the bytes to be moved */ ffmbyt(fptr, ptr, REPORT_EOF, status); ffgbyt(fptr, ntomov, buffer, status); /* move by shift amount and write the bytes */ ffmbyt(fptr, ptr + nshift, IGNORE_EOF, status); if (ffpbyt(fptr, ntomov, buffer, status) > 0) { ffpmsg("Error while shifting block (ffshft)"); return(*status); } ntodo -= ntomov; if (nshift < 0) /* if moving block up ... */ ptr += ntomov; } /* now overwrite the old data with fill */ if ((fptr->Fptr)->hdutype == ASCII_TBL) memset(buffer, 32, shftbuffsize); /* fill ASCII tables with spaces */ else memset(buffer, 0, shftbuffsize); /* fill other HDUs with zeros */ if (nshift < 0) { ntodo = -nshift; /* point to the end of the shifted block */ ptr = firstbyte + nbytes + nshift; } else { ntodo = nshift; /* point to original beginning of the block */ ptr = firstbyte; } ffmbyt(fptr, ptr, REPORT_EOF, status); while (ntodo) { ntomov = (long) (minvalue(ntodo, shftbuffsize)); ffpbyt(fptr, ntomov, buffer, status); ntodo -= ntomov; } return(*status); } indi-0.5/src/cfitsio/putcoluj.c0000644000175000017500000010271310610474375014364 0ustar jrjr/* This file, putcoluj.c, contains routines that write data elements to */ /* a FITS image or table, with unsigned long datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppruj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; unsigned long nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TULONG, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcluj(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnuj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values that are written */ unsigned long nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; unsigned long nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TULONG, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnuj(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2duj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3duj(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3duj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TULONG, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcluj(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcluj(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssuj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ unsigned long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TULONG, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcluj(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpuj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcluj(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcluj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONG): ffu4fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TLONGLONG): ffu4fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffu4fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffu4fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffu4fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffu4fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffu4fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpcluj).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnuj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned long *array, /* I - array of values to write */ unsigned long nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcluj(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcluj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcluj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fi1(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fi2(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fi4(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 2147483648. && sizeof(long) == 4) { /* Instead of subtracting 2147483648, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(long *) &input[ii] ) ^ 0x80000000; } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > INT32_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fi8(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fr4(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fr8(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffu4fstr(unsigned long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } indi-0.5/src/cfitsio/compress.h0000644000175000017500000001570410610474402014351 0ustar jrjr/* compress.h -- definitions for the decompression routines used in CFITSIO */ /* Blatantly copied and modified from the original gzip-1.2.4 source code. */ #include #include #include #include /* 'near' is only relevant for 16-bit PC with small memory model */ # define near #if defined(VAXC) || defined(VMS) # define RECORD_IO 1 #else # define RECORD_IO 0 #endif #define get_char() get_byte() /* gzip.h -- common declarations for all gzip modules */ #define OF(args) args typedef void *voidp; #define memzero(s, n) memset ((voidp)(s), 0, (n)) typedef unsigned char uch; typedef unsigned short ush; typedef unsigned long ulg; /* private version of MIN function */ #define MINZIP(a,b) ((a) <= (b) ? (a) : (b)) /* Return codes from gzip */ #define OK 0 #define ERROR 1 #define WARNING 2 /* Compression methods (see algorithm.doc) */ #define STORED 0 #define COMPRESSED 1 #define PACKED 2 #define LZHED 3 /* methods 4 to 7 reserved */ #define DEFLATED 8 #define MAX_METHODS 9 #define INBUFSIZ 0x8000 /* input buffer size */ #define INBUF_EXTRA 64 /* required by unlzw() */ #define OUTBUFSIZ 16384 /* output buffer size */ #define OUTBUF_EXTRA 2048 /* required by unlzw() */ #define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */ #define WSIZE 0x8000 /* window size--must be a power of two, and */ #define DECLARE(type, array, size) type array[size] #define tab_suffix window #define tab_prefix prev /* hash link (see deflate.c) */ #define head (prev+WSIZE) /* hash head (see deflate.c) */ #define PACK_MAGIC "\037\036" /* Magic header for packed files */ #define GZIP_MAGIC "\037\213" /* Magic header for gzip files, 1F 8B */ #define OLD_GZIP_MAGIC "\037\236" /* Magic header for gzip 0.5 = freeze 1.x */ #define LZH_MAGIC "\037\240" /* Magic header for SCO LZH Compress files*/ #define LZW_MAGIC "\037\235" /* Magic header for lzw files, 1F 9D */ #define PKZIP_MAGIC "\120\113\003\004" /* Magic header for pkzip files */ /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ #define RESERVED 0xC0 /* bit 6,7: reserved */ #define MIN_MATCH 3 #define MAX_MATCH 258 #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) #define MAX_DIST (WSIZE-MIN_LOOKAHEAD) #define translate_eol 0 /* no option -a yet */ #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(0)) #define try_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(1)) #define put_ubyte(c) {window[outcnt++]=(uch)(c); if (outcnt==WSIZE)\ flush_window();} /* Macros for getting two-byte and four-byte header values */ #define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)) #define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)) /* Diagnostic functions */ # define Assert(cond,msg) # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) /* lzw.h -- define the lzw functions. */ #ifndef BITS # define BITS 16 #endif #define INIT_BITS 9 /* Initial number of bits per code */ #define BIT_MASK 0x1f /* Mask for 'number of compression bits' */ #define BLOCK_MODE 0x80 #define LZW_RESERVED 0x60 /* reserved bits */ #define CLEAR 256 /* flush the dictionary */ #define FIRST (CLEAR+1) /* first free entry */ /* prototypes */ #define local static void ffpmsg(const char *err_message); local int get_method OF((FILE *in)); local ulg updcrc OF((uch *s, unsigned n)); local int fill_inbuf OF((int eof_ok)); local void flush_outbuf OF((void)); local void flush_window OF((void)); local void write_buf OF((voidp buf, unsigned cnt)); local void error OF((char *m)); local ulg flush_block OF((char *buf, ulg stored_len, int eof)); typedef int file_t; /* Do not use stdio */ #define NO_FILE (-1) /* in memory compression */ local int file_read OF((char *buf, unsigned size)); local void send_bits OF((int value, int length)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((void)); local void copy_block OF((char *buf, unsigned len, int header)); local int (*read_buf) OF((char *buf, unsigned size)); local void lm_init OF((int pack_level, ush *flags)); local ulg deflate OF((void)); local void ct_init OF((ush *attr, int *method)); local int ct_tally OF((int dist, int lc)); local void bi_init OF((file_t zipfile)); #define put_byte(c) {outbuf[outcnt++]=(uch)(c); if (outcnt==OUTBUFSIZ)\ flush_outbuf();} /* Output a 16 bit value, lsb first */ #define put_short(w) \ { if (outcnt < OUTBUFSIZ-2) { \ outbuf[outcnt++] = (uch) ((w) & 0xff); \ outbuf[outcnt++] = (uch) ((ush)(w) >> 8); \ } else { \ put_byte((uch)((w) & 0xff)); \ put_byte((uch)((ush)(w) >> 8)); \ } \ } /* Output a 32 bit value to the bit stream, lsb first */ #define put_long(n) { \ put_short((n) & 0xffff); \ put_short(((ulg)(n)) >> 16); \ } #define seekable() 0 /* force sequential output */ /* io.c */ local void fillbuf OF((int n)); local unsigned getbits OF((int n)); local void init_getbits OF((void)); /* maketbl.c */ local void make_table OF((int nchar, uch bitlen[], int tablebits, ush table[])); /* huf.c */ local void read_pt_len OF((int nn, int nbit, int i_special)); local void read_c_len OF((void)); local unsigned decode_c OF((void)); local unsigned decode_p OF((void)); local void huf_decode_start OF((void)); /* decode.c */ local void decode_start OF((void)); local unsigned decode OF((unsigned count, uch buffer[])); local int unlzh OF((FILE *in, FILE *out)); local int unlzw OF((FILE *in, FILE *out)); local void read_tree OF((void)); local void build_tree_unpack OF((void)); local int unpack OF((FILE *in, FILE *out)); local int check_zipfile OF((FILE *in)); local int unzip OF((FILE *in, FILE *out)); int (*work) OF((FILE *infile, FILE *outfile)) = unzip; /* function to call */ /* inflate.c */ struct huft { uch e; /* number of extra bits or operation */ uch b; /* number of bits in this code or subcode */ union { ush n; /* literal, length base, or distance base */ struct huft *t; /* pointer to next level of table */ } v; }; local int huft_build OF((unsigned *, unsigned, unsigned, ush *, ush *, struct huft **, int *)); local int huft_free OF((struct huft *)); local int inflate_codes OF((struct huft *, struct huft *, int, int)); local int inflate_stored OF((void)); local int inflate_fixed OF((void)); local int inflate_dynamic OF((void)); local int inflate_block OF((int *)); local int inflate OF((void)); /* end of compress.h include file */ indi-0.5/src/cfitsio/drvrsmem.h0000644000175000017500000001461010610474402014350 0ustar jrjr/* S H A R E D M E M O R Y D R I V E R ======================================= by Jerzy.Borkowski@obs.unige.ch 09-Mar-98 : initial version 1.0 released 23-Mar-98 : shared_malloc now accepts new handle as an argument */ #include /* this is necessary for Solaris/Linux */ #include #include #ifdef _AIX #include #else #include #endif /* configuration parameters */ #define SHARED_MAXSEG (16) /* maximum number of shared memory blocks */ #define SHARED_KEYBASE (14011963) /* base for shared memory keys, may be overriden by getenv */ #define SHARED_FDNAME ("/tmp/.shmem-lockfile") /* template for lock file name */ #define SHARED_ENV_KEYBASE ("SHMEM_LIB_KEYBASE") /* name of environment variable */ #define SHARED_ENV_MAXSEG ("SHMEM_LIB_MAXSEG") /* name of environment variable */ /* useful constants */ #define SHARED_RDONLY (0) /* flag for shared_(un)lock, lock for read */ #define SHARED_RDWRITE (1) /* flag for shared_(un)lock, lock for write */ #define SHARED_WAIT (0) /* flag for shared_lock, block if cannot lock immediate */ #define SHARED_NOWAIT (2) /* flag for shared_lock, fail if cannot lock immediate */ #define SHARED_NOLOCK (0x100) /* flag for shared_validate function */ #define SHARED_RESIZE (4) /* flag for shared_malloc, object is resizeable */ #define SHARED_PERSIST (8) /* flag for shared_malloc, object is not deleted after last proc detaches */ #define SHARED_INVALID (-1) /* invalid handle for semaphore/shared memory */ #define SHARED_EMPTY (0) /* entries for shared_used table */ #define SHARED_USED (1) #define SHARED_GRANUL (16384) /* granularity of shared_malloc allocation = phys page size, system dependent */ /* checkpoints in shared memory segments - might be omitted */ #define SHARED_ID_0 ('J') /* first byte of identifier in BLKHEAD */ #define SHARED_ID_1 ('B') /* second byte of identifier in BLKHEAD */ #define BLOCK_REG (0) /* value for tflag member of BLKHEAD */ #define BLOCK_SHARED (1) /* value for tflag member of BLKHEAD */ /* generic error codes */ #define SHARED_OK (0) #define SHARED_ERR_MIN_IDX SHARED_BADARG #define SHARED_ERR_MAX_IDX SHARED_NORESIZE #define DAL_SHM_FREE (0) #define DAL_SHM_USED (1) #define DAL_SHM_ID0 ('D') #define DAL_SHM_ID1 ('S') #define DAL_SHM_ID2 ('M') #define DAL_SHM_SEGHEAD_ID (0x19630114) /* data types */ /* BLKHEAD object is placed at the beginning of every memory segment (both shared and regular) to allow automatic recognition of segments type */ typedef union { struct BLKHEADstruct { char ID[2]; /* ID = 'JB', just as a checkpoint */ char tflag; /* is it shared memory or regular one ? */ int handle; /* this is not necessary, used only for non-resizeable objects via ptr */ } s; double d; /* for proper alignment on every machine */ } BLKHEAD; typedef void *SHARED_P; /* generic type of shared memory pointer */ typedef struct SHARED_GTABstruct /* data type used in global table */ { int sem; /* access semaphore (1 field): process count */ int semkey; /* key value used to generate semaphore handle */ int key; /* key value used to generate shared memory handle (realloc changes it) */ int handle; /* handle of shared memory segment */ int size; /* size of shared memory segment */ int nprocdebug; /* attached proc counter, helps remove zombie segments */ char attr; /* attributes of shared memory object */ } SHARED_GTAB; typedef struct SHARED_LTABstruct /* data type used in local table */ { BLKHEAD *p; /* pointer to segment (may be null) */ int tcnt; /* number of threads in this process attached to segment */ int lkcnt; /* >=0 <- number of read locks, -1 - write lock */ long seekpos; /* current pointer position, read/write/seek operations change it */ } SHARED_LTAB; /* system dependent definitions */ #ifndef HAVE_FLOCK_T typedef struct flock flock_t; #define HAVE_FLOCK_T #endif #ifndef HAVE_UNION_SEMUN union semun { int val; struct semid_ds *buf; unsigned short *array; }; #define HAVE_UNION_SEMUN #endif typedef struct DAL_SHM_SEGHEAD_STRUCT DAL_SHM_SEGHEAD; struct DAL_SHM_SEGHEAD_STRUCT { int ID; /* ID for debugging */ int h; /* handle of sh. mem */ int size; /* size of data area */ int nodeidx; /* offset of root object (node struct typically) */ }; /* API routines */ #ifdef __cplusplus extern "C" { #endif void shared_cleanup(void); /* must be called at exit/abort */ int shared_init(int debug_msgs); /* must be called before any other shared memory routine */ int shared_recover(int id); /* try to recover dormant segment(s) after applic crash */ int shared_malloc(long size, int mode, int newhandle); /* allocate n-bytes of shared memory */ int shared_attach(int idx); /* attach to segment given index to table */ int shared_free(int idx); /* release shared memory */ SHARED_P shared_lock(int idx, int mode); /* lock segment for reading */ SHARED_P shared_realloc(int idx, long newsize); /* reallocate n-bytes of shared memory (ON LOCKED SEGMENT ONLY) */ int shared_size(int idx); /* get size of attached shared memory segment (ON LOCKED SEGMENT ONLY) */ int shared_attr(int idx); /* get attributes of attached shared memory segment (ON LOCKED SEGMENT ONLY) */ int shared_set_attr(int idx, int newattr); /* set attributes of attached shared memory segment (ON LOCKED SEGMENT ONLY) */ int shared_unlock(int idx); /* unlock segment (ON LOCKED SEGMENT ONLY) */ int shared_set_debug(int debug_msgs); /* set/reset debug mode */ int shared_set_createmode(int mode); /* set/reset debug mode */ int shared_list(int id); /* list segment(s) */ int shared_uncond_delete(int id); /* uncondintionally delete (NOWAIT operation) segment(s) */ int shared_getaddr(int id, char **address); /* get starting address of FITS file in segment */ int smem_init(void); int smem_shutdown(void); int smem_setoptions(int options); int smem_getoptions(int *options); int smem_getversion(int *version); int smem_open(char *filename, int rwmode, int *driverhandle); int smem_create(char *filename, int *driverhandle); int smem_close(int driverhandle); int smem_remove(char *filename); int smem_size(int driverhandle, LONGLONG *size); int smem_flush(int driverhandle); int smem_seek(int driverhandle, LONGLONG offset); int smem_read(int driverhandle, void *buffer, long nbytes); int smem_write(int driverhandle, void *buffer, long nbytes); #ifdef __cplusplus } #endif indi-0.5/src/cfitsio/getcolj.c0000644000175000017500000043054410610474374014153 0ustar jrjr/* This file, getcolj.c, contains routines that read data elements from */ /* a FITS image or table, with long data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long nulval, /* I - value for undefined pixels */ long *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; long nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TLONG, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclj(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TLONG, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclj(fptr, 2, row, firstelem, nelem, 1, 2, 0L, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dj(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3], nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TLONG, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclj(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclj(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ long nulval, /* I - value to set undefined pixels */ long *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; long nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TLONG, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgclj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ long *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; long nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TLONG, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ long *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclj(fptr, 1, row, firstelem, nelem, 1, 1, 0L, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long nulval, /* I - value for null pixels */ long *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { long dummy = 0; ffgclj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ long nulval, /* I - value for null pixels if nultyp = 1 */ long *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if (ffgcprll(fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TLONG) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0. && LONGSIZE == 32) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) &array[next], status); if (convert) fffi4i4((INT32BIT *) &array[next], ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8i4((LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1i4((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2i4((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4i4((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8i4((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstri4((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgclj).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgclj).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1i4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (long) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2i4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (long) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4i4(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; Process the array of data in reverse order, to handle the case where the input data is 4-bytes and the output is 8-bytes and the conversion is being done in place in the same array. */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = ntodo - 1; ii >= 0; ii--) output[ii] = (long) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = ntodo - 1; ii >= 0; ii--) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = ntodo - 1; ii >= 0; ii--) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = ntodo - 1; ii >= 0; ii--) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8i4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < LONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > LONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < LONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > LONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4i4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (zero > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8i4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (input[ii] > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (zero > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstri4(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ long nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ long *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONG_MIN; } else if (dvalue > DLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONG_MAX; } else output[ii] = (long) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } /* ======================================================================== */ /* the following routines support the 'long long' data type */ /* ======================================================================== */ /*--------------------------------------------------------------------------*/ int ffgpvjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ LONGLONG nulval, /* I - value for undefined pixels */ LONGLONG *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; LONGLONG nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TLONGLONG, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcljj(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ LONGLONG *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; LONGLONG dummy = 0; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TLONGLONG, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcljj(fptr, 2, row, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2djj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG nulval ,/* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG *array,/* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3djj(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3djj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ LONGLONG *array,/* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; LONGLONG nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TLONGLONG, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcljj(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcljj(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ LONGLONG nulval,/* I - value to set undefined pixels */ LONGLONG *array,/* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; LONGLONG nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TLONGLONG, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgcljj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ LONGLONG *array,/* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; LONGLONG nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TLONGLONG, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcljj(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ LONGLONG *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; LONGLONG dummy = 0; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcljj(fptr, 1, row, firstelem, nelem, 1, 1, dummy, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ LONGLONG nulval, /* I - value for null pixels */ LONGLONG *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ LONGLONG *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { LONGLONG dummy = 0; ffgcljj(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcljj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ LONGLONG nulval, /* I - value for null pixels if nultyp = 1 */ LONGLONG *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if (ffgcprll(fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TLONGLONG) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) &array[next], status); if (convert) fffi8i8((LONGLONG *) &array[next], ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4i8((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1i8((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2i8((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4i8((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8i8((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstri8((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgclj).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgclj).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1i8(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (LONGLONG) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2i8(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (LONGLONG) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4i8(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (LONGLONG) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8i8(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4i8(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (zero > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8i8(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (input[ii] > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (zero > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstri8(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ LONGLONG nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ LONGLONG *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else output[ii] = (LONGLONG) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } indi-0.5/src/cfitsio/scalnull.c0000644000175000017500000002721510610474375014337 0ustar jrjr/* Copyright (Unpublished-all rights reserved under the copyright laws of the United States), U.S. Government as represented by the Administrator of the National Aeronautics and Space Administration. No copyright is claimed in the United States under Title 17, U.S. Code. Permission to freely use, copy, modify, and distribute this software and its documentation without fee is hereby granted, provided that this copyright notice and disclaimer of warranty appears in all copies. (However, see the restriction on the use of the gzip compression code, below). e-mail: pence@tetra.gsfc.nasa.gov DISCLAIMER: THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NASA BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT , OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER." The file compress.c contains (slightly modified) source code that originally came from gzip-1.2.4, copyright (C) 1992-1993 by Jean-loup Gailly. This gzip code is distributed under the GNU General Public License and thus requires that any software that uses the CFITSIO library (which in turn uses the gzip code) must conform to the provisions in the GNU General Public License. A copy of the GNU license is included at the beginning of compress.c file. Similarly, the file wcsutil.c contains 2 slightly modified routines from the Classic AIPS package that are also distributed under the GNU General Public License. Alternate versions of the compress.c and wcsutil.c files (called compress_alternate.c and wcsutil_alternate.c) are provided for users who want to use the CFITSIO library but are unwilling or unable to publicly release their software under the terms of the GNU General Public License. These alternate versions contains non-functional stubs for the file compression and uncompression routines and the world coordinate transformation routines used by CFITSIO. Replace the file `compress.c' with `compress_alternate.c' and 'wcsutil.c' with 'wcsutil_alternate.c before compiling the CFITSIO library. This will produce a version of CFITSIO which does not support reading or writing compressed FITS files, or doing image coordinate transformations, but is otherwise identical to the standard version. */ /* This file, scalnull.c, contains the FITSIO routines used to define */ /* the starting heap address, the value scaling and the null values. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpthp(fitsfile *fptr, /* I - FITS file pointer */ long theap, /* I - starting addrss for the heap */ int *status) /* IO - error status */ /* Define the starting address for the heap for a binary table. The default address is NAXIS1 * NAXIS2. It is in units of bytes relative to the beginning of the regular binary table data. This routine also writes the appropriate THEAP keyword to the FITS header. */ { if (*status > 0 || theap < 1) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->heapstart = theap; ffukyj(fptr, "THEAP", theap, "byte offset to heap area", status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpscl(fitsfile *fptr, /* I - FITS file pointer */ double scale, /* I - scaling factor: value of BSCALE */ double zero, /* I - zero point: value of BZERO */ int *status) /* IO - error status */ /* Define the linear scaling factor for the primary array or image extension pixel values. This routine overrides the scaling values given by the BSCALE and BZERO keywords if present. Note that this routine does not write or modify the BSCALE and BZERO keywords, but instead only modifies the values temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the scaling back to the BSCALE and BZERO keyword values (or 1. and 0. respectively if the keywords are not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (scale == 0) return(*status = ZERO_SCALE); /* zero scale value is illegal */ if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype != IMAGE_HDU) return(*status = NOT_IMAGE); /* not proper HDU type */ if (fits_is_compressed_image(fptr, status)) /* compressed images */ { (fptr->Fptr)->cn_bscale = scale; (fptr->Fptr)->cn_bzero = zero; return(*status); } /* set pointer to the first 'column' (contains group parameters if any) */ colptr = (fptr->Fptr)->tableptr; colptr++; /* increment to the 2nd 'column' pointer (the image itself) */ colptr->tscale = scale; colptr->tzero = zero; return(*status); } /*--------------------------------------------------------------------------*/ int ffpnul(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG nulvalue, /* I - null pixel value: value of BLANK */ int *status) /* IO - error status */ /* Define the value used to represent undefined pixels in the primary array or image extension. This only applies to integer image pixel (i.e. BITPIX > 0). This routine overrides the null pixel value given by the BLANK keyword if present. Note that this routine does not write or modify the BLANK keyword, but instead only modifies the value temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the null value back to the BLANK keyword value (or not defined if the keyword is not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype != IMAGE_HDU) return(*status = NOT_IMAGE); /* not proper HDU type */ if (fits_is_compressed_image(fptr, status)) /* ignore compressed images */ return(*status); /* set pointer to the first 'column' (contains group parameters if any) */ colptr = (fptr->Fptr)->tableptr; colptr++; /* increment to the 2nd 'column' pointer (the image itself) */ colptr->tnull = nulvalue; return(*status); } /*--------------------------------------------------------------------------*/ int fftscl(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number to apply scaling to */ double scale, /* I - scaling factor: value of TSCALn */ double zero, /* I - zero point: value of TZEROn */ int *status) /* IO - error status */ /* Define the linear scaling factor for the TABLE or BINTABLE extension column values. This routine overrides the scaling values given by the TSCALn and TZEROn keywords if present. Note that this routine does not write or modify the TSCALn and TZEROn keywords, but instead only modifies the values temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the scaling back to the TSCALn and TZEROn keyword values (or 1. and 0. respectively if the keywords are not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (scale == 0) return(*status = ZERO_SCALE); /* zero scale value is illegal */ if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype == IMAGE_HDU) return(*status = NOT_TABLE); /* not proper HDU type */ colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ colptr->tscale = scale; colptr->tzero = zero; return(*status); } /*--------------------------------------------------------------------------*/ int fftnul(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number to apply nulvalue to */ LONGLONG nulvalue, /* I - null pixel value: value of TNULLn */ int *status) /* IO - error status */ /* Define the value used to represent undefined pixels in the BINTABLE column. This only applies to integer datatype columns (TFORM = B, I, or J). This routine overrides the null pixel value given by the TNULLn keyword if present. Note that this routine does not write or modify the TNULLn keyword, but instead only modifies the value temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the null value back to the TNULLn keyword value (or not defined if the keyword is not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype != BINARY_TBL) return(*status = NOT_BTABLE); /* not proper HDU type */ colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ colptr->tnull = nulvalue; return(*status); } /*--------------------------------------------------------------------------*/ int ffsnul(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number to apply nulvalue to */ char *nulstring, /* I - null pixel value: value of TNULLn */ int *status) /* IO - error status */ /* Define the string used to represent undefined pixels in the ASCII TABLE column. This routine overrides the null value given by the TNULLn keyword if present. Note that this routine does not write or modify the TNULLn keyword, but instead only modifies the value temporarily in the internal buffer. Thus, a subsequent call to the ffrdef routine will reset the null value back to the TNULLn keyword value (or not defined if the keyword is not present). */ { tcolumn *colptr; int hdutype; if (*status > 0) return(*status); if (ffghdt(fptr, &hdutype, status) > 0) /* get HDU type */ return(*status); if (hdutype != ASCII_TBL) return(*status = NOT_ATABLE); /* not proper HDU type */ colptr = (fptr->Fptr)->tableptr; /* set pointer to the first column */ colptr += (colnum - 1); /* increment to the correct column */ colptr->strnull[0] = '\0'; strncat(colptr->strnull, nulstring, 19); /* limit string to 19 chars */ return(*status); } indi-0.5/src/cfitsio/eval.y0000644000175000017500000051255010605175703013475 0ustar jrjr%{ /************************************************************************/ /* */ /* CFITSIO Lexical Parser */ /* */ /* This file is one of 3 files containing code which parses an */ /* arithmetic expression and evaluates it in the context of an input */ /* FITS file table extension. The CFITSIO lexical parser is divided */ /* into the following 3 parts/files: the CFITSIO "front-end", */ /* eval_f.c, contains the interface between the user/CFITSIO and the */ /* real core of the parser; the FLEX interpreter, eval_l.c, takes the */ /* input string and parses it into tokens and identifies the FITS */ /* information required to evaluate the expression (ie, keywords and */ /* columns); and, the BISON grammar and evaluation routines, eval_y.c, */ /* receives the FLEX output and determines and performs the actual */ /* operations. The files eval_l.c and eval_y.c are produced from */ /* running flex and bison on the files eval.l and eval.y, respectively. */ /* (flex and bison are available from any GNU archive: see www.gnu.org) */ /* */ /* The grammar rules, rather than evaluating the expression in situ, */ /* builds a tree, or Nodal, structure mapping out the order of */ /* operations and expression dependencies. This "compilation" process */ /* allows for much faster processing of multiple rows. This technique */ /* was developed by Uwe Lammers of the XMM Science Analysis System, */ /* although the CFITSIO implementation is entirely code original. */ /* */ /* */ /* Modification History: */ /* */ /* Kent Blackburn c1992 Original parser code developed for the */ /* FTOOLS software package, in particular, */ /* the fselect task. */ /* Kent Blackburn c1995 BIT column support added */ /* Peter D Wilson Feb 1998 Vector column support added */ /* Peter D Wilson May 1998 Ported to CFITSIO library. User */ /* interface routines written, in essence */ /* making fselect, fcalc, and maketime */ /* capabilities available to all tools */ /* via single function calls. */ /* Peter D Wilson Jun 1998 Major rewrite of parser core, so as to */ /* create a run-time evaluation tree, */ /* inspired by the work of Uwe Lammers, */ /* resulting in a speed increase of */ /* 10-100 times. */ /* Peter D Wilson Jul 1998 gtifilter(a,b,c,d) function added */ /* Peter D Wilson Aug 1998 regfilter(a,b,c,d) function added */ /* Peter D Wilson Jul 1999 Make parser fitsfile-independent, */ /* allowing a purely vector-based usage */ /* Craig B Markwardt Jun 2004 Add MEDIAN() function */ /* Craig B Markwardt Jun 2004 Add SUM(), and MIN/MAX() for bit arrays */ /* Craig B Markwardt Jun 2004 Allow subscripting of nX bit arrays */ /* Craig B Markwardt Jun 2004 Implement statistical functions */ /* NVALID(), AVERAGE(), and STDDEV() */ /* for integer and floating point vectors */ /* Craig B Markwardt Jun 2004 Use NULL values for range errors instead*/ /* of throwing a parse error */ /* Craig B Markwardt Oct 2004 Add ACCUM() and SEQDIFF() functions */ /* Craig B Markwardt Feb 2005 Add ANGSEP() function */ /* Craig B Markwardt Aug 2005 CIRCLE, BOX, ELLIPSE, NEAR and REGFILTER*/ /* functions now accept vector arguments */ /* */ /************************************************************************/ #define APPROX 1.0e-7 #include "eval_defs.h" #include "region.h" #include #include #ifndef alloca #define alloca malloc #endif /* Shrink the initial stack depth to keep local data <32K (mac limit) */ /* yacc will allocate more space if needed, though. */ #define YYINITDEPTH 100 /***************************************************************/ /* Replace Bison's BACKUP macro with one that fixes a bug -- */ /* must update state after popping the stack -- and allows */ /* popping multiple terms at one time. */ /***************************************************************/ #define YYNEWBACKUP(token, value) \ do \ if (yychar == YYEMPTY ) \ { yychar = (token); \ memcpy( &yylval, &(value), sizeof(value) ); \ yychar1 = YYTRANSLATE (yychar); \ while (yylen--) YYPOPSTACK; \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { yyerror ("syntax error: cannot back up"); YYERROR; } \ while (0) /***************************************************************/ /* Useful macros for accessing/testing Nodes */ /***************************************************************/ #define TEST(a) if( (a)<0 ) YYERROR #define SIZE(a) gParse.Nodes[ a ].value.nelem #define TYPE(a) gParse.Nodes[ a ].type #define PROMOTE(a,b) if( TYPE(a) > TYPE(b) ) \ b = New_Unary( TYPE(a), 0, b ); \ else if( TYPE(a) < TYPE(b) ) \ a = New_Unary( TYPE(b), 0, a ); /***** Internal functions *****/ #ifdef __cplusplus extern "C" { #endif static int Alloc_Node ( void ); static void Free_Last_Node( void ); static void Evaluate_Node ( int thisNode ); static int New_Const ( int returnType, void *value, long len ); static int New_Column( int ColNum ); static int New_Offset( int ColNum, int offset ); static int New_Unary ( int returnType, int Op, int Node1 ); static int New_BinOp ( int returnType, int Node1, int Op, int Node2 ); static int New_Func ( int returnType, funcOp Op, int nNodes, int Node1, int Node2, int Node3, int Node4, int Node5, int Node6, int Node7 ); static int New_Deref ( int Var, int nDim, int Dim1, int Dim2, int Dim3, int Dim4, int Dim5 ); static int New_GTI ( char *fname, int Node1, char *start, char *stop ); static int New_REG ( char *fname, int NodeX, int NodeY, char *colNames ); static int New_Vector( int subNode ); static int Close_Vec ( int vecNode ); static int Locate_Col( Node *this ); static int Test_Dims ( int Node1, int Node2 ); static void Copy_Dims ( int Node1, int Node2 ); static void Allocate_Ptrs( Node *this ); static void Do_Unary ( Node *this ); static void Do_Offset ( Node *this ); static void Do_BinOp_bit ( Node *this ); static void Do_BinOp_str ( Node *this ); static void Do_BinOp_log ( Node *this ); static void Do_BinOp_lng ( Node *this ); static void Do_BinOp_dbl ( Node *this ); static void Do_Func ( Node *this ); static void Do_Deref ( Node *this ); static void Do_GTI ( Node *this ); static void Do_REG ( Node *this ); static void Do_Vector ( Node *this ); static long Search_GTI ( double evtTime, long nGTI, double *start, double *stop, int ordered ); static char saobox (double xcen, double ycen, double xwid, double ywid, double rot, double xcol, double ycol); static char ellipse(double xcen, double ycen, double xrad, double yrad, double rot, double xcol, double ycol); static char circle (double xcen, double ycen, double rad, double xcol, double ycol); static char bnear (double x, double y, double tolerance); static char bitcmp (char *bitstrm1, char *bitstrm2); static char bitlgte(char *bits1, int oper, char *bits2); static void bitand(char *result, char *bitstrm1, char *bitstrm2); static void bitor (char *result, char *bitstrm1, char *bitstrm2); static void bitnot(char *result, char *bits); static void yyerror(char *msg); #ifdef __cplusplus } #endif %} %union { int Node; /* Index of Node */ double dbl; /* real value */ long lng; /* integer value */ char log; /* logical value */ char str[256]; /* string value */ } %token BOOLEAN /* First 3 must be in order of */ %token LONG /* increasing promotion for later use */ %token DOUBLE %token STRING %token BITSTR %token FUNCTION %token BFUNCTION %token GTIFILTER %token REGFILTER %token COLUMN %token BCOLUMN %token SCOLUMN %token BITCOL %token ROWREF %token NULLREF %token SNULLREF %type expr %type bexpr %type sexpr %type bits %type vector %type bvector %left ',' '=' ':' '{' '}' %right '?' %left OR %left AND %left EQ NE '~' %left GT LT LTE GTE %left '+' '-' '%' %left '*' '/' %left '|' '&' %right POWER %left NOT %left INTCAST FLTCAST %left UMINUS %left '[' %right ACCUM DIFF %% lines: /* nothing ; was | lines line */ | lines line ; line: '\n' {} | expr '\n' { if( $1<0 ) { yyerror("Couldn't build node structure: out of memory?"); YYERROR; } gParse.resultNode = $1; } | bexpr '\n' { if( $1<0 ) { yyerror("Couldn't build node structure: out of memory?"); YYERROR; } gParse.resultNode = $1; } | sexpr '\n' { if( $1<0 ) { yyerror("Couldn't build node structure: out of memory?"); YYERROR; } gParse.resultNode = $1; } | bits '\n' { if( $1<0 ) { yyerror("Couldn't build node structure: out of memory?"); YYERROR; } gParse.resultNode = $1; } | error '\n' { yyerrok; } ; bvector: '{' bexpr { $$ = New_Vector( $2 ); TEST($$); } | bvector ',' bexpr { if( gParse.Nodes[$1].nSubNodes >= MAXSUBS ) { $1 = Close_Vec( $1 ); TEST($1); $$ = New_Vector( $1 ); TEST($$); } else { $$ = $1; } gParse.Nodes[$$].SubNodes[ gParse.Nodes[$$].nSubNodes++ ] = $3; } ; vector: '{' expr { $$ = New_Vector( $2 ); TEST($$); } | vector ',' expr { if( TYPE($1) < TYPE($3) ) TYPE($1) = TYPE($3); if( gParse.Nodes[$1].nSubNodes >= MAXSUBS ) { $1 = Close_Vec( $1 ); TEST($1); $$ = New_Vector( $1 ); TEST($$); } else { $$ = $1; } gParse.Nodes[$$].SubNodes[ gParse.Nodes[$$].nSubNodes++ ] = $3; } | vector ',' bexpr { if( gParse.Nodes[$1].nSubNodes >= MAXSUBS ) { $1 = Close_Vec( $1 ); TEST($1); $$ = New_Vector( $1 ); TEST($$); } else { $$ = $1; } gParse.Nodes[$$].SubNodes[ gParse.Nodes[$$].nSubNodes++ ] = $3; } | bvector ',' expr { TYPE($1) = TYPE($3); if( gParse.Nodes[$1].nSubNodes >= MAXSUBS ) { $1 = Close_Vec( $1 ); TEST($1); $$ = New_Vector( $1 ); TEST($$); } else { $$ = $1; } gParse.Nodes[$$].SubNodes[ gParse.Nodes[$$].nSubNodes++ ] = $3; } ; expr: vector '}' { $$ = Close_Vec( $1 ); TEST($$); } ; bexpr: bvector '}' { $$ = Close_Vec( $1 ); TEST($$); } ; bits: BITSTR { $$ = New_Const( BITSTR, $1, strlen($1)+1 ); TEST($$); SIZE($$) = strlen($1); } | BITCOL { $$ = New_Column( $1 ); TEST($$); } | BITCOL '{' expr '}' { if( TYPE($3) != LONG || gParse.Nodes[$3].operation != CONST_OP ) { yyerror("Offset argument must be a constant integer"); YYERROR; } $$ = New_Offset( $1, $3 ); TEST($$); } | bits '&' bits { $$ = New_BinOp( BITSTR, $1, '&', $3 ); TEST($$); SIZE($$) = ( SIZE($1)>SIZE($3) ? SIZE($1) : SIZE($3) ); } | bits '|' bits { $$ = New_BinOp( BITSTR, $1, '|', $3 ); TEST($$); SIZE($$) = ( SIZE($1)>SIZE($3) ? SIZE($1) : SIZE($3) ); } | bits '+' bits { $$ = New_BinOp( BITSTR, $1, '+', $3 ); TEST($$); SIZE($$) = SIZE($1) + SIZE($3); } | bits '[' expr ']' { $$ = New_Deref( $1, 1, $3, 0, 0, 0, 0 ); TEST($$); } | bits '[' expr ',' expr ']' { $$ = New_Deref( $1, 2, $3, $5, 0, 0, 0 ); TEST($$); } | bits '[' expr ',' expr ',' expr ']' { $$ = New_Deref( $1, 3, $3, $5, $7, 0, 0 ); TEST($$); } | bits '[' expr ',' expr ',' expr ',' expr ']' { $$ = New_Deref( $1, 4, $3, $5, $7, $9, 0 ); TEST($$); } | bits '[' expr ',' expr ',' expr ',' expr ',' expr ']' { $$ = New_Deref( $1, 5, $3, $5, $7, $9, $11 ); TEST($$); } | NOT bits { $$ = New_Unary( BITSTR, NOT, $2 ); TEST($$); } | '(' bits ')' { $$ = $2; } ; expr: LONG { $$ = New_Const( LONG, &($1), sizeof(long) ); TEST($$); } | DOUBLE { $$ = New_Const( DOUBLE, &($1), sizeof(double) ); TEST($$); } | COLUMN { $$ = New_Column( $1 ); TEST($$); } | COLUMN '{' expr '}' { if( TYPE($3) != LONG || gParse.Nodes[$3].operation != CONST_OP ) { yyerror("Offset argument must be a constant integer"); YYERROR; } $$ = New_Offset( $1, $3 ); TEST($$); } | ROWREF { $$ = New_Func( LONG, row_fct, 0, 0, 0, 0, 0, 0, 0, 0 ); } | NULLREF { $$ = New_Func( LONG, null_fct, 0, 0, 0, 0, 0, 0, 0, 0 ); } | expr '%' expr { PROMOTE($1,$3); $$ = New_BinOp( TYPE($1), $1, '%', $3 ); TEST($$); } | expr '+' expr { PROMOTE($1,$3); $$ = New_BinOp( TYPE($1), $1, '+', $3 ); TEST($$); } | expr '-' expr { PROMOTE($1,$3); $$ = New_BinOp( TYPE($1), $1, '-', $3 ); TEST($$); } | expr '*' expr { PROMOTE($1,$3); $$ = New_BinOp( TYPE($1), $1, '*', $3 ); TEST($$); } | expr '/' expr { PROMOTE($1,$3); $$ = New_BinOp( TYPE($1), $1, '/', $3 ); TEST($$); } | expr POWER expr { PROMOTE($1,$3); $$ = New_BinOp( TYPE($1), $1, POWER, $3 ); TEST($$); } | '+' expr %prec UMINUS { $$ = $2; } | '-' expr %prec UMINUS { $$ = New_Unary( TYPE($2), UMINUS, $2 ); TEST($$); } | '(' expr ')' { $$ = $2; } | expr '*' bexpr { $3 = New_Unary( TYPE($1), 0, $3 ); $$ = New_BinOp( TYPE($1), $1, '*', $3 ); TEST($$); } | bexpr '*' expr { $1 = New_Unary( TYPE($3), 0, $1 ); $$ = New_BinOp( TYPE($3), $1, '*', $3 ); TEST($$); } | bexpr '?' expr ':' expr { PROMOTE($3,$5); if( ! Test_Dims($3,$5) ) { yyerror("Incompatible dimensions in '?:' arguments"); YYERROR; } $$ = New_Func( 0, ifthenelse_fct, 3, $3, $5, $1, 0, 0, 0, 0 ); TEST($$); if( SIZE($3)=SIZE($4) && Test_Dims( $2, $4 ) ) { PROMOTE($2,$4); $$ = New_Func( 0, defnull_fct, 2, $2, $4, 0, 0, 0, 0, 0 ); TEST($$); } else { yyerror("Dimensions of DEFNULL arguments " "are not compatible"); YYERROR; } } else if (FSTRCMP($1,"ARCTAN2(") == 0) { if( TYPE($2) != DOUBLE ) $2 = New_Unary( DOUBLE, 0, $2 ); if( TYPE($4) != DOUBLE ) $4 = New_Unary( DOUBLE, 0, $4 ); if( Test_Dims( $2, $4 ) ) { $$ = New_Func( 0, atan2_fct, 2, $2, $4, 0, 0, 0, 0, 0 ); TEST($$); if( SIZE($2)=SIZE($4) && Test_Dims( $2, $4 ) ) { $$ = New_Func( 0, defnull_fct, 2, $2, $4, 0, 0, 0, 0, 0 ); TEST($$); } else { yyerror("Dimensions of DEFNULL arguments are not compatible"); YYERROR; } } else { yyerror("Boolean Function(expr,expr) not supported"); YYERROR; } } | BFUNCTION expr ',' expr ',' expr ')' { if( TYPE($2) != DOUBLE ) $2 = New_Unary( DOUBLE, 0, $2 ); if( TYPE($4) != DOUBLE ) $4 = New_Unary( DOUBLE, 0, $4 ); if( TYPE($6) != DOUBLE ) $6 = New_Unary( DOUBLE, 0, $6 ); if( ! (Test_Dims( $2, $4 ) && Test_Dims( $4, $6 ) ) ) { yyerror("Dimensions of NEAR arguments " "are not compatible"); YYERROR; } else { if (FSTRCMP($1,"NEAR(") == 0) { $$ = New_Func( BOOLEAN, near_fct, 3, $2, $4, $6, 0, 0, 0, 0 ); } else { yyerror("Boolean Function not supported"); YYERROR; } TEST($$); if( SIZE($$)SIZE($2) ) SIZE($$) = SIZE($4); } } ; %% /*************************************************************************/ /* Start of "New" routines which build the expression Nodal structure */ /*************************************************************************/ static int Alloc_Node( void ) { /* Use this for allocation to guarantee *Nodes */ Node *newNodePtr; /* survives on failure, making it still valid */ /* while working our way out of this error */ if( gParse.nNodes == gParse.nNodesAlloc ) { if( gParse.Nodes ) { gParse.nNodesAlloc += gParse.nNodesAlloc; newNodePtr = (Node *)realloc( gParse.Nodes, sizeof(Node)*gParse.nNodesAlloc ); } else { gParse.nNodesAlloc = 100; newNodePtr = (Node *)malloc ( sizeof(Node)*gParse.nNodesAlloc ); } if( newNodePtr ) { gParse.Nodes = newNodePtr; } else { gParse.status = MEMORY_ALLOCATION; return( -1 ); } } return ( gParse.nNodes++ ); } static void Free_Last_Node( void ) { if( gParse.nNodes ) gParse.nNodes--; } static int New_Const( int returnType, void *value, long len ) { Node *this; int n; n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = CONST_OP; /* Flag a constant */ this->DoOp = NULL; this->nSubNodes = 0; this->type = returnType; memcpy( &(this->value.data), value, len ); this->value.undef = NULL; this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } return(n); } static int New_Column( int ColNum ) { Node *this; int n, i; n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = -ColNum; this->DoOp = NULL; this->nSubNodes = 0; this->type = gParse.varData[ColNum].type; this->value.nelem = gParse.varData[ColNum].nelem; this->value.naxis = gParse.varData[ColNum].naxis; for( i=0; ivalue.naxes[i] = gParse.varData[ColNum].naxes[i]; } return(n); } static int New_Offset( int ColNum, int offsetNode ) { Node *this; int n, i, colNode; colNode = New_Column( ColNum ); if( colNode<0 ) return(-1); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = '{'; this->DoOp = Do_Offset; this->nSubNodes = 2; this->SubNodes[0] = colNode; this->SubNodes[1] = offsetNode; this->type = gParse.varData[ColNum].type; this->value.nelem = gParse.varData[ColNum].nelem; this->value.naxis = gParse.varData[ColNum].naxis; for( i=0; ivalue.naxes[i] = gParse.varData[ColNum].naxes[i]; } return(n); } static int New_Unary( int returnType, int Op, int Node1 ) { Node *this, *that; int i,n; if( Node1<0 ) return(-1); that = gParse.Nodes + Node1; if( !Op ) Op = returnType; if( (Op==DOUBLE || Op==FLTCAST) && that->type==DOUBLE ) return( Node1 ); if( (Op==LONG || Op==INTCAST) && that->type==LONG ) return( Node1 ); if( (Op==BOOLEAN ) && that->type==BOOLEAN ) return( Node1 ); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = Op; this->DoOp = Do_Unary; this->nSubNodes = 1; this->SubNodes[0] = Node1; this->type = returnType; that = gParse.Nodes + Node1; /* Reset in case .Nodes mv'd */ this->value.nelem = that->value.nelem; this->value.naxis = that->value.naxis; for( i=0; ivalue.naxis; i++ ) this->value.naxes[i] = that->value.naxes[i]; if( that->operation==CONST_OP ) this->DoOp( this ); } return( n ); } static int New_BinOp( int returnType, int Node1, int Op, int Node2 ) { Node *this,*that1,*that2; int n,i,constant; if( Node1<0 || Node2<0 ) return(-1); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = Op; this->nSubNodes = 2; this->SubNodes[0]= Node1; this->SubNodes[1]= Node2; this->type = returnType; that1 = gParse.Nodes + Node1; that2 = gParse.Nodes + Node2; constant = (that1->operation==CONST_OP && that2->operation==CONST_OP); if( that1->type!=STRING && that1->type!=BITSTR ) if( !Test_Dims( Node1, Node2 ) ) { Free_Last_Node(); yyerror("Array sizes/dims do not match for binary operator"); return(-1); } if( that1->value.nelem == 1 ) that1 = that2; this->value.nelem = that1->value.nelem; this->value.naxis = that1->value.naxis; for( i=0; ivalue.naxis; i++ ) this->value.naxes[i] = that1->value.naxes[i]; if ( Op == ACCUM && that1->type == BITSTR ) { /* ACCUM is rank-reducing on bit strings */ this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } /* Both subnodes should be of same time */ switch( that1->type ) { case BITSTR: this->DoOp = Do_BinOp_bit; break; case STRING: this->DoOp = Do_BinOp_str; break; case BOOLEAN: this->DoOp = Do_BinOp_log; break; case LONG: this->DoOp = Do_BinOp_lng; break; case DOUBLE: this->DoOp = Do_BinOp_dbl; break; } if( constant ) this->DoOp( this ); } return( n ); } static int New_Func( int returnType, funcOp Op, int nNodes, int Node1, int Node2, int Node3, int Node4, int Node5, int Node6, int Node7 ) /* If returnType==0 , use Node1's type and vector sizes as returnType, */ /* else return a single value of type returnType */ { Node *this, *that; int i,n,constant; if( Node1<0 || Node2<0 || Node3<0 || Node4<0 || Node5<0 || Node6<0 || Node7<0 ) return(-1); n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->operation = (int)Op; this->DoOp = Do_Func; this->nSubNodes = nNodes; this->SubNodes[0] = Node1; this->SubNodes[1] = Node2; this->SubNodes[2] = Node3; this->SubNodes[3] = Node4; this->SubNodes[4] = Node5; this->SubNodes[5] = Node6; this->SubNodes[6] = Node7; i = constant = nNodes; /* Functions with zero params are not const */ if (Op == poirnd_fct) constant = 0; /* Nor is Poisson deviate */ while( i-- ) constant = ( constant && gParse.Nodes[ this->SubNodes[i] ].operation==CONST_OP ); if( returnType ) { this->type = returnType; this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } else { that = gParse.Nodes + Node1; this->type = that->type; this->value.nelem = that->value.nelem; this->value.naxis = that->value.naxis; for( i=0; ivalue.naxis; i++ ) this->value.naxes[i] = that->value.naxes[i]; } if( constant ) this->DoOp( this ); } return( n ); } static int New_Deref( int Var, int nDim, int Dim1, int Dim2, int Dim3, int Dim4, int Dim5 ) { int n, idx, constant; long elem=0; Node *this, *theVar, *theDim[MAXDIMS]; if( Var<0 || Dim1<0 || Dim2<0 || Dim3<0 || Dim4<0 || Dim5<0 ) return(-1); theVar = gParse.Nodes + Var; if( theVar->operation==CONST_OP || theVar->value.nelem==1 ) { yyerror("Cannot index a scalar value"); return(-1); } n = Alloc_Node(); if( n>=0 ) { this = gParse.Nodes + n; this->nSubNodes = nDim+1; theVar = gParse.Nodes + (this->SubNodes[0]=Var); theDim[0] = gParse.Nodes + (this->SubNodes[1]=Dim1); theDim[1] = gParse.Nodes + (this->SubNodes[2]=Dim2); theDim[2] = gParse.Nodes + (this->SubNodes[3]=Dim3); theDim[3] = gParse.Nodes + (this->SubNodes[4]=Dim4); theDim[4] = gParse.Nodes + (this->SubNodes[5]=Dim5); constant = theVar->operation==CONST_OP; for( idx=0; idxoperation==CONST_OP); for( idx=0; idxvalue.nelem>1 ) { Free_Last_Node(); yyerror("Cannot use an array as an index value"); return(-1); } else if( theDim[idx]->type!=LONG ) { Free_Last_Node(); yyerror("Index value must be an integer type"); return(-1); } this->operation = '['; this->DoOp = Do_Deref; this->type = theVar->type; if( theVar->value.naxis == nDim ) { /* All dimensions specified */ this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; } else if( nDim==1 ) { /* Dereference only one dimension */ elem=1; this->value.naxis = theVar->value.naxis-1; for( idx=0; idxvalue.naxis; idx++ ) { elem *= ( this->value.naxes[idx] = theVar->value.naxes[idx] ); } this->value.nelem = elem; } else { Free_Last_Node(); yyerror("Must specify just one or all indices for vector"); return(-1); } if( constant ) this->DoOp( this ); } return(n); } extern int yyGetVariable( char *varName, YYSTYPE *varVal ); static int New_GTI( char *fname, int Node1, char *start, char *stop ) { fitsfile *fptr; Node *this, *that0, *that1; int type,i,n, startCol, stopCol, Node0; int hdutype, hdunum, evthdu, samefile, extvers, movetotype, tstat; char extname[100]; long nrows; double timeZeroI[2], timeZeroF[2], dt, timeSpan; char xcol[20], xexpr[20]; YYSTYPE colVal; if( Node1==-99 ) { type = yyGetVariable( "TIME", &colVal ); if( type==COLUMN ) { Node1 = New_Column( (int)colVal.lng ); } else { yyerror("Could not build TIME column for GTIFILTER"); return(-1); } } Node1 = New_Unary( DOUBLE, 0, Node1 ); Node0 = Alloc_Node(); /* This will hold the START/STOP times */ if( Node1<0 || Node0<0 ) return(-1); /* Record current HDU number in case we need to move within this file */ fptr = gParse.def_fptr; ffghdn( fptr, &evthdu ); /* Look for TIMEZERO keywords in current extension */ tstat = 0; if( ffgkyd( fptr, "TIMEZERO", timeZeroI, NULL, &tstat ) ) { tstat = 0; if( ffgkyd( fptr, "TIMEZERI", timeZeroI, NULL, &tstat ) ) { timeZeroI[0] = timeZeroF[0] = 0.0; } else if( ffgkyd( fptr, "TIMEZERF", timeZeroF, NULL, &tstat ) ) { timeZeroF[0] = 0.0; } } else { timeZeroF[0] = 0.0; } /* Resolve filename parameter */ switch( fname[0] ) { case '\0': samefile = 1; hdunum = 1; break; case '[': samefile = 1; i = 1; while( fname[i] != '\0' && fname[i] != ']' ) i++; if( fname[i] ) { fname[i] = '\0'; fname++; ffexts( fname, &hdunum, extname, &extvers, &movetotype, xcol, xexpr, &gParse.status ); if( *extname ) { ffmnhd( fptr, movetotype, extname, extvers, &gParse.status ); ffghdn( fptr, &hdunum ); } else if( hdunum ) { ffmahd( fptr, ++hdunum, &hdutype, &gParse.status ); } else if( !gParse.status ) { yyerror("Cannot use primary array for GTI filter"); return( -1 ); } } else { yyerror("File extension specifier lacks closing ']'"); return( -1 ); } break; case '+': samefile = 1; hdunum = atoi( fname ) + 1; if( hdunum>1 ) ffmahd( fptr, hdunum, &hdutype, &gParse.status ); else { yyerror("Cannot use primary array for GTI filter"); return( -1 ); } break; default: samefile = 0; if( ! ffopen( &fptr, fname, READONLY, &gParse.status ) ) ffghdn( fptr, &hdunum ); break; } if( gParse.status ) return(-1); /* If at primary, search for GTI extension */ if( hdunum==1 ) { while( 1 ) { hdunum++; if( ffmahd( fptr, hdunum, &hdutype, &gParse.status ) ) break; if( hdutype==IMAGE_HDU ) continue; tstat = 0; if( ffgkys( fptr, "EXTNAME", extname, NULL, &tstat ) ) continue; ffupch( extname ); if( strstr( extname, "GTI" ) ) break; } if( gParse.status ) { if( gParse.status==END_OF_FILE ) yyerror("GTI extension not found in this file"); return(-1); } } /* Locate START/STOP Columns */ ffgcno( fptr, CASEINSEN, start, &startCol, &gParse.status ); ffgcno( fptr, CASEINSEN, stop, &stopCol, &gParse.status ); if( gParse.status ) return(-1); /* Look for TIMEZERO keywords in GTI extension */ tstat = 0; if( ffgkyd( fptr, "TIMEZERO", timeZeroI+1, NULL, &tstat ) ) { tstat = 0; if( ffgkyd( fptr, "TIMEZERI", timeZeroI+1, NULL, &tstat ) ) { timeZeroI[1] = timeZeroF[1] = 0.0; } else if( ffgkyd( fptr, "TIMEZERF", timeZeroF+1, NULL, &tstat ) ) { timeZeroF[1] = 0.0; } } else { timeZeroF[1] = 0.0; } n = Alloc_Node(); if( n >= 0 ) { this = gParse.Nodes + n; this->nSubNodes = 2; this->SubNodes[1] = Node1; this->operation = (int)gtifilt_fct; this->DoOp = Do_GTI; this->type = BOOLEAN; that1 = gParse.Nodes + Node1; this->value.nelem = that1->value.nelem; this->value.naxis = that1->value.naxis; for( i=0; i < that1->value.naxis; i++ ) this->value.naxes[i] = that1->value.naxes[i]; /* Init START/STOP node to be treated as a "constant" */ this->SubNodes[0] = Node0; that0 = gParse.Nodes + Node0; that0->operation = CONST_OP; that0->DoOp = NULL; that0->value.data.ptr= NULL; /* Read in START/STOP times */ if( ffgkyj( fptr, "NAXIS2", &nrows, NULL, &gParse.status ) ) return(-1); that0->value.nelem = nrows; if( nrows ) { that0->value.data.dblptr = (double*)malloc( 2*nrows*sizeof(double) ); if( !that0->value.data.dblptr ) { gParse.status = MEMORY_ALLOCATION; return(-1); } ffgcvd( fptr, startCol, 1L, 1L, nrows, 0.0, that0->value.data.dblptr, &i, &gParse.status ); ffgcvd( fptr, stopCol, 1L, 1L, nrows, 0.0, that0->value.data.dblptr+nrows, &i, &gParse.status ); if( gParse.status ) { free( that0->value.data.dblptr ); return(-1); } /* Test for fully time-ordered GTI... both START && STOP */ that0->type = 1; /* Assume yes */ i = nrows; while( --i ) if( that0->value.data.dblptr[i-1] >= that0->value.data.dblptr[i] || that0->value.data.dblptr[i-1+nrows] >= that0->value.data.dblptr[i+nrows] ) { that0->type = 0; break; } /* Handle TIMEZERO offset, if any */ dt = (timeZeroI[1] - timeZeroI[0]) + (timeZeroF[1] - timeZeroF[0]); timeSpan = that0->value.data.dblptr[nrows+nrows-1] - that0->value.data.dblptr[0]; if( fabs( dt / timeSpan ) > 1e-12 ) { for( i=0; i<(nrows+nrows); i++ ) that0->value.data.dblptr[i] += dt; } } if( gParse.Nodes[Node1].operation==CONST_OP ) this->DoOp( this ); } if( samefile ) ffmahd( fptr, evthdu, &hdutype, &gParse.status ); else ffclos( fptr, &gParse.status ); return( n ); } static int New_REG( char *fname, int NodeX, int NodeY, char *colNames ) { Node *this, *that0; int type, n, Node0; int Xcol, Ycol, tstat; WCSdata wcs; SAORegion *Rgn; char *cX, *cY; YYSTYPE colVal; if( NodeX==-99 ) { type = yyGetVariable( "X", &colVal ); if( type==COLUMN ) { NodeX = New_Column( (int)colVal.lng ); } else { yyerror("Could not build X column for REGFILTER"); return(-1); } } if( NodeY==-99 ) { type = yyGetVariable( "Y", &colVal ); if( type==COLUMN ) { NodeY = New_Column( (int)colVal.lng ); } else { yyerror("Could not build Y column for REGFILTER"); return(-1); } } NodeX = New_Unary( DOUBLE, 0, NodeX ); NodeY = New_Unary( DOUBLE, 0, NodeY ); Node0 = Alloc_Node(); /* This will hold the Region Data */ if( NodeX<0 || NodeY<0 || Node0<0 ) return(-1); if( ! (Test_Dims( NodeX, NodeY ) ) ) { yyerror("Dimensions of REGFILTER arguments are not compatible"); return (-1); } n = Alloc_Node(); if( n >= 0 ) { this = gParse.Nodes + n; this->nSubNodes = 3; this->SubNodes[0] = Node0; this->SubNodes[1] = NodeX; this->SubNodes[2] = NodeY; this->operation = (int)regfilt_fct; this->DoOp = Do_REG; this->type = BOOLEAN; this->value.nelem = 1; this->value.naxis = 1; this->value.naxes[0] = 1; Copy_Dims(n, NodeX); if( SIZE(NodeX)operation = CONST_OP; that0->DoOp = NULL; /* Identify what columns to use for WCS information */ Xcol = Ycol = 0; if( *colNames ) { /* Use the column names in this string for WCS info */ while( *colNames==' ' ) colNames++; cX = cY = colNames; while( *cY && *cY!=' ' && *cY!=',' ) cY++; if( *cY ) *(cY++) = '\0'; while( *cY==' ' ) cY++; if( !*cY ) { yyerror("Could not extract valid pair of column names from REGFILTER"); Free_Last_Node(); return( -1 ); } fits_get_colnum( gParse.def_fptr, CASEINSEN, cX, &Xcol, &gParse.status ); fits_get_colnum( gParse.def_fptr, CASEINSEN, cY, &Ycol, &gParse.status ); if( gParse.status ) { yyerror("Could not locate columns indicated for WCS info"); Free_Last_Node(); return( -1 ); } } else { /* Try to find columns used in X/Y expressions */ Xcol = Locate_Col( gParse.Nodes + NodeX ); Ycol = Locate_Col( gParse.Nodes + NodeY ); if( Xcol<0 || Ycol<0 ) { yyerror("Found multiple X/Y column references in REGFILTER"); Free_Last_Node(); return( -1 ); } } /* Now, get the WCS info, if it exists, from the indicated columns */ wcs.exists = 0; if( Xcol>0 && Ycol>0 ) { tstat = 0; ffgtcs( gParse.def_fptr, Xcol, Ycol, &wcs.xrefval, &wcs.yrefval, &wcs.xrefpix, &wcs.yrefpix, &wcs.xinc, &wcs.yinc, &wcs.rot, wcs.type, &tstat ); if( tstat==NO_WCS_KEY ) { wcs.exists = 0; } else if( tstat ) { gParse.status = tstat; Free_Last_Node(); return( -1 ); } else { wcs.exists = 1; } } /* Read in Region file */ fits_read_rgnfile( fname, &wcs, &Rgn, &gParse.status ); if( gParse.status ) { Free_Last_Node(); return( -1 ); } that0->value.data.ptr = Rgn; if( gParse.Nodes[NodeX].operation==CONST_OP && gParse.Nodes[NodeY].operation==CONST_OP ) this->DoOp( this ); } return( n ); } static int New_Vector( int subNode ) { Node *this, *that; int n; n = Alloc_Node(); if( n >= 0 ) { this = gParse.Nodes + n; that = gParse.Nodes + subNode; this->type = that->type; this->nSubNodes = 1; this->SubNodes[0] = subNode; this->operation = '{'; this->DoOp = Do_Vector; } return( n ); } static int Close_Vec( int vecNode ) { Node *this; int n, nelem=0; this = gParse.Nodes + vecNode; for( n=0; n < this->nSubNodes; n++ ) { if( TYPE( this->SubNodes[n] ) != this->type ) { this->SubNodes[n] = New_Unary( this->type, 0, this->SubNodes[n] ); if( this->SubNodes[n]<0 ) return(-1); } nelem += SIZE(this->SubNodes[n]); } this->value.naxis = 1; this->value.nelem = nelem; this->value.naxes[0] = nelem; return( vecNode ); } static int Locate_Col( Node *this ) /* Locate the TABLE column number of any columns in "this" calculation. */ /* Return ZERO if none found, or negative if more than 1 found. */ { Node *that; int i, col=0, newCol, nfound=0; if( this->nSubNodes==0 && this->operation<=0 && this->operation!=CONST_OP ) return gParse.colData[ - this->operation].colnum; for( i=0; inSubNodes; i++ ) { that = gParse.Nodes + this->SubNodes[i]; if( that->operation>0 ) { newCol = Locate_Col( that ); if( newCol<=0 ) { nfound += -newCol; } else { if( !nfound ) { col = newCol; nfound++; } else if( col != newCol ) { nfound++; } } } else if( that->operation!=CONST_OP ) { /* Found a Column */ newCol = gParse.colData[- that->operation].colnum; if( !nfound ) { col = newCol; nfound++; } else if( col != newCol ) { nfound++; } } } if( nfound!=1 ) return( - nfound ); else return( col ); } static int Test_Dims( int Node1, int Node2 ) { Node *that1, *that2; int valid, i; if( Node1<0 || Node2<0 ) return(0); that1 = gParse.Nodes + Node1; that2 = gParse.Nodes + Node2; if( that1->value.nelem==1 || that2->value.nelem==1 ) valid = 1; else if( that1->type==that2->type && that1->value.nelem==that2->value.nelem && that1->value.naxis==that2->value.naxis ) { valid = 1; for( i=0; ivalue.naxis; i++ ) { if( that1->value.naxes[i]!=that2->value.naxes[i] ) valid = 0; } } else valid = 0; return( valid ); } static void Copy_Dims( int Node1, int Node2 ) { Node *that1, *that2; int i; if( Node1<0 || Node2<0 ) return; that1 = gParse.Nodes + Node1; that2 = gParse.Nodes + Node2; that1->value.nelem = that2->value.nelem; that1->value.naxis = that2->value.naxis; for( i=0; ivalue.naxis; i++ ) that1->value.naxes[i] = that2->value.naxes[i]; } /********************************************************************/ /* Routines for actually evaluating the expression start here */ /********************************************************************/ void Evaluate_Parser( long firstRow, long nRows ) /***********************************************************************/ /* Reset the parser for processing another batch of data... */ /* firstRow: Row number of the first element to evaluate */ /* nRows: Number of rows to be processed */ /* Initialize each COLUMN node so that its UNDEF and DATA pointers */ /* point to the appropriate column arrays. */ /* Finally, call Evaluate_Node for final node. */ /***********************************************************************/ { int i, column; long offset, rowOffset; gParse.firstRow = firstRow; gParse.nRows = nRows; /* Reset Column Nodes' pointers to point to right data and UNDEF arrays */ rowOffset = firstRow - gParse.firstDataRow; for( i=0; i 0 || gParse.Nodes[i].operation == CONST_OP ) continue; column = -gParse.Nodes[i].operation; offset = gParse.varData[column].nelem * rowOffset; gParse.Nodes[i].value.undef = gParse.varData[column].undef + offset; switch( gParse.Nodes[i].type ) { case BITSTR: gParse.Nodes[i].value.data.strptr = (char**)gParse.varData[column].data + rowOffset; gParse.Nodes[i].value.undef = NULL; break; case STRING: gParse.Nodes[i].value.data.strptr = (char**)gParse.varData[column].data + rowOffset; gParse.Nodes[i].value.undef = gParse.varData[column].undef + rowOffset; break; case BOOLEAN: gParse.Nodes[i].value.data.logptr = (char*)gParse.varData[column].data + offset; break; case LONG: gParse.Nodes[i].value.data.lngptr = (long*)gParse.varData[column].data + offset; break; case DOUBLE: gParse.Nodes[i].value.data.dblptr = (double*)gParse.varData[column].data + offset; break; } } Evaluate_Node( gParse.resultNode ); } static void Evaluate_Node( int thisNode ) /**********************************************************************/ /* Recursively evaluate thisNode's subNodes, then call one of the */ /* Do_ functions pointed to by thisNode's DoOp element. */ /**********************************************************************/ { Node *this; int i; if( gParse.status ) return; this = gParse.Nodes + thisNode; if( this->operation>0 ) { /* <=0 indicate constants and columns */ i = this->nSubNodes; while( i-- ) { Evaluate_Node( this->SubNodes[i] ); if( gParse.status ) return; } this->DoOp( this ); } } static void Allocate_Ptrs( Node *this ) { long elem, row, size; if( this->type==BITSTR || this->type==STRING ) { this->value.data.strptr = (char**)malloc( gParse.nRows * sizeof(char*) ); if( this->value.data.strptr ) { this->value.data.strptr[0] = (char*)malloc( gParse.nRows * (this->value.nelem+2) * sizeof(char) ); if( this->value.data.strptr[0] ) { row = 0; while( (++row)value.data.strptr[row] = this->value.data.strptr[row-1] + this->value.nelem+1; } if( this->type==STRING ) { this->value.undef = this->value.data.strptr[row-1] + this->value.nelem+1; } else { this->value.undef = NULL; /* BITSTRs don't use undef array */ } } else { gParse.status = MEMORY_ALLOCATION; free( this->value.data.strptr ); } } else { gParse.status = MEMORY_ALLOCATION; } } else { elem = this->value.nelem * gParse.nRows; switch( this->type ) { case DOUBLE: size = sizeof( double ); break; case LONG: size = sizeof( long ); break; case BOOLEAN: size = sizeof( char ); break; default: size = 1; break; } this->value.data.ptr = calloc(size+1, elem); if( this->value.data.ptr==NULL ) { gParse.status = MEMORY_ALLOCATION; } else { this->value.undef = (char *)this->value.data.ptr + elem*size; } } } static void Do_Unary( Node *this ) { Node *that; long elem; that = gParse.Nodes + this->SubNodes[0]; if( that->operation==CONST_OP ) { /* Operating on a constant! */ switch( this->operation ) { case DOUBLE: case FLTCAST: if( that->type==LONG ) this->value.data.dbl = (double)that->value.data.lng; else if( that->type==BOOLEAN ) this->value.data.dbl = ( that->value.data.log ? 1.0 : 0.0 ); break; case LONG: case INTCAST: if( that->type==DOUBLE ) this->value.data.lng = (long)that->value.data.dbl; else if( that->type==BOOLEAN ) this->value.data.lng = ( that->value.data.log ? 1L : 0L ); break; case BOOLEAN: if( that->type==DOUBLE ) this->value.data.log = ( that->value.data.dbl != 0.0 ); else if( that->type==LONG ) this->value.data.log = ( that->value.data.lng != 0L ); break; case UMINUS: if( that->type==DOUBLE ) this->value.data.dbl = - that->value.data.dbl; else if( that->type==LONG ) this->value.data.lng = - that->value.data.lng; break; case NOT: if( that->type==BOOLEAN ) this->value.data.log = ( ! that->value.data.log ); else if( that->type==BITSTR ) bitnot( this->value.data.str, that->value.data.str ); break; } this->operation = CONST_OP; } else { Allocate_Ptrs( this ); if( !gParse.status ) { if( this->type!=BITSTR ) { elem = gParse.nRows; if( this->type!=STRING ) elem *= this->value.nelem; while( elem-- ) this->value.undef[elem] = that->value.undef[elem]; } elem = gParse.nRows * this->value.nelem; switch( this->operation ) { case BOOLEAN: if( that->type==DOUBLE ) while( elem-- ) this->value.data.logptr[elem] = ( that->value.data.dblptr[elem] != 0.0 ); else if( that->type==LONG ) while( elem-- ) this->value.data.logptr[elem] = ( that->value.data.lngptr[elem] != 0L ); break; case DOUBLE: case FLTCAST: if( that->type==LONG ) while( elem-- ) this->value.data.dblptr[elem] = (double)that->value.data.lngptr[elem]; else if( that->type==BOOLEAN ) while( elem-- ) this->value.data.dblptr[elem] = ( that->value.data.logptr[elem] ? 1.0 : 0.0 ); break; case LONG: case INTCAST: if( that->type==DOUBLE ) while( elem-- ) this->value.data.lngptr[elem] = (long)that->value.data.dblptr[elem]; else if( that->type==BOOLEAN ) while( elem-- ) this->value.data.lngptr[elem] = ( that->value.data.logptr[elem] ? 1L : 0L ); break; case UMINUS: if( that->type==DOUBLE ) { while( elem-- ) this->value.data.dblptr[elem] = - that->value.data.dblptr[elem]; } else if( that->type==LONG ) { while( elem-- ) this->value.data.lngptr[elem] = - that->value.data.lngptr[elem]; } break; case NOT: if( that->type==BOOLEAN ) { while( elem-- ) this->value.data.logptr[elem] = ( ! that->value.data.logptr[elem] ); } else if( that->type==BITSTR ) { elem = gParse.nRows; while( elem-- ) bitnot( this->value.data.strptr[elem], that->value.data.strptr[elem] ); } break; } } } if( that->operation>0 ) { free( that->value.data.ptr ); } } static void Do_Offset( Node *this ) { Node *col; long fRow, nRowOverlap, nRowReload, rowOffset; long nelem, elem, offset, nRealElem; int status; col = gParse.Nodes + this->SubNodes[0]; rowOffset = gParse.Nodes[ this->SubNodes[1] ].value.data.lng; Allocate_Ptrs( this ); fRow = gParse.firstRow + rowOffset; if( this->type==STRING || this->type==BITSTR ) nRealElem = 1; else nRealElem = this->value.nelem; nelem = nRealElem; if( fRow < gParse.firstDataRow ) { /* Must fill in data at start of array */ nRowReload = gParse.firstDataRow - fRow; if( nRowReload > gParse.nRows ) nRowReload = gParse.nRows; nRowOverlap = gParse.nRows - nRowReload; offset = 0; /* NULLify any values falling out of bounds */ while( fRow<1 && nRowReload>0 ) { if( this->type == BITSTR ) { nelem = this->value.nelem; this->value.data.strptr[offset][ nelem ] = '\0'; while( nelem-- ) this->value.data.strptr[offset][nelem] = '0'; offset++; } else { while( nelem-- ) this->value.undef[offset++] = 1; } nelem = nRealElem; fRow++; nRowReload--; } } else if( fRow + gParse.nRows > gParse.firstDataRow + gParse.nDataRows ) { /* Must fill in data at end of array */ nRowReload = (fRow+gParse.nRows) - (gParse.firstDataRow+gParse.nDataRows); if( nRowReload>gParse.nRows ) { nRowReload = gParse.nRows; } else { fRow = gParse.firstDataRow + gParse.nDataRows; } nRowOverlap = gParse.nRows - nRowReload; offset = nRowOverlap * nelem; /* NULLify any values falling out of bounds */ elem = gParse.nRows * nelem; while( fRow+nRowReload>gParse.totalRows && nRowReload>0 ) { if( this->type == BITSTR ) { nelem = this->value.nelem; elem--; this->value.data.strptr[elem][ nelem ] = '\0'; while( nelem-- ) this->value.data.strptr[elem][nelem] = '0'; } else { while( nelem-- ) this->value.undef[--elem] = 1; } nelem = nRealElem; nRowReload--; } } else { nRowReload = 0; nRowOverlap = gParse.nRows; offset = 0; } if( nRowReload>0 ) { switch( this->type ) { case BITSTR: case STRING: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.strptr+offset, this->value.undef+offset ); break; case BOOLEAN: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.logptr+offset, this->value.undef+offset ); break; case LONG: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.lngptr+offset, this->value.undef+offset ); break; case DOUBLE: status = (*gParse.loadData)( -col->operation, fRow, nRowReload, this->value.data.dblptr+offset, this->value.undef+offset ); break; } } /* Now copy over the overlapping region, if any */ if( nRowOverlap <= 0 ) return; if( rowOffset>0 ) elem = nRowOverlap * nelem; else elem = gParse.nRows * nelem; offset = nelem * rowOffset; while( nRowOverlap-- && !gParse.status ) { while( nelem-- && !gParse.status ) { elem--; if( this->type != BITSTR ) this->value.undef[elem] = col->value.undef[elem+offset]; switch( this->type ) { case BITSTR: strcpy( this->value.data.strptr[elem ], col->value.data.strptr[elem+offset] ); break; case STRING: strcpy( this->value.data.strptr[elem ], col->value.data.strptr[elem+offset] ); break; case BOOLEAN: this->value.data.logptr[elem] = col->value.data.logptr[elem+offset]; break; case LONG: this->value.data.lngptr[elem] = col->value.data.lngptr[elem+offset]; break; case DOUBLE: this->value.data.dblptr[elem] = col->value.data.dblptr[elem+offset]; break; } } nelem = nRealElem; } } static void Do_BinOp_bit( Node *this ) { Node *that1, *that2; char *sptr1=NULL, *sptr2=NULL; int const1, const2; long rows; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; const1 = ( that1->operation==CONST_OP ); const2 = ( that2->operation==CONST_OP ); sptr1 = ( const1 ? that1->value.data.str : NULL ); sptr2 = ( const2 ? that2->value.data.str : NULL ); if( const1 && const2 ) { switch( this->operation ) { case NE: this->value.data.log = !bitcmp( sptr1, sptr2 ); break; case EQ: this->value.data.log = bitcmp( sptr1, sptr2 ); break; case GT: case LT: case LTE: case GTE: this->value.data.log = bitlgte( sptr1, this->operation, sptr2 ); break; case '|': bitor( this->value.data.str, sptr1, sptr2 ); break; case '&': bitand( this->value.data.str, sptr1, sptr2 ); break; case '+': strcpy( this->value.data.str, sptr1 ); strcat( this->value.data.str, sptr2 ); break; case ACCUM: this->value.data.lng = 0; while( *sptr1 ) { if ( *sptr1 == '1' ) this->value.data.lng ++; sptr1 ++; } break; } this->operation = CONST_OP; } else { Allocate_Ptrs( this ); if( !gParse.status ) { rows = gParse.nRows; switch( this->operation ) { /* BITSTR comparisons */ case NE: case EQ: case GT: case LT: case LTE: case GTE: while( rows-- ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; switch( this->operation ) { case NE: this->value.data.logptr[rows] = !bitcmp( sptr1, sptr2 ); break; case EQ: this->value.data.logptr[rows] = bitcmp( sptr1, sptr2 ); break; case GT: case LT: case LTE: case GTE: this->value.data.logptr[rows] = bitlgte( sptr1, this->operation, sptr2 ); break; } this->value.undef[rows] = 0; } break; /* BITSTR AND/ORs ... no UNDEFS in or out */ case '|': case '&': case '+': while( rows-- ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; if( this->operation=='|' ) bitor( this->value.data.strptr[rows], sptr1, sptr2 ); else if( this->operation=='&' ) bitand( this->value.data.strptr[rows], sptr1, sptr2 ); else { strcpy( this->value.data.strptr[rows], sptr1 ); strcat( this->value.data.strptr[rows], sptr2 ); } } break; /* Accumulate 1 bits */ case ACCUM: { long i, previous, curr; previous = that2->value.data.lng; /* Cumulative sum of this chunk */ for (i=0; ivalue.data.strptr[i]; for (curr = 0; *sptr1; sptr1 ++) { if ( *sptr1 == '1' ) curr ++; } previous += curr; this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } /* Store final cumulant for next pass */ that2->value.data.lng = previous; } } } } if( that1->operation>0 ) { free( that1->value.data.strptr[0] ); free( that1->value.data.strptr ); } if( that2->operation>0 ) { free( that2->value.data.strptr[0] ); free( that2->value.data.strptr ); } } static void Do_BinOp_str( Node *this ) { Node *that1, *that2; char *sptr1, *sptr2, null1=0, null2=0; int const1, const2, val; long rows; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; const1 = ( that1->operation==CONST_OP ); const2 = ( that2->operation==CONST_OP ); sptr1 = ( const1 ? that1->value.data.str : NULL ); sptr2 = ( const2 ? that2->value.data.str : NULL ); if( const1 && const2 ) { /* Result is a constant */ switch( this->operation ) { /* Compare Strings */ case NE: case EQ: val = ( FSTRCMP( sptr1, sptr2 ) == 0 ); this->value.data.log = ( this->operation==EQ ? val : !val ); break; case GT: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) > 0 ); break; case LT: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) < 0 ); break; case GTE: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) >= 0 ); break; case LTE: this->value.data.log = ( FSTRCMP( sptr1, sptr2 ) <= 0 ); break; /* Concat Strings */ case '+': strcpy( this->value.data.str, sptr1 ); strcat( this->value.data.str, sptr2 ); break; } this->operation = CONST_OP; } else { /* Not a constant */ Allocate_Ptrs( this ); if( !gParse.status ) { rows = gParse.nRows; switch( this->operation ) { /* Compare Strings */ case NE: case EQ: while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; val = ( FSTRCMP( sptr1, sptr2 ) == 0 ); this->value.data.logptr[rows] = ( this->operation==EQ ? val : !val ); } } break; case GT: case LT: while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; val = ( FSTRCMP( sptr1, sptr2 ) ); this->value.data.logptr[rows] = ( this->operation==GT ? val>0 : val<0 ); } } break; case GTE: case LTE: while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; val = ( FSTRCMP( sptr1, sptr2 ) ); this->value.data.logptr[rows] = ( this->operation==GTE ? val>=0 : val<=0 ); } } break; /* Concat Strings */ case '+': while( rows-- ) { if( !const1 ) null1 = that1->value.undef[rows]; if( !const2 ) null2 = that2->value.undef[rows]; this->value.undef[rows] = (null1 || null2); if( ! this->value.undef[rows] ) { if( !const1 ) sptr1 = that1->value.data.strptr[rows]; if( !const2 ) sptr2 = that2->value.data.strptr[rows]; strcpy( this->value.data.strptr[rows], sptr1 ); strcat( this->value.data.strptr[rows], sptr2 ); } } break; } } } if( that1->operation>0 ) { free( that1->value.data.strptr[0] ); free( that1->value.data.strptr ); } if( that2->operation>0 ) { free( that2->value.data.strptr[0] ); free( that2->value.data.strptr ); } } static void Do_BinOp_log( Node *this ) { Node *that1, *that2; int vector1, vector2; char val1=0, val2=0, null1=0, null2=0; long rows, nelem, elem; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; vector1 = ( that1->operation!=CONST_OP ); if( vector1 ) vector1 = that1->value.nelem; else { val1 = that1->value.data.log; } vector2 = ( that2->operation!=CONST_OP ); if( vector2 ) vector2 = that2->value.nelem; else { val2 = that2->value.data.log; } if( !vector1 && !vector2 ) { /* Result is a constant */ switch( this->operation ) { case OR: this->value.data.log = (val1 || val2); break; case AND: this->value.data.log = (val1 && val2); break; case EQ: this->value.data.log = ( (val1 && val2) || (!val1 && !val2) ); break; case NE: this->value.data.log = ( (val1 && !val2) || (!val1 && val2) ); break; case ACCUM: this->value.data.lng = val1; break; } this->operation=CONST_OP; } else if (this->operation == ACCUM) { long i, previous, curr; rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { previous = that2->value.data.lng; /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.logptr[i]; previous += curr; } this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } /* Store final cumulant for next pass */ that2->value.data.lng = previous; } } else { rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { if (this->operation == ACCUM) { long i, previous, curr; previous = that2->value.data.lng; /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.logptr[i]; previous += curr; } this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } /* Store final cumulant for next pass */ that2->value.data.lng = previous; } while( rows-- ) { while( nelem-- ) { elem--; if( vector1>1 ) { val1 = that1->value.data.logptr[elem]; null1 = that1->value.undef[elem]; } else if( vector1 ) { val1 = that1->value.data.logptr[rows]; null1 = that1->value.undef[rows]; } if( vector2>1 ) { val2 = that2->value.data.logptr[elem]; null2 = that2->value.undef[elem]; } else if( vector2 ) { val2 = that2->value.data.logptr[rows]; null2 = that2->value.undef[rows]; } this->value.undef[elem] = (null1 || null2); switch( this->operation ) { case OR: /* This is more complicated than others to suppress UNDEFs */ /* in those cases where the other argument is DEF && TRUE */ if( !null1 && !null2 ) { this->value.data.logptr[elem] = (val1 || val2); } else if( (null1 && !null2 && val2) || ( !null1 && null2 && val1 ) ) { this->value.data.logptr[elem] = 1; this->value.undef[elem] = 0; } break; case AND: /* This is more complicated than others to suppress UNDEFs */ /* in those cases where the other argument is DEF && FALSE */ if( !null1 && !null2 ) { this->value.data.logptr[elem] = (val1 && val2); } else if( (null1 && !null2 && !val2) || ( !null1 && null2 && !val1 ) ) { this->value.data.logptr[elem] = 0; this->value.undef[elem] = 0; } break; case EQ: this->value.data.logptr[elem] = ( (val1 && val2) || (!val1 && !val2) ); break; case NE: this->value.data.logptr[elem] = ( (val1 && !val2) || (!val1 && val2) ); break; } } nelem = this->value.nelem; } } } if( that1->operation>0 ) { free( that1->value.data.ptr ); } if( that2->operation>0 ) { free( that2->value.data.ptr ); } } static void Do_BinOp_lng( Node *this ) { Node *that1, *that2; int vector1, vector2; long val1=0, val2=0; char null1=0, null2=0; long rows, nelem, elem; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; vector1 = ( that1->operation!=CONST_OP ); if( vector1 ) vector1 = that1->value.nelem; else { val1 = that1->value.data.lng; } vector2 = ( that2->operation!=CONST_OP ); if( vector2 ) vector2 = that2->value.nelem; else { val2 = that2->value.data.lng; } if( !vector1 && !vector2 ) { /* Result is a constant */ switch( this->operation ) { case '~': /* Treat as == for LONGS */ case EQ: this->value.data.log = (val1 == val2); break; case NE: this->value.data.log = (val1 != val2); break; case GT: this->value.data.log = (val1 > val2); break; case LT: this->value.data.log = (val1 < val2); break; case LTE: this->value.data.log = (val1 <= val2); break; case GTE: this->value.data.log = (val1 >= val2); break; case '+': this->value.data.lng = (val1 + val2); break; case '-': this->value.data.lng = (val1 - val2); break; case '*': this->value.data.lng = (val1 * val2); break; case '%': if( val2 ) this->value.data.lng = (val1 % val2); else yyerror("Divide by Zero"); break; case '/': if( val2 ) this->value.data.lng = (val1 / val2); else yyerror("Divide by Zero"); break; case POWER: this->value.data.lng = (long)pow((double)val1,(double)val2); break; case ACCUM: this->value.data.lng = val1; break; case DIFF: this->value.data.lng = 0; break; } this->operation=CONST_OP; } else if ((this->operation == ACCUM) || (this->operation == DIFF)) { long i, previous, curr; long undef; rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { previous = that2->value.data.lng; undef = (long) that2->value.undef; if (this->operation == ACCUM) { /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.lngptr[i]; previous += curr; } this->value.data.lngptr[i] = previous; this->value.undef[i] = 0; } } else { /* Sequential difference for this chunk */ for (i=0; ivalue.data.lngptr[i]; if (that1->value.undef[i] || undef) { /* Either this, or previous, value was undefined */ this->value.data.lngptr[i] = 0; this->value.undef[i] = 1; } else { /* Both defined, we are okay! */ this->value.data.lngptr[i] = curr - previous; this->value.undef[i] = 0; } previous = curr; undef = that1->value.undef[i]; } } /* Store final cumulant for next pass */ that2->value.data.lng = previous; that2->value.undef = (char *) undef; /* XXX evil, but no harm here */ } } else { rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); while( rows-- && !gParse.status ) { while( nelem-- && !gParse.status ) { elem--; if( vector1>1 ) { val1 = that1->value.data.lngptr[elem]; null1 = that1->value.undef[elem]; } else if( vector1 ) { val1 = that1->value.data.lngptr[rows]; null1 = that1->value.undef[rows]; } if( vector2>1 ) { val2 = that2->value.data.lngptr[elem]; null2 = that2->value.undef[elem]; } else if( vector2 ) { val2 = that2->value.data.lngptr[rows]; null2 = that2->value.undef[rows]; } this->value.undef[elem] = (null1 || null2); switch( this->operation ) { case '~': /* Treat as == for LONGS */ case EQ: this->value.data.logptr[elem] = (val1 == val2); break; case NE: this->value.data.logptr[elem] = (val1 != val2); break; case GT: this->value.data.logptr[elem] = (val1 > val2); break; case LT: this->value.data.logptr[elem] = (val1 < val2); break; case LTE: this->value.data.logptr[elem] = (val1 <= val2); break; case GTE: this->value.data.logptr[elem] = (val1 >= val2); break; case '+': this->value.data.lngptr[elem] = (val1 + val2); break; case '-': this->value.data.lngptr[elem] = (val1 - val2); break; case '*': this->value.data.lngptr[elem] = (val1 * val2); break; case '%': if( val2 ) this->value.data.lngptr[elem] = (val1 % val2); else { this->value.data.lngptr[elem] = 0; this->value.undef[elem] = 1; } break; case '/': if( val2 ) this->value.data.lngptr[elem] = (val1 / val2); else { this->value.data.lngptr[elem] = 0; this->value.undef[elem] = 1; } break; case POWER: this->value.data.lngptr[elem] = (long)pow((double)val1,(double)val2); break; } } nelem = this->value.nelem; } } if( that1->operation>0 ) { free( that1->value.data.ptr ); } if( that2->operation>0 ) { free( that2->value.data.ptr ); } } static void Do_BinOp_dbl( Node *this ) { Node *that1, *that2; int vector1, vector2; double val1=0.0, val2=0.0; char null1=0, null2=0; long rows, nelem, elem; that1 = gParse.Nodes + this->SubNodes[0]; that2 = gParse.Nodes + this->SubNodes[1]; vector1 = ( that1->operation!=CONST_OP ); if( vector1 ) vector1 = that1->value.nelem; else { val1 = that1->value.data.dbl; } vector2 = ( that2->operation!=CONST_OP ); if( vector2 ) vector2 = that2->value.nelem; else { val2 = that2->value.data.dbl; } if( !vector1 && !vector2 ) { /* Result is a constant */ switch( this->operation ) { case '~': this->value.data.log = ( fabs(val1-val2) < APPROX ); break; case EQ: this->value.data.log = (val1 == val2); break; case NE: this->value.data.log = (val1 != val2); break; case GT: this->value.data.log = (val1 > val2); break; case LT: this->value.data.log = (val1 < val2); break; case LTE: this->value.data.log = (val1 <= val2); break; case GTE: this->value.data.log = (val1 >= val2); break; case '+': this->value.data.dbl = (val1 + val2); break; case '-': this->value.data.dbl = (val1 - val2); break; case '*': this->value.data.dbl = (val1 * val2); break; case '%': if( val2 ) this->value.data.dbl = val1 - val2*((int)(val1/val2)); else yyerror("Divide by Zero"); break; case '/': if( val2 ) this->value.data.dbl = (val1 / val2); else yyerror("Divide by Zero"); break; case POWER: this->value.data.dbl = (double)pow(val1,val2); break; case ACCUM: this->value.data.dbl = val1; break; case DIFF: this->value.data.dbl = 0; break; } this->operation=CONST_OP; } else if ((this->operation == ACCUM) || (this->operation == DIFF)) { long i; long undef; double previous, curr; rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); if( !gParse.status ) { previous = that2->value.data.dbl; undef = (long) that2->value.undef; if (this->operation == ACCUM) { /* Cumulative sum of this chunk */ for (i=0; ivalue.undef[i]) { curr = that1->value.data.dblptr[i]; previous += curr; } this->value.data.dblptr[i] = previous; this->value.undef[i] = 0; } } else { /* Sequential difference for this chunk */ for (i=0; ivalue.data.dblptr[i]; if (that1->value.undef[i] || undef) { /* Either this, or previous, value was undefined */ this->value.data.dblptr[i] = 0; this->value.undef[i] = 1; } else { /* Both defined, we are okay! */ this->value.data.dblptr[i] = curr - previous; this->value.undef[i] = 0; } previous = curr; undef = that1->value.undef[i]; } } /* Store final cumulant for next pass */ that2->value.data.dbl = previous; that2->value.undef = (char *) undef; /* XXX evil, but no harm here */ } } else { rows = gParse.nRows; nelem = this->value.nelem; elem = this->value.nelem * rows; Allocate_Ptrs( this ); while( rows-- && !gParse.status ) { while( nelem-- && !gParse.status ) { elem--; if( vector1>1 ) { val1 = that1->value.data.dblptr[elem]; null1 = that1->value.undef[elem]; } else if( vector1 ) { val1 = that1->value.data.dblptr[rows]; null1 = that1->value.undef[rows]; } if( vector2>1 ) { val2 = that2->value.data.dblptr[elem]; null2 = that2->value.undef[elem]; } else if( vector2 ) { val2 = that2->value.data.dblptr[rows]; null2 = that2->value.undef[rows]; } this->value.undef[elem] = (null1 || null2); switch( this->operation ) { case '~': this->value.data.logptr[elem] = ( fabs(val1-val2) < APPROX ); break; case EQ: this->value.data.logptr[elem] = (val1 == val2); break; case NE: this->value.data.logptr[elem] = (val1 != val2); break; case GT: this->value.data.logptr[elem] = (val1 > val2); break; case LT: this->value.data.logptr[elem] = (val1 < val2); break; case LTE: this->value.data.logptr[elem] = (val1 <= val2); break; case GTE: this->value.data.logptr[elem] = (val1 >= val2); break; case '+': this->value.data.dblptr[elem] = (val1 + val2); break; case '-': this->value.data.dblptr[elem] = (val1 - val2); break; case '*': this->value.data.dblptr[elem] = (val1 * val2); break; case '%': if( val2 ) this->value.data.dblptr[elem] = val1 - val2*((int)(val1/val2)); else { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } break; case '/': if( val2 ) this->value.data.dblptr[elem] = (val1 / val2); else { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } break; case POWER: this->value.data.dblptr[elem] = (double)pow(val1,val2); break; } } nelem = this->value.nelem; } } if( that1->operation>0 ) { free( that1->value.data.ptr ); } if( that2->operation>0 ) { free( that2->value.data.ptr ); } } /* * This Quickselect routine is based on the algorithm described in * "Numerical recipes in C", Second Edition, * Cambridge University Press, 1992, Section 8.5, ISBN 0-521-43108-5 * This code by Nicolas Devillard - 1998. Public domain. * http://ndevilla.free.fr/median/median/src/quickselect.c */ #define ELEM_SWAP(a,b) { register long t=(a);(a)=(b);(b)=t; } /* * qselect_median_lng - select the median value of a long array * * This routine selects the median value of the long integer array * arr[]. If there are an even number of elements, the "lower median" * is selected. * * The array arr[] is scrambled, so users must operate on a scratch * array if they wish the values to be preserved. * * long arr[] - array of values * int n - number of elements in arr * * RETURNS: the lower median value of arr[] * */ long qselect_median_lng(long arr[], int n) { int low, high ; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) { /* One element only */ return arr[median]; } if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median]; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP #define ELEM_SWAP(a,b) { register double t=(a);(a)=(b);(b)=t; } /* * qselect_median_dbl - select the median value of a double array * * This routine selects the median value of the double array * arr[]. If there are an even number of elements, the "lower median" * is selected. * * The array arr[] is scrambled, so users must operate on a scratch * array if they wish the values to be preserved. * * double arr[] - array of values * int n - number of elements in arr * * RETURNS: the lower median value of arr[] * */ double qselect_median_dbl(double arr[], int n) { int low, high ; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) { /* One element only */ return arr[median] ; } if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median] ; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP /* * angsep_calc - compute angular separation between celestial coordinates * * This routine computes the angular separation between to coordinates * on the celestial sphere (i.e. RA and Dec). Note that all units are * in DEGREES, unlike the other trig functions in the calculator. * * double ra1, dec1 - RA and Dec of the first position in degrees * double ra2, dec2 - RA and Dec of the second position in degrees * * RETURNS: (double) angular separation in degrees * */ double angsep_calc(double ra1, double dec1, double ra2, double dec2) { double cd; static double deg = 0; if (deg == 0) deg = ((double)4)*atan((double)1)/((double)180); /* deg = 1.0; **** UNCOMMENT IF YOU WANT RADIANS */ cd = sin(dec1*deg)*sin(dec2*deg) + cos(dec1*deg)*cos(dec2*deg)*cos((ra1-ra2)*deg); if (cd < (-1)) cd = -1; if (cd > (+1)) cd = +1; return acos(cd)/deg; } static double ran1() { static double dval = 0.0; double rndVal; if (dval == 0.0) { if( rand()<32768 && rand()<32768 ) dval = 32768.0; else dval = 2147483648.0; } rndVal = (double)rand(); while( rndVal > dval ) dval *= 2.0; return rndVal/dval; } /* Gaussian deviate routine from Numerical Recipes */ static double gasdev() { static int iset = 0; static double gset; double fac, rsq, v1, v2; if (iset == 0) { do { v1 = 2.0*ran1()-1.0; v2 = 2.0*ran1()-1.0; rsq = v1*v1 + v2*v2; } while (rsq >= 1.0 || rsq == 0.0); fac = sqrt(-2.0*log(rsq)/rsq); gset = v1*fac; iset = 1; return v2*fac; } else { iset = 0; return gset; } } /* lgamma function - from Numerical Recipes */ float gammaln(float xx) /* Returns the value ln Gamma[(xx)] for xx > 0. */ { /* Internal arithmetic will be done in double precision, a nicety that you can omit if five-figure accuracy is good enough. */ double x,y,tmp,ser; static double cof[6]={76.18009172947146,-86.50532032941677, 24.01409824083091,-1.231739572450155, 0.1208650973866179e-2,-0.5395239384953e-5}; int j; y=x=xx; tmp=x+5.5; tmp -= (x+0.5)*log(tmp); ser=1.000000000190015; for (j=0;j<=5;j++) ser += cof[j]/++y; return (float) -tmp+log(2.5066282746310005*ser/x); } /* Poisson deviate - derived from Numerical Recipes */ static long poidev(double xm) { static double sq, alxm, g, oldm = -1.0; static double pi = 0; double em, t, y; if (pi == 0) pi = ((double)4)*atan((double)1); if (xm < 20.0) { if (xm != oldm) { oldm = xm; g = exp(-xm); } em = -1; t = 1.0; do { em += 1; t *= ran1(); } while (t > g); } else { if (xm != oldm) { oldm = xm; sq = sqrt(2.0*xm); alxm = log(xm); g = xm*alxm-gammaln( (float) (xm+1.0)); } do { do { y = tan(pi*ran1()); em = sq*y+xm; } while (em < 0.0); em = floor(em); t = 0.9*(1.0+y*y)*exp(em*alxm-gammaln( (float) (em+1.0) )-g); } while (ran1() > t); } /* Return integer version */ return (long int) floor(em+0.5); } static void Do_Func( Node *this ) { Node *theParams[MAXSUBS]; int vector[MAXSUBS], allConst; lval pVals[MAXSUBS]; char pNull[MAXSUBS]; long ival; double dval; int i, valInit; long row, elem, nelem; i = this->nSubNodes; allConst = 1; while( i-- ) { theParams[i] = gParse.Nodes + this->SubNodes[i]; vector[i] = ( theParams[i]->operation!=CONST_OP ); if( vector[i] ) { allConst = 0; vector[i] = theParams[i]->value.nelem; } else { if( theParams[i]->type==DOUBLE ) { pVals[i].data.dbl = theParams[i]->value.data.dbl; } else if( theParams[i]->type==LONG ) { pVals[i].data.lng = theParams[i]->value.data.lng; } else if( theParams[i]->type==BOOLEAN ) { pVals[i].data.log = theParams[i]->value.data.log; } else strcpy(pVals[i].data.str, theParams[i]->value.data.str); pNull[i] = 0; } } if( this->nSubNodes==0 ) allConst = 0; /* These do produce scalars */ if( this->operation == poirnd_fct ) allConst = 0; if( allConst ) { switch( this->operation ) { /* Non-Trig single-argument functions */ case sum_fct: if( theParams[0]->type==BOOLEAN ) this->value.data.lng = ( pVals[0].data.log ? 1 : 0 ); else if( theParams[0]->type==LONG ) this->value.data.lng = pVals[0].data.lng; else if( theParams[0]->type==DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( theParams[0]->type==BITSTR ) strcpy(this->value.data.str, pVals[0].data.str); break; case average_fct: if( theParams[0]->type==LONG ) this->value.data.dbl = pVals[0].data.lng; else if( theParams[0]->type==DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; break; case stddev_fct: this->value.data.dbl = 0; /* Standard deviation of a constant = 0 */ break; case median_fct: if( theParams[0]->type==BOOLEAN ) this->value.data.lng = ( pVals[0].data.log ? 1 : 0 ); else if( theParams[0]->type==LONG ) this->value.data.lng = pVals[0].data.lng; else this->value.data.dbl = pVals[0].data.dbl; break; case poirnd_fct: if( theParams[0]->type==DOUBLE ) this->value.data.lng = poidev(pVals[0].data.dbl); else this->value.data.lng = poidev(pVals[0].data.lng); break; case abs_fct: if( theParams[0]->type==DOUBLE ) { dval = pVals[0].data.dbl; this->value.data.dbl = (dval>0.0 ? dval : -dval); } else { ival = pVals[0].data.lng; this->value.data.lng = (ival> 0 ? ival : -ival); } break; /* Special Null-Handling Functions */ case nonnull_fct: this->value.data.lng = 1; /* Constants are always 1-element and defined */ break; case isnull_fct: /* Constants are always defined */ this->value.data.log = 0; break; case defnull_fct: if( this->type==BOOLEAN ) this->value.data.log = pVals[0].data.log; else if( this->type==LONG ) this->value.data.lng = pVals[0].data.lng; else if( this->type==DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( this->type==STRING ) strcpy(this->value.data.str,pVals[0].data.str); break; /* Math functions with 1 double argument */ case sin_fct: this->value.data.dbl = sin( pVals[0].data.dbl ); break; case cos_fct: this->value.data.dbl = cos( pVals[0].data.dbl ); break; case tan_fct: this->value.data.dbl = tan( pVals[0].data.dbl ); break; case asin_fct: dval = pVals[0].data.dbl; if( dval<-1.0 || dval>1.0 ) yyerror("Out of range argument to arcsin"); else this->value.data.dbl = asin( dval ); break; case acos_fct: dval = pVals[0].data.dbl; if( dval<-1.0 || dval>1.0 ) yyerror("Out of range argument to arccos"); else this->value.data.dbl = acos( dval ); break; case atan_fct: this->value.data.dbl = atan( pVals[0].data.dbl ); break; case sinh_fct: this->value.data.dbl = sinh( pVals[0].data.dbl ); break; case cosh_fct: this->value.data.dbl = cosh( pVals[0].data.dbl ); break; case tanh_fct: this->value.data.dbl = tanh( pVals[0].data.dbl ); break; case exp_fct: this->value.data.dbl = exp( pVals[0].data.dbl ); break; case log_fct: dval = pVals[0].data.dbl; if( dval<=0.0 ) yyerror("Out of range argument to log"); else this->value.data.dbl = log( dval ); break; case log10_fct: dval = pVals[0].data.dbl; if( dval<=0.0 ) yyerror("Out of range argument to log10"); else this->value.data.dbl = log10( dval ); break; case sqrt_fct: dval = pVals[0].data.dbl; if( dval<0.0 ) yyerror("Out of range argument to sqrt"); else this->value.data.dbl = sqrt( dval ); break; case ceil_fct: this->value.data.dbl = ceil( pVals[0].data.dbl ); break; case floor_fct: this->value.data.dbl = floor( pVals[0].data.dbl ); break; case round_fct: this->value.data.dbl = floor( pVals[0].data.dbl + 0.5 ); break; /* Two-argument Trig Functions */ case atan2_fct: this->value.data.dbl = atan2( pVals[0].data.dbl, pVals[1].data.dbl ); break; /* Four-argument ANGSEP function */ case angsep_fct: this->value.data.dbl = angsep_calc(pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl); /* Min/Max functions taking 1 or 2 arguments */ case min1_fct: /* No constant vectors! */ if( this->type == DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( this->type == LONG ) this->value.data.lng = pVals[0].data.lng; else if( this->type == BITSTR ) strcpy(this->value.data.str, pVals[0].data.str); break; case min2_fct: if( this->type == DOUBLE ) this->value.data.dbl = minvalue( pVals[0].data.dbl, pVals[1].data.dbl ); else if( this->type == LONG ) this->value.data.lng = minvalue( pVals[0].data.lng, pVals[1].data.lng ); break; case max1_fct: /* No constant vectors! */ if( this->type == DOUBLE ) this->value.data.dbl = pVals[0].data.dbl; else if( this->type == LONG ) this->value.data.lng = pVals[0].data.lng; else if( this->type == BITSTR ) strcpy(this->value.data.str, pVals[0].data.str); break; case max2_fct: if( this->type == DOUBLE ) this->value.data.dbl = maxvalue( pVals[0].data.dbl, pVals[1].data.dbl ); else if( this->type == LONG ) this->value.data.lng = maxvalue( pVals[0].data.lng, pVals[1].data.lng ); break; /* Boolean SAO region Functions... scalar or vector dbls */ case near_fct: this->value.data.log = bnear( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl ); break; case circle_fct: this->value.data.log = circle( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl ); break; case box_fct: this->value.data.log = saobox( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); break; case elps_fct: this->value.data.log = ellipse( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); break; /* C Conditional expression: bool ? expr : expr */ case ifthenelse_fct: switch( this->type ) { case BOOLEAN: this->value.data.log = ( pVals[2].data.log ? pVals[0].data.log : pVals[1].data.log ); break; case LONG: this->value.data.lng = ( pVals[2].data.log ? pVals[0].data.lng : pVals[1].data.lng ); break; case DOUBLE: this->value.data.dbl = ( pVals[2].data.log ? pVals[0].data.dbl : pVals[1].data.dbl ); break; case STRING: strcpy(this->value.data.str, ( pVals[2].data.log ? pVals[0].data.str : pVals[1].data.str ) ); break; } break; } this->operation = CONST_OP; } else { Allocate_Ptrs( this ); row = gParse.nRows; elem = row * this->value.nelem; if( !gParse.status ) { switch( this->operation ) { /* Special functions with no arguments */ case row_fct: while( row-- ) { this->value.data.lngptr[row] = gParse.firstRow + row; this->value.undef[row] = 0; } break; case null_fct: if( this->type==LONG ) { while( row-- ) { this->value.data.lngptr[row] = 0; this->value.undef[row] = 1; } } else if( this->type==STRING ) { while( row-- ) { this->value.data.strptr[row][0] = '\0'; this->value.undef[row] = 1; } } break; case rnd_fct: while( row-- ) { this->value.data.dblptr[row] = ran1(); this->value.undef[row] = 0; } break; case gasrnd_fct: while( row-- ) { this->value.data.dblptr[row] = gasdev(); this->value.undef[row] = 0; } break; case poirnd_fct: if( theParams[0]->type==DOUBLE ) { if (theParams[0]->operation == CONST_OP) { while( elem-- ) { this->value.undef[elem] = (pVals[0].data.dbl < 0); if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = poidev(pVals[0].data.dbl); } } } else { while( elem-- ) { this->value.undef[elem] = theParams[0]->value.undef[elem]; if (theParams[0]->value.data.dblptr[elem] < 0) this->value.undef[elem] = 1; if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = poidev(theParams[0]->value.data.dblptr[elem]); } } /* while */ } /* ! CONST_OP */ } else { /* LONG */ if (theParams[0]->operation == CONST_OP) { while( elem-- ) { this->value.undef[elem] = (pVals[0].data.lng < 0); if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = poidev(pVals[0].data.lng); } } } else { while( elem-- ) { this->value.undef[elem] = theParams[0]->value.undef[elem]; if (theParams[0]->value.data.lngptr[elem] < 0) this->value.undef[elem] = 1; if (! this->value.undef[elem]) { this->value.data.lngptr[elem] = poidev(theParams[0]->value.data.lngptr[elem]); } } /* while */ } /* ! CONST_OP */ } /* END LONG */ break; /* Non-Trig single-argument functions */ case sum_fct: elem = row * theParams[0]->value.nelem; if( theParams[0]->type==BOOLEAN ) { while( row-- ) { this->value.data.lngptr[row] = 0; /* Default is UNDEF until a defined value is found */ this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( ! theParams[0]->value.undef[elem] ) { this->value.data.lngptr[row] += ( theParams[0]->value.data.logptr[elem] ? 1 : 0 ); this->value.undef[row] = 0; } } } } else if( theParams[0]->type==LONG ) { while( row-- ) { this->value.data.lngptr[row] = 0; /* Default is UNDEF until a defined value is found */ this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( ! theParams[0]->value.undef[elem] ) { this->value.data.lngptr[row] += theParams[0]->value.data.lngptr[elem]; this->value.undef[row] = 0; } } } } else if( theParams[0]->type==DOUBLE ){ while( row-- ) { this->value.data.dblptr[row] = 0.0; /* Default is UNDEF until a defined value is found */ this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( ! theParams[0]->value.undef[elem] ) { this->value.data.dblptr[row] += theParams[0]->value.data.dblptr[elem]; this->value.undef[row] = 0; } } } } else { /* BITSTR */ nelem = theParams[0]->value.nelem; while( row-- ) { char *sptr1 = theParams[0]->value.data.strptr[row]; this->value.data.lngptr[row] = 0; this->value.undef[row] = 0; while (*sptr1) { if (*sptr1 == '1') this->value.data.lngptr[row] ++; sptr1++; } } } break; case average_fct: elem = row * theParams[0]->value.nelem; if( theParams[0]->type==LONG ) { while( row-- ) { int count = 0; this->value.data.dblptr[row] = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { this->value.data.dblptr[row] += theParams[0]->value.data.lngptr[elem]; count ++; } } if (count == 0) { this->value.undef[row] = 1; } else { this->value.undef[row] = 0; this->value.data.dblptr[row] /= count; } } } else if( theParams[0]->type==DOUBLE ){ while( row-- ) { int count = 0; this->value.data.dblptr[row] = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { this->value.data.dblptr[row] += theParams[0]->value.data.dblptr[elem]; count ++; } } if (count == 0) { this->value.undef[row] = 1; } else { this->value.undef[row] = 0; this->value.data.dblptr[row] /= count; } } } break; case stddev_fct: elem = row * theParams[0]->value.nelem; if( theParams[0]->type==LONG ) { /* Compute the mean value */ while( row-- ) { int count = 0; double sum = 0, sum2 = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { sum += theParams[0]->value.data.lngptr[elem]; count ++; } } if (count > 1) { sum /= count; /* Compute the sum of squared deviations */ nelem = theParams[0]->value.nelem; elem += nelem; /* Reset elem for second pass */ while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { double dx = (theParams[0]->value.data.lngptr[elem] - sum); sum2 += (dx*dx); } } sum2 /= (double)count-1; this->value.undef[row] = 0; this->value.data.dblptr[row] = sqrt(sum2); } else { this->value.undef[row] = 0; /* STDDEV => 0 */ this->value.data.dblptr[row] = 0; } } } else if( theParams[0]->type==DOUBLE ){ /* Compute the mean value */ while( row-- ) { int count = 0; double sum = 0, sum2 = 0; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { sum += theParams[0]->value.data.dblptr[elem]; count ++; } } if (count > 1) { sum /= count; /* Compute the sum of squared deviations */ nelem = theParams[0]->value.nelem; elem += nelem; /* Reset elem for second pass */ while( nelem-- ) { elem--; if (theParams[0]->value.undef[elem] == 0) { double dx = (theParams[0]->value.data.dblptr[elem] - sum); sum2 += (dx*dx); } } sum2 /= (double)count-1; this->value.undef[row] = 0; this->value.data.dblptr[row] = sqrt(sum2); } else { this->value.undef[row] = 0; /* STDDEV => 0 */ this->value.data.dblptr[row] = 0; } } } break; case median_fct: elem = row * theParams[0]->value.nelem; nelem = theParams[0]->value.nelem; if( theParams[0]->type==LONG ) { long *dptr = theParams[0]->value.data.lngptr; char *uptr = theParams[0]->value.undef; long *mptr = (long *) malloc(sizeof(long)*nelem); int irow; /* Allocate temporary storage for this row, since the quickselect function will scramble the contents */ if (mptr == 0) { yyerror("Could not allocate temporary memory in median function"); free( this->value.data.ptr ); break; } for (irow=0; irow 0) { this->value.undef[irow] = 0; this->value.data.lngptr[irow] = qselect_median_lng(mptr, nelem1); } else { this->value.undef[irow] = 1; this->value.data.lngptr[irow] = 0; } } free(mptr); } else { double *dptr = theParams[0]->value.data.dblptr; char *uptr = theParams[0]->value.undef; double *mptr = (double *) malloc(sizeof(double)*nelem); int irow; /* Allocate temporary storage for this row, since the quickselect function will scramble the contents */ if (mptr == 0) { yyerror("Could not allocate temporary memory in median function"); free( this->value.data.ptr ); break; } for (irow=0; irow 0) { this->value.undef[irow] = 0; this->value.data.dblptr[irow] = qselect_median_dbl(mptr, nelem1); } else { this->value.undef[irow] = 1; this->value.data.dblptr[irow] = 0; } } free(mptr); } break; case abs_fct: if( theParams[0]->type==DOUBLE ) while( elem-- ) { dval = theParams[0]->value.data.dblptr[elem]; this->value.data.dblptr[elem] = (dval>0.0 ? dval : -dval); this->value.undef[elem] = theParams[0]->value.undef[elem]; } else while( elem-- ) { ival = theParams[0]->value.data.lngptr[elem]; this->value.data.lngptr[elem] = (ival> 0 ? ival : -ival); this->value.undef[elem] = theParams[0]->value.undef[elem]; } break; /* Special Null-Handling Functions */ case nonnull_fct: nelem = theParams[0]->value.nelem; if ( theParams[0]->type==STRING ) nelem = 1; elem = row * nelem; while( row-- ) { int nelem1 = nelem; this->value.undef[row] = 0; /* Initialize to 0 (defined) */ this->value.data.lngptr[row] = 0; while( nelem1-- ) { elem --; if ( theParams[0]->value.undef[elem] == 0 ) this->value.data.lngptr[row] ++; } } break; case isnull_fct: if( theParams[0]->type==STRING ) elem = row; while( elem-- ) { this->value.data.logptr[elem] = theParams[0]->value.undef[elem]; this->value.undef[elem] = 0; } break; case defnull_fct: switch( this->type ) { case BOOLEAN: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pNull[i] = theParams[i]->value.undef[elem]; pVals[i].data.log = theParams[i]->value.data.logptr[elem]; } else if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; pVals[i].data.log = theParams[i]->value.data.logptr[row]; } if( pNull[0] ) { this->value.undef[elem] = pNull[1]; this->value.data.logptr[elem] = pVals[1].data.log; } else { this->value.undef[elem] = 0; this->value.data.logptr[elem] = pVals[0].data.log; } } } break; case LONG: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pNull[i] = theParams[i]->value.undef[elem]; pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; } else if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; } if( pNull[0] ) { this->value.undef[elem] = pNull[1]; this->value.data.lngptr[elem] = pVals[1].data.lng; } else { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[0].data.lng; } } } break; case DOUBLE: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pNull[i] = theParams[i]->value.undef[elem]; pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; } else if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; } if( pNull[0] ) { this->value.undef[elem] = pNull[1]; this->value.data.dblptr[elem] = pVals[1].data.dbl; } else { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[0].data.dbl; } } } break; case STRING: while( row-- ) { i=2; while( i-- ) if( vector[i] ) { pNull[i] = theParams[i]->value.undef[row]; strcpy(pVals[i].data.str, theParams[i]->value.data.strptr[row]); } if( pNull[0] ) { this->value.undef[row] = pNull[1]; strcpy(this->value.data.strptr[row],pVals[1].data.str); } else { this->value.undef[elem] = 0; strcpy(this->value.data.strptr[row],pVals[0].data.str); } } } break; /* Math functions with 1 double argument */ case sin_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = sin( theParams[0]->value.data.dblptr[elem] ); } break; case cos_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = cos( theParams[0]->value.data.dblptr[elem] ); } break; case tan_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = tan( theParams[0]->value.data.dblptr[elem] ); } break; case asin_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<-1.0 || dval>1.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = asin( dval ); } break; case acos_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<-1.0 || dval>1.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = acos( dval ); } break; case atan_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; this->value.data.dblptr[elem] = atan( dval ); } break; case sinh_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = sinh( theParams[0]->value.data.dblptr[elem] ); } break; case cosh_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = cosh( theParams[0]->value.data.dblptr[elem] ); } break; case tanh_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = tanh( theParams[0]->value.data.dblptr[elem] ); } break; case exp_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; this->value.data.dblptr[elem] = exp( dval ); } break; case log_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<=0.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = log( dval ); } break; case log10_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<=0.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = log10( dval ); } break; case sqrt_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { dval = theParams[0]->value.data.dblptr[elem]; if( dval<0.0 ) { this->value.data.dblptr[elem] = 0.0; this->value.undef[elem] = 1; } else this->value.data.dblptr[elem] = sqrt( dval ); } break; case ceil_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = ceil( theParams[0]->value.data.dblptr[elem] ); } break; case floor_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = floor( theParams[0]->value.data.dblptr[elem] ); } break; case round_fct: while( elem-- ) if( !(this->value.undef[elem] = theParams[0]->value.undef[elem]) ) { this->value.data.dblptr[elem] = floor( theParams[0]->value.data.dblptr[elem] + 0.5); } break; /* Two-argument Trig Functions */ case atan2_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1]) ) ) this->value.data.dblptr[elem] = atan2( pVals[0].data.dbl, pVals[1].data.dbl ); } } break; /* Four-argument ANGSEP Function */ case angsep_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=4; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3]) ) ) this->value.data.dblptr[elem] = angsep_calc(pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl); } } break; /* Min/Max functions taking 1 or 2 arguments */ case min1_fct: elem = row * theParams[0]->value.nelem; if( this->type==LONG ) { long minVal=0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; minVal = theParams[0]->value.data.lngptr[elem]; } else { minVal = minvalue( minVal, theParams[0]->value.data.lngptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.lngptr[row] = minVal; } } else if( this->type==DOUBLE ) { double minVal=0.0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; minVal = theParams[0]->value.data.dblptr[elem]; } else { minVal = minvalue( minVal, theParams[0]->value.data.dblptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.dblptr[row] = minVal; } } else if( this->type==BITSTR ) { char minVal; while( row-- ) { char *sptr1 = theParams[0]->value.data.strptr[row]; minVal = '1'; while (*sptr1) { if (*sptr1 == '0') minVal = '0'; sptr1++; } this->value.data.strptr[row][0] = minVal; this->value.data.strptr[row][1] = 0; /* Null terminate */ } } break; case min2_fct: if( this->type==LONG ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.lngptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[1].data.lng; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[0].data.lng; } else { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = minvalue( pVals[0].data.lng, pVals[1].data.lng ); } } } } else if( this->type==DOUBLE ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.dblptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[1].data.dbl; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[0].data.dbl; } else { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = minvalue( pVals[0].data.dbl, pVals[1].data.dbl ); } } } } break; case max1_fct: elem = row * theParams[0]->value.nelem; if( this->type==LONG ) { long maxVal=0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; maxVal = theParams[0]->value.data.lngptr[elem]; } else { maxVal = maxvalue( maxVal, theParams[0]->value.data.lngptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.lngptr[row] = maxVal; } } else if( this->type==DOUBLE ) { double maxVal=0.0; while( row-- ) { valInit = 1; this->value.undef[row] = 1; nelem = theParams[0]->value.nelem; while( nelem-- ) { elem--; if ( !theParams[0]->value.undef[elem] ) { if ( valInit ) { valInit = 0; maxVal = theParams[0]->value.data.dblptr[elem]; } else { maxVal = maxvalue( maxVal, theParams[0]->value.data.dblptr[elem] ); } this->value.undef[row] = 0; } } this->value.data.dblptr[row] = maxVal; } } else if( this->type==BITSTR ) { char maxVal; while( row-- ) { char *sptr1 = theParams[0]->value.data.strptr[row]; maxVal = '0'; while (*sptr1) { if (*sptr1 == '1') maxVal = '1'; sptr1++; } this->value.data.strptr[row][0] = maxVal; this->value.data.strptr[row][1] = 0; /* Null terminate */ } } break; case max2_fct: if( this->type==LONG ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.lngptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[1].data.lng; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = pVals[0].data.lng; } else { this->value.undef[elem] = 0; this->value.data.lngptr[elem] = maxvalue( pVals[0].data.lng, pVals[1].data.lng ); } } } } else if( this->type==DOUBLE ) { while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( pNull[0] && pNull[1] ) { this->value.undef[elem] = 1; this->value.data.dblptr[elem] = 0; } else if (pNull[0]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[1].data.dbl; } else if (pNull[1]) { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = pVals[0].data.dbl; } else { this->value.undef[elem] = 0; this->value.data.dblptr[elem] = maxvalue( pVals[0].data.dbl, pVals[1].data.dbl ); } } } } break; /* Boolean SAO region Functions... scalar or vector dbls */ case near_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=3; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2]) ) ) this->value.data.logptr[elem] = bnear( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl ); } } break; case circle_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=5; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3] || pNull[4]) ) ) this->value.data.logptr[elem] = circle( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl ); } } break; case box_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=7; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3] || pNull[4] || pNull[5] || pNull[6] ) ) ) this->value.data.logptr[elem] = saobox( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); } } break; case elps_fct: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; i=7; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = (pNull[0] || pNull[1] || pNull[2] || pNull[3] || pNull[4] || pNull[5] || pNull[6] ) ) ) this->value.data.logptr[elem] = ellipse( pVals[0].data.dbl, pVals[1].data.dbl, pVals[2].data.dbl, pVals[3].data.dbl, pVals[4].data.dbl, pVals[5].data.dbl, pVals[6].data.dbl ); } } break; /* C Conditional expression: bool ? expr : expr */ case ifthenelse_fct: switch( this->type ) { case BOOLEAN: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; if( vector[2]>1 ) { pVals[2].data.log = theParams[2]->value.data.logptr[elem]; pNull[2] = theParams[2]->value.undef[elem]; } else if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.log = theParams[i]->value.data.logptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.log = theParams[i]->value.data.logptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = pNull[2]) ) { if( pVals[2].data.log ) { this->value.data.logptr[elem] = pVals[0].data.log; this->value.undef[elem] = pNull[0]; } else { this->value.data.logptr[elem] = pVals[1].data.log; this->value.undef[elem] = pNull[1]; } } } } break; case LONG: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; if( vector[2]>1 ) { pVals[2].data.log = theParams[2]->value.data.logptr[elem]; pNull[2] = theParams[2]->value.undef[elem]; } else if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.lng = theParams[i]->value.data.lngptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = pNull[2]) ) { if( pVals[2].data.log ) { this->value.data.lngptr[elem] = pVals[0].data.lng; this->value.undef[elem] = pNull[0]; } else { this->value.data.lngptr[elem] = pVals[1].data.lng; this->value.undef[elem] = pNull[1]; } } } } break; case DOUBLE: while( row-- ) { nelem = this->value.nelem; while( nelem-- ) { elem--; if( vector[2]>1 ) { pVals[2].data.log = theParams[2]->value.data.logptr[elem]; pNull[2] = theParams[2]->value.undef[elem]; } else if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i]>1 ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[elem]; pNull[i] = theParams[i]->value.undef[elem]; } else if( vector[i] ) { pVals[i].data.dbl = theParams[i]->value.data.dblptr[row]; pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[elem] = pNull[2]) ) { if( pVals[2].data.log ) { this->value.data.dblptr[elem] = pVals[0].data.dbl; this->value.undef[elem] = pNull[0]; } else { this->value.data.dblptr[elem] = pVals[1].data.dbl; this->value.undef[elem] = pNull[1]; } } } } break; case STRING: while( row-- ) { if( vector[2] ) { pVals[2].data.log = theParams[2]->value.data.logptr[row]; pNull[2] = theParams[2]->value.undef[row]; } i=2; while( i-- ) if( vector[i] ) { strcpy( pVals[i].data.str, theParams[i]->value.data.strptr[row] ); pNull[i] = theParams[i]->value.undef[row]; } if( !(this->value.undef[row] = pNull[2]) ) { if( pVals[2].data.log ) { strcpy( this->value.data.strptr[row], pVals[0].data.str ); this->value.undef[row] = pNull[0]; } else { strcpy( this->value.data.strptr[row], pVals[1].data.str ); this->value.undef[row] = pNull[1]; } } else { this->value.data.strptr[row][0] = '\0'; } } break; } break; } } } i = this->nSubNodes; while( i-- ) { if( theParams[i]->operation>0 ) { /* Currently only numeric params allowed */ free( theParams[i]->value.data.ptr ); } } } static void Do_Deref( Node *this ) { Node *theVar, *theDims[MAXDIMS]; int isConst[MAXDIMS], allConst; long dimVals[MAXDIMS]; int i, nDims; long row, elem, dsize; theVar = gParse.Nodes + this->SubNodes[0]; i = nDims = this->nSubNodes-1; allConst = 1; while( i-- ) { theDims[i] = gParse.Nodes + this->SubNodes[i+1]; isConst[i] = ( theDims[i]->operation==CONST_OP ); if( isConst[i] ) dimVals[i] = theDims[i]->value.data.lng; else allConst = 0; } if( this->type==DOUBLE ) { dsize = sizeof( double ); } else if( this->type==LONG ) { dsize = sizeof( long ); } else if( this->type==BOOLEAN ) { dsize = sizeof( char ); } else dsize = 0; Allocate_Ptrs( this ); if( !gParse.status ) { if( allConst && theVar->value.naxis==nDims ) { /* Dereference completely using constant indices */ elem = 0; i = nDims; while( i-- ) { if( dimVals[i]<1 || dimVals[i]>theVar->value.naxes[i] ) break; elem = theVar->value.naxes[i]*elem + dimVals[i]-1; } if( i<0 ) { for( row=0; rowtype==STRING ) this->value.undef[row] = theVar->value.undef[row]; else if( this->type==BITSTR ) this->value.undef; /* Dummy - BITSTRs do not have undefs */ else this->value.undef[row] = theVar->value.undef[elem]; if( this->type==DOUBLE ) this->value.data.dblptr[row] = theVar->value.data.dblptr[elem]; else if( this->type==LONG ) this->value.data.lngptr[row] = theVar->value.data.lngptr[elem]; else if( this->type==BOOLEAN ) this->value.data.logptr[row] = theVar->value.data.logptr[elem]; else { /* XXX Note, the below expression uses knowledge of the layout of the string format, namely (nelem+1) characters per string, followed by (nelem+1) "undef" values. */ this->value.data.strptr[row][0] = theVar->value.data.strptr[0][elem+row]; this->value.data.strptr[row][1] = 0; /* Null terminate */ } elem += theVar->value.nelem; } } else { yyerror("Index out of range"); free( this->value.data.ptr ); } } else if( allConst && nDims==1 ) { /* Reduce dimensions by 1, using a constant index */ if( dimVals[0] < 1 || dimVals[0] > theVar->value.naxes[ theVar->value.naxis-1 ] ) { yyerror("Index out of range"); free( this->value.data.ptr ); } else if ( this->type == BITSTR || this->type == STRING ) { elem = this->value.nelem * (dimVals[0]-1); for( row=0; rowvalue.undef) this->value.undef[row] = theVar->value.undef[row]; memcpy( (char*)this->value.data.strptr[0] + row*sizeof(char)*(this->value.nelem+1), (char*)theVar->value.data.strptr[0] + elem*sizeof(char), this->value.nelem * sizeof(char) ); /* Null terminate */ this->value.data.strptr[row][this->value.nelem] = 0; elem += theVar->value.nelem+1; } } else { elem = this->value.nelem * (dimVals[0]-1); for( row=0; rowvalue.undef + row*this->value.nelem, theVar->value.undef + elem, this->value.nelem * sizeof(char) ); memcpy( (char*)this->value.data.ptr + row*dsize*this->value.nelem, (char*)theVar->value.data.ptr + elem*dsize, this->value.nelem * dsize ); elem += theVar->value.nelem; } } } else if( theVar->value.naxis==nDims ) { /* Dereference completely using an expression for the indices */ for( row=0; rowvalue.undef[row] ) { yyerror("Null encountered as vector index"); free( this->value.data.ptr ); break; } else dimVals[i] = theDims[i]->value.data.lngptr[row]; } } if( gParse.status ) break; elem = 0; i = nDims; while( i-- ) { if( dimVals[i]<1 || dimVals[i]>theVar->value.naxes[i] ) break; elem = theVar->value.naxes[i]*elem + dimVals[i]-1; } if( i<0 ) { elem += row*theVar->value.nelem; if( this->type==STRING ) this->value.undef[row] = theVar->value.undef[row]; else if( this->type==BITSTR ) this->value.undef; /* Dummy - BITSTRs do not have undefs */ else this->value.undef[row] = theVar->value.undef[elem]; if( this->type==DOUBLE ) this->value.data.dblptr[row] = theVar->value.data.dblptr[elem]; else if( this->type==LONG ) this->value.data.lngptr[row] = theVar->value.data.lngptr[elem]; else if( this->type==BOOLEAN ) this->value.data.logptr[row] = theVar->value.data.logptr[elem]; else { /* XXX Note, the below expression uses knowledge of the layout of the string format, namely (nelem+1) characters per string, followed by (nelem+1) "undef" values. */ this->value.data.strptr[row][0] = theVar->value.data.strptr[0][elem+row]; this->value.data.strptr[row][1] = 0; /* Null terminate */ } } else { yyerror("Index out of range"); free( this->value.data.ptr ); } } } else { /* Reduce dimensions by 1, using a nonconstant expression */ for( row=0; rowvalue.undef[row] ) { yyerror("Null encountered as vector index"); free( this->value.data.ptr ); break; } else dimVals[0] = theDims[0]->value.data.lngptr[row]; if( dimVals[0] < 1 || dimVals[0] > theVar->value.naxes[ theVar->value.naxis-1 ] ) { yyerror("Index out of range"); free( this->value.data.ptr ); } else if ( this->type == BITSTR || this->type == STRING ) { elem = this->value.nelem * (dimVals[0]-1); elem += row*(theVar->value.nelem+1); if (this->value.undef) this->value.undef[row] = theVar->value.undef[row]; memcpy( (char*)this->value.data.strptr[0] + row*sizeof(char)*(this->value.nelem+1), (char*)theVar->value.data.strptr[0] + elem*sizeof(char), this->value.nelem * sizeof(char) ); /* Null terminate */ this->value.data.strptr[row][this->value.nelem] = 0; } else { elem = this->value.nelem * (dimVals[0]-1); elem += row*theVar->value.nelem; memcpy( this->value.undef + row*this->value.nelem, theVar->value.undef + elem, this->value.nelem * sizeof(char) ); memcpy( (char*)this->value.data.ptr + row*dsize*this->value.nelem, (char*)theVar->value.data.ptr + elem*dsize, this->value.nelem * dsize ); } } } } if( theVar->operation>0 ) { if (theVar->type == STRING || theVar->type == BITSTR) free(theVar->value.data.strptr[0] ); else free( theVar->value.data.ptr ); } for( i=0; ioperation>0 ) { free( theDims[i]->value.data.ptr ); } } static void Do_GTI( Node *this ) { Node *theExpr, *theTimes; double *start, *stop, *times; long elem, nGTI, gti; int ordered; theTimes = gParse.Nodes + this->SubNodes[0]; theExpr = gParse.Nodes + this->SubNodes[1]; nGTI = theTimes->value.nelem; start = theTimes->value.data.dblptr; stop = theTimes->value.data.dblptr + nGTI; ordered = theTimes->type; if( theExpr->operation==CONST_OP ) { this->value.data.log = (Search_GTI( theExpr->value.data.dbl, nGTI, start, stop, ordered )>=0); this->operation = CONST_OP; } else { Allocate_Ptrs( this ); times = theExpr->value.data.dblptr; if( !gParse.status ) { elem = gParse.nRows * this->value.nelem; if( nGTI ) { gti = -1; while( elem-- ) { if( (this->value.undef[elem] = theExpr->value.undef[elem]) ) continue; /* Before searching entire GTI, check the GTI found last time */ if( gti<0 || times[elem]stop[gti] ) { gti = Search_GTI( times[elem], nGTI, start, stop, ordered ); } this->value.data.logptr[elem] = ( gti>=0 ); } } else while( elem-- ) { this->value.data.logptr[elem] = 0; this->value.undef[elem] = 0; } } } if( theExpr->operation>0 ) free( theExpr->value.data.ptr ); } static long Search_GTI( double evtTime, long nGTI, double *start, double *stop, int ordered ) { long gti, step; if( ordered && nGTI>15 ) { /* If time-ordered and lots of GTIs, */ /* use "FAST" Binary search algorithm */ if( evtTime>=start[0] && evtTime<=stop[nGTI-1] ) { gti = step = (nGTI >> 1); while(1) { if( step>1L ) step >>= 1; if( evtTime>stop[gti] ) { if( evtTime>=start[gti+1] ) gti += step; else { gti = -1L; break; } } else if( evtTime=start[gti] && evtTime<=stop[gti] ) break; } return( gti ); } static void Do_REG( Node *this ) { Node *theRegion, *theX, *theY; double Xval=0.0, Yval=0.0; char Xnull=0, Ynull=0; int Xvector, Yvector; long nelem, elem, rows; theRegion = gParse.Nodes + this->SubNodes[0]; theX = gParse.Nodes + this->SubNodes[1]; theY = gParse.Nodes + this->SubNodes[2]; Xvector = ( theX->operation!=CONST_OP ); if( Xvector ) Xvector = theX->value.nelem; else { Xval = theX->value.data.dbl; } Yvector = ( theY->operation!=CONST_OP ); if( Yvector ) Yvector = theY->value.nelem; else { Yval = theY->value.data.dbl; } if( !Xvector && !Yvector ) { this->value.data.log = ( fits_in_region( Xval, Yval, (SAORegion *)theRegion->value.data.ptr ) != 0 ); this->operation = CONST_OP; } else { Allocate_Ptrs( this ); if( !gParse.status ) { rows = gParse.nRows; nelem = this->value.nelem; elem = rows*nelem; while( rows-- ) { while( nelem-- ) { elem--; if( Xvector>1 ) { Xval = theX->value.data.dblptr[elem]; Xnull = theX->value.undef[elem]; } else if( Xvector ) { Xval = theX->value.data.dblptr[rows]; Xnull = theX->value.undef[rows]; } if( Yvector>1 ) { Yval = theY->value.data.dblptr[elem]; Ynull = theY->value.undef[elem]; } else if( Yvector ) { Yval = theY->value.data.dblptr[rows]; Ynull = theY->value.undef[rows]; } this->value.undef[elem] = ( Xnull || Ynull ); if( this->value.undef[elem] ) continue; this->value.data.logptr[elem] = ( fits_in_region( Xval, Yval, (SAORegion *)theRegion->value.data.ptr ) != 0 ); } nelem = this->value.nelem; } } } if( theX->operation>0 ) free( theX->value.data.ptr ); if( theY->operation>0 ) free( theY->value.data.ptr ); } static void Do_Vector( Node *this ) { Node *that; long row, elem, idx, jdx, offset=0; int node; Allocate_Ptrs( this ); if( !gParse.status ) { for( node=0; nodenSubNodes; node++ ) { that = gParse.Nodes + this->SubNodes[node]; if( that->operation == CONST_OP ) { idx = gParse.nRows*this->value.nelem + offset; while( (idx-=this->value.nelem)>=0 ) { this->value.undef[idx] = 0; switch( this->type ) { case BOOLEAN: this->value.data.logptr[idx] = that->value.data.log; break; case LONG: this->value.data.lngptr[idx] = that->value.data.lng; break; case DOUBLE: this->value.data.dblptr[idx] = that->value.data.dbl; break; } } } else { row = gParse.nRows; idx = row * that->value.nelem; while( row-- ) { elem = that->value.nelem; jdx = row*this->value.nelem + offset; while( elem-- ) { this->value.undef[jdx+elem] = that->value.undef[--idx]; switch( this->type ) { case BOOLEAN: this->value.data.logptr[jdx+elem] = that->value.data.logptr[idx]; break; case LONG: this->value.data.lngptr[jdx+elem] = that->value.data.lngptr[idx]; break; case DOUBLE: this->value.data.dblptr[jdx+elem] = that->value.data.dblptr[idx]; break; } } } } offset += that->value.nelem; } } for( node=0; node < this->nSubNodes; node++ ) if( gParse.Nodes[this->SubNodes[node]].operation>0 ) free( gParse.Nodes[this->SubNodes[node]].value.data.ptr ); } /*****************************************************************************/ /* Utility routines which perform the calculations on bits and SAO regions */ /*****************************************************************************/ static char bitlgte(char *bits1, int oper, char *bits2) { int val1, val2, nextbit; char result; int i, l1, l2, length, ldiff; char stream[256]; char chr1, chr2; l1 = strlen(bits1); l2 = strlen(bits2); if (l1 < l2) { length = l2; ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bits1++); stream[i] = '\0'; bits1 = stream; } else if (l2 < l1) { length = l1; ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bits2++); stream[i] = '\0'; bits2 = stream; } else length = l1; val1 = val2 = 0; nextbit = 1; while( length-- ) { chr1 = bits1[length]; chr2 = bits2[length]; if ((chr1 != 'x')&&(chr1 != 'X')&&(chr2 != 'x')&&(chr2 != 'X')) { if (chr1 == '1') val1 += nextbit; if (chr2 == '1') val2 += nextbit; nextbit *= 2; } } result = 0; switch (oper) { case LT: if (val1 < val2) result = 1; break; case LTE: if (val1 <= val2) result = 1; break; case GT: if (val1 > val2) result = 1; break; case GTE: if (val1 >= val2) result = 1; break; } return (result); } static void bitand(char *result,char *bitstrm1,char *bitstrm2) { int i, l1, l2, ldiff; char stream[256]; char chr1, chr2; l1 = strlen(bitstrm1); l2 = strlen(bitstrm2); if (l1 < l2) { ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bitstrm1++); stream[i] = '\0'; bitstrm1 = stream; } else if (l2 < l1) { ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bitstrm2++); stream[i] = '\0'; bitstrm2 = stream; } while ( (chr1 = *(bitstrm1++)) ) { chr2 = *(bitstrm2++); if ((chr1 == 'x') || (chr2 == 'x')) *result = 'x'; else if ((chr1 == '1') && (chr2 == '1')) *result = '1'; else *result = '0'; result++; } *result = '\0'; } static void bitor(char *result,char *bitstrm1,char *bitstrm2) { int i, l1, l2, ldiff; char stream[256]; char chr1, chr2; l1 = strlen(bitstrm1); l2 = strlen(bitstrm2); if (l1 < l2) { ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bitstrm1++); stream[i] = '\0'; bitstrm1 = stream; } else if (l2 < l1) { ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bitstrm2++); stream[i] = '\0'; bitstrm2 = stream; } while ( (chr1 = *(bitstrm1++)) ) { chr2 = *(bitstrm2++); if ((chr1 == '1') || (chr2 == '1')) *result = '1'; else if ((chr1 == '0') || (chr2 == '0')) *result = '0'; else *result = 'x'; result++; } *result = '\0'; } static void bitnot(char *result,char *bits) { int length; char chr; length = strlen(bits); while( length-- ) { chr = *(bits++); *(result++) = ( chr=='1' ? '0' : ( chr=='0' ? '1' : chr ) ); } *result = '\0'; } static char bitcmp(char *bitstrm1, char *bitstrm2) { int i, l1, l2, ldiff; char stream[256]; char chr1, chr2; l1 = strlen(bitstrm1); l2 = strlen(bitstrm2); if (l1 < l2) { ldiff = l2 - l1; i=0; while( ldiff-- ) stream[i++] = '0'; while( l1-- ) stream[i++] = *(bitstrm1++); stream[i] = '\0'; bitstrm1 = stream; } else if (l2 < l1) { ldiff = l1 - l2; i=0; while( ldiff-- ) stream[i++] = '0'; while( l2-- ) stream[i++] = *(bitstrm2++); stream[i] = '\0'; bitstrm2 = stream; } while( (chr1 = *(bitstrm1++)) ) { chr2 = *(bitstrm2++); if ( ((chr1 == '0') && (chr2 == '1')) || ((chr1 == '1') && (chr2 == '0')) ) return( 0 ); } return( 1 ); } static char bnear(double x, double y, double tolerance) { if (fabs(x - y) < tolerance) return ( 1 ); else return ( 0 ); } static char saobox(double xcen, double ycen, double xwid, double ywid, double rot, double xcol, double ycol) { double x,y,xprime,yprime,xmin,xmax,ymin,ymax,theta; theta = (rot / 180.0) * myPI; xprime = xcol - xcen; yprime = ycol - ycen; x = xprime * cos(theta) + yprime * sin(theta); y = -xprime * sin(theta) + yprime * cos(theta); xmin = - 0.5 * xwid; xmax = 0.5 * xwid; ymin = - 0.5 * ywid; ymax = 0.5 * ywid; if ((x >= xmin) && (x <= xmax) && (y >= ymin) && (y <= ymax)) return ( 1 ); else return ( 0 ); } static char circle(double xcen, double ycen, double rad, double xcol, double ycol) { double r2,dx,dy,dlen; dx = xcol - xcen; dy = ycol - ycen; dx *= dx; dy *= dy; dlen = dx + dy; r2 = rad * rad; if (dlen <= r2) return ( 1 ); else return ( 0 ); } static char ellipse(double xcen, double ycen, double xrad, double yrad, double rot, double xcol, double ycol) { double x,y,xprime,yprime,dx,dy,dlen,theta; theta = (rot / 180.0) * myPI; xprime = xcol - xcen; yprime = ycol - ycen; x = xprime * cos(theta) + yprime * sin(theta); y = -xprime * sin(theta) + yprime * cos(theta); dx = x / xrad; dy = y / yrad; dx *= dx; dy *= dy; dlen = dx + dy; if (dlen <= 1.0) return ( 1 ); else return ( 0 ); } static void yyerror(char *s) { char msg[80]; if( !gParse.status ) gParse.status = PARSE_SYNTAX_ERR; strncpy(msg, s, 80); msg[79] = '\0'; ffpmsg(msg); } indi-0.5/src/cfitsio/compress.c0000644000175000017500000054007010610474374014353 0ustar jrjr#include "compress.h" local void error OF((char *m)); /* ====================================================================== This file contains source code that was copied and modified from the original gzip-1.2.4 program, which contained the following copyright and warranty notices: "gzip is free software, you can redistribute it and/or modify it under the terms of the GNU General Public License, a copy of which is provided below. The latest version of gzip are always available by ftp in prep.ai.mit.edu:/pub/gnu, or in any of the prep mirror sites." * gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface * Copyright (C) 1992-1993 Jean-loup Gailly * The unzip code was written and put in the public domain by Mark Adler. * Portions of the lzw code are derived from the public domain 'compress' * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies, * Ken Turkowski, Dave Mack and Peter Jannesen. * * See the license_msg below and the file COPYING for the software license. * See the file algorithm.doc for the compression algorithms and file formats. * unlzh.c -- decompress files in SCO compress -H (LZH) format. * The code in this file is directly derived from the public domain 'ar002' * written by Haruhiko Okumura. ---------- Beginning of GNU GENERAL PUBLIC LICENSE ---------------- GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS ------------- End of GNU GENERAL PUBLIC LICENSE ---------------- =========================================================================== */ /* global buffers */ static DECLARE(uch, inbuf, INBUFSIZ +INBUF_EXTRA); static DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA); static DECLARE(ush, d_buf, DIST_BUFSIZE); static DECLARE(uch, window, 2L*WSIZE); #ifndef MAXSEG_64K static DECLARE(ush, tab_prefix, 1L< 0) return(*status); /* save input parameters into global variables */ strcpy(ifname, filename); ifd = diskfile; memptr = (void **) buffptr; memsize = buffsize; realloc_fn = mem_realloc; in_memptr = NULL; /* signal that we are reading from file, not memory */ /* clear input and output buffers */ outcnt = 0; insize = inptr = 0; bytes_in = bytes_out = 0L; part_nb = 0; method = get_method(ifd); if (method < 0) { return(*status = 414); /* error message already emitted */ } /* Actually do the compression/decompression. Loop over zipped members. */ for (;;) { if ((*work)(ifd, ofd) != OK) { method = -1; /* force cleanup */ *status = 414; /* report some sort of decompression error */ break; } if (last_member || inptr == insize) break; /* end of file */ method = get_method(ifd); if (method < 0) break; /* error message already emitted */ bytes_out = 0; /* required for length check */ } /* *buffptr = *memptr; *buffsize = *memsize; */ *filesize = bytes_out; return(*status); } /*--------------------------------------------------------------------------*/ int uncompress2mem_from_mem( char *inmemptr, /* I - memory pointer to compressed bytes */ size_t inmemsize, /* I - size of input compressed file */ char **buffptr, /* IO - memory pointer */ size_t *buffsize, /* IO - size of buffer, in bytes */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ size_t *filesize, /* O - size of file, in bytes */ int *status) /* IO - error status */ /* Uncompress the file into memory. Fill whatever amount of memory has already been allocated, then realloc more memory, using the supplied input function, if necessary. */ { if (*status > 0) return(*status); /* save input parameters into global variables */ in_memptr = inmemptr; in_memsize = inmemsize; memptr = (void **) buffptr; memsize = buffsize; realloc_fn = mem_realloc; /* clear input and output buffers */ outcnt = 0; insize = inptr = 0; bytes_in = bytes_out = 0L; part_nb = 0; method = get_method(ifd); if (method < 0) { return(*status = 414); /* error message already emitted */ } /* Actually do the compression/decompression. Loop over zipped members. */ for (;;) { if ((*work)(ifd, ofd) != OK) { method = -1; /* force cleanup */ *status = 414; /* report some sort of decompression error */ break; } if (last_member || inptr == insize) break; /* end of file */ method = get_method(ifd); if (method < 0) break; /* error message already emitted */ bytes_out = 0; /* required for length check */ } /* *buffptr = *memptr; *buffsize = *memsize; */ *filesize = bytes_out; return(*status); } /*--------------------------------------------------------------------------*/ int uncompress2file(char *filename, /* name of input file */ FILE *indiskfile, /* I - input file pointer */ FILE *outdiskfile, /* I - output file pointer */ int *status) /* IO - error status */ /* Uncompress the file into file. */ { if (*status > 0) return(*status); /* save input parameters into global variables */ strcpy(ifname, filename); ifd = indiskfile; ofd = outdiskfile; realloc_fn = NULL; /* a null reallocation fn signals that the file is */ /* to be uncompressed to a file on disk, not memory */ in_memptr = NULL; /* signal that we are reading from file, not memory */ /* clear input and output buffers */ outcnt = 0; insize = inptr = 0; bytes_in = bytes_out = 0L; part_nb = 0; method = get_method(ifd); if (method < 0) { return(*status = 1); /* error message already emitted */ } /* Actually do the compression/decompression. Loop over zipped members. */ for (;;) { if ((*work)(ifd, ofd) != OK) { method = -1; /* force cleanup */ break; } if (last_member || inptr == insize) break; /* end of file */ method = get_method(ifd); if (method < 0) break; /* error message already emitted */ bytes_out = 0; /* required for length check */ } return(*status); } /*--------------------------------------------------------------------------*/ int compress2mem_from_mem( char *inmemptr, /* I - memory pointer to uncompressed bytes */ size_t inmemsize, /* I - size of input uncompressed file */ char **buffptr, /* IO - memory pointer for compressed file */ size_t *buffsize, /* IO - size of buffer, in bytes */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ size_t *filesize, /* O - size of file, in bytes */ int *status) /* IO - error status */ /* Compress the file into memory. Fill whatever amount of memory has already been allocated, then realloc more memory, using the supplied input function, if necessary. */ { uch flags = 0; /* general purpose bit flags */ ush attr = 0; /* ascii/binary flag */ ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ if (*status > 0) return(*status); /* save input parameters into global variables */ in_memptr = inmemptr; in_memsize = inmemsize; memptr = (void **) buffptr; memsize = buffsize; realloc_fn = mem_realloc; /* clear input and output buffers */ outcnt = 0; insize = inptr = 0; bytes_in = bytes_out = 0L; part_nb = 0; method = DEFLATED; /* write gzip header bytes */ put_byte(GZIP_MAGIC[0]); /* magic header */ put_byte(GZIP_MAGIC[1]); put_byte(DEFLATED); /* compression method */ put_byte(flags); /* just write zero as dummy value for the timestamp put_long(time_stamp); */ put_long(0); /* dummy time stamp */ /* Write deflated file to zip file */ crc_value = updcrc(0, 0); bi_init(NO_FILE); ct_init(&attr, &method); lm_init(level, &deflate_flags); put_byte((uch)deflate_flags); /* extra flags */ put_byte(0); /* OS identifier; 0 = default */ header_bytes = (long)outcnt; (void)deflate(); /* Write the crc and uncompressed size */ put_long(crc_value); put_long(isize); header_bytes += 2*sizeof(long); flush_outbuf(); *buffptr = *memptr; *buffsize = *memsize; *filesize = bytes_out; return(*status); } /*--------------------------------------------------------------------------*/ int compress2file_from_mem( char *inmemptr, /* I - memory pointer to uncompressed bytes */ size_t inmemsize, /* I - size of input uncompressed file */ FILE *outdiskfile, size_t *filesize, /* O - size of file, in bytes */ int *status) /* Compress the memory file into disk file. */ { uch flags = 0; /* general purpose bit flags */ ush attr = 0; /* ascii/binary flag */ ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ if (*status > 0) return(*status); /* save input parameters into global variables */ in_memptr = inmemptr; in_memsize = inmemsize; ofd = outdiskfile; realloc_fn = NULL; /* a null reallocation fn signals that the file is */ /* to be compressed to a file on disk, not memory */ /* clear input and output buffers */ outcnt = 0; insize = inptr = 0; bytes_in = bytes_out = 0L; part_nb = 0; method = DEFLATED; /* write gzip header bytes */ put_byte(GZIP_MAGIC[0]); /* magic header */ put_byte(GZIP_MAGIC[1]); put_byte(DEFLATED); /* compression method */ put_byte(flags); /* just write zero as dummy value for the timestamp put_long(time_stamp); */ put_long(0); /* dummy time stamp */ /* Write deflated file to zip file */ crc_value = updcrc(0, 0); bi_init(NO_FILE); ct_init(&attr, &method); lm_init(level, &deflate_flags); put_byte((uch)deflate_flags); /* extra flags */ put_byte(0); /* OS identifier; 0 = default */ header_bytes = (long)outcnt; (void)deflate(); /* Write the crc and uncompressed size */ put_long(crc_value); put_long(isize); header_bytes += 2*sizeof(long); flush_outbuf(); *filesize = bytes_out; return(*status); } /*--------------------------------------------------------------------------*/ /* ****************************** */ /* The following came from gzip.c */ /* ****************************** */ /* ======================================================================== * Check the magic number of the input file and update ofname if an * original name was given and to_stdout is not set. * Return the compression method, -1 for error, -2 for warning. * Set inptr to the offset of the next byte to be processed. * Updates time_stamp if there is one and --no-time is not used. * This function may be called repeatedly for an input file consisting * of several contiguous gzip'ed members. * IN assertions: there is at least one remaining compressed member. * If the member is a zip file, it must be the only one. */ local int get_method(in) FILE *in; /* input file descriptor */ { uch flags; /* compression flags */ char magic[2]; /* magic header */ magic[0] = (char)get_byte(); magic[1] = (char)get_byte(); method = -1; /* unknown yet */ part_nb++; /* number of parts in gzip file */ header_bytes = 0; last_member = RECORD_IO; /* assume multiple members in gzip file except for record oriented I/O */ if (memcmp(magic, GZIP_MAGIC, 2) == 0 || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) { method = (int)get_byte(); if (method != DEFLATED) { error("unknown compression method -- get newer version of gzip"); exit_code = ERROR; return -1; } work = unzip; flags = (uch)get_byte(); if ((flags & ENCRYPTED) != 0) { error("input file is encrypted -- get newer version of gzip"); exit_code = ERROR; return -1; } if ((flags & CONTINUATION) != 0) { error( "file is a a multi-part gzip file -- get newer version of gzip"); exit_code = ERROR; if (force <= 1) return -1; } if ((flags & RESERVED) != 0) { error("file has flags 0x%x -- get newer version of gzip"); exit_code = ERROR; if (force <= 1) return -1; } (void)get_byte(); /* Ignore time stamp */ (void)get_byte(); (void)get_byte(); (void)get_byte(); (void)get_byte(); /* Ignore extra flags for the moment */ (void)get_byte(); /* Ignore OS type for the moment */ if ((flags & CONTINUATION) != 0) { (void)get_byte(); (void)get_byte(); } if ((flags & EXTRA_FIELD) != 0) { unsigned len = (unsigned)get_byte(); len |= ((unsigned)get_byte())<<8; while (len--) (void)get_byte(); } /* Get original file name if it was truncated */ if ((flags & ORIG_NAME) != 0) { /* Discard the old name */ char c; /* dummy used for NeXTstep 3.0 cc optimizer bug */ do {c=get_byte();} while (c != 0); } /* ORIG_NAME */ /* Discard file comment if any */ if ((flags & COMMENT) != 0) { while (get_char() != 0) /* null */ ; } if (part_nb == 1) { header_bytes = inptr + 2*sizeof(long); /* include crc and size */ } } else if (memcmp(magic, PKZIP_MAGIC, 2) == 0 && inptr == 2 && memcmp((char*)inbuf, PKZIP_MAGIC, 4) == 0) { /* To simplify the code, we support a zip file when alone only. * We are thus guaranteed that the entire local header fits in inbuf. */ inptr = 0; work = unzip; if (check_zipfile(in) != OK) return -1; /* check_zipfile may get ofname from the local header */ last_member = 1; } else if (memcmp(magic, PACK_MAGIC, 2) == 0) { work = unpack; method = PACKED; } else if (memcmp(magic, LZW_MAGIC, 2) == 0) { work = unlzw; method = COMPRESSED; last_member = 1; } else if (memcmp(magic, LZH_MAGIC, 2) == 0) { work = unlzh; method = LZHED; last_member = 1; } if (method >= 0) return method; if (part_nb == 1) { error("file not in gzip format:"); exit_code = ERROR; return -1; } else { /* decompression OK, trailing garbage ignored */ return -2; } } /* ========================================================================*/ /* this marks the start of the code that was originally in the */ /* gzip source file called 'util.c' */ /* util.c -- utility functions for gzip support * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. */ extern ulg crc_32_tab[]; /* crc table, defined below */ /* =========================================================================== * Run a set of bytes through the crc shift register. If s is a NULL * pointer, then initialize the crc shift register contents instead. * Return the current crc in either case. */ local ulg updcrc(s, n) uch *s; /* pointer to bytes to pump through */ unsigned n; /* number of bytes in s[] */ { register ulg c; /* temporary variable */ static ulg crc = (ulg)0xffffffffL; /* shift register contents */ if (s == NULL) { c = 0xffffffffUL; } else { c = crc; if (n) do { c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); } while (--n); } crc = c; return c ^ 0xffffffffUL; /* (instead of ~c for 64-bit machines) */ } /* =========================================================================== * Fill the input buffer. This is called only when the buffer is empty. */ local int fill_inbuf(eof_ok) int eof_ok; /* set if EOF acceptable as a result */ { int len; if (in_memptr) { /* read from memory, not from a file */ if (in_memsize < INBUFSIZ) insize = in_memsize; else insize = INBUFSIZ; memcpy( (char*)inbuf, in_memptr, insize); in_memptr += insize; in_memsize -= insize; } else { /* Read as much as possible from file */ insize = 0; do { /* len = read(ifd, (char*)inbuf+insize, INBUFSIZ-insize); */ len = fread((char*)inbuf+insize, 1, INBUFSIZ-insize, ifd); if (len == 0 || len == EOF) break; insize += len; } while (insize < INBUFSIZ); } if (insize == 0) { if (eof_ok) return EOF; error("unexpected end of file"); exit_code = ERROR; return ERROR; } bytes_in += (ulg)insize; inptr = 1; return inbuf[0]; } /* =========================================================================== * Read a new buffer from the current input file, perform end-of-line * translation, and update the crc and input file size. * IN assertion: size >= 2 (for end-of-line translation) (this routine came from zip.c, and was modified to read and write from/to memory) */ int file_read(buf, size) char *buf; unsigned size; { unsigned len; Assert(insize == 0, "inbuf not empty"); len = in_memsize - isize; /* number of bytes left to compress */ if (size < len) len = size; /* only copy the requested number of bytes */ memcpy(buf, in_memptr + isize, len); /* len = read(ifd, buf, size); if (len == (unsigned)(-1) || len == 0) return (int)len; */ crc_value = updcrc((uch*)buf, len); isize += (ulg)len; return (int)len; } /* =========================================================================== * Write the output buffer outbuf[0..outcnt-1] and update bytes_out. * (used for the compressed data only) */ local void flush_outbuf() { if (outcnt == 0) return; write_buf((char *)outbuf, outcnt); bytes_out += (ulg)outcnt; outcnt = 0; } /* =========================================================================== * Write the output window window[0..outcnt-1] and update crc and bytes_out. * (Used for the decompressed data only.) */ local void flush_window() { if (exit_code != OK) return; if (outcnt == 0) return; updcrc(window, outcnt); write_buf((char *)window, outcnt); bytes_out += (ulg)outcnt; outcnt = 0; } /* =========================================================================== * copy buffer into memory; allocate more memory if required */ local void write_buf(buf, cnt) voidp buf; unsigned cnt; { if (!realloc_fn) { /* append buffer to file */ /* added 'unsigned' to get rid of compiler warning (WDP 1/1/99) */ if ((unsigned long) fwrite(buf, 1, cnt, ofd) != cnt) { error ("failed to write buffer to uncompressed output file (write_buf)"); exit_code = ERROR; return; } } else { /* copy/append buffer into memory */ /* get more memory if current buffer is too small */ if (bytes_out + cnt > *memsize) { *memptr = realloc_fn(*memptr, bytes_out + cnt); *memsize = bytes_out + cnt; /* new memory buffer size */ } if (!(*memptr)) { error("malloc failed while uncompressing (write_buf)"); exit_code = ERROR; return; } /* copy into memory buffer */ memcpy((char *) *memptr + bytes_out, (char *) buf, cnt); } } /* ======================================================================== * Error handlers. */ local void error(m) char *m; { ffpmsg(ifname); ffpmsg(m); } /* ======================================================================== * Table of CRC-32's of all single-byte values (made by makecrc.c) */ ulg crc_32_tab[] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL }; /* ******************************************** */ /* ** the following code came from unlzh.c **** */ /* ******************************************** */ #define DICBIT 13 /* 12(-lh4-) or 13(-lh5-) */ #define DICSIZ ((unsigned) 1 << DICBIT) #ifndef CHAR_BIT # define CHAR_BIT 8 #endif #ifndef UCHAR_MAX # define UCHAR_MAX 255 #endif #define BITBUFSIZ (CHAR_BIT * 2 * sizeof(char)) /* Do not use CHAR_BIT * sizeof(bitbuf), does not work on machines * for which short is not on 16 bits (Cray). */ /* encode.c and decode.c */ #define MAXMATCH 256 /* formerly F (not more than UCHAR_MAX + 1) */ #define THRESHOLD 3 /* choose optimal value */ /* huf.c */ #define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD) /* alphabet = {0, 1, 2, ..., NC - 1} */ #define CBIT 9 /* $\lfloor \log_2 NC \rfloor + 1$ */ #define CODE_BIT 16 /* codeword length */ #define NP (DICBIT + 1) #define NT (CODE_BIT + 3) #define PBIT 4 /* smallest integer such that (1U << PBIT) > NP */ #define TBIT 5 /* smallest integer such that (1U << TBIT) > NT */ #if NT > NP # define NPT NT #else # define NPT NP #endif /* local ush left[2 * NC - 1]; */ /* local ush right[2 * NC - 1]; */ #define left prev #define right head #if NC > (1<<(BITS-2)) error cannot overlay left+right and prev #endif /* local uch c_len[NC]; */ #define c_len outbuf #if NC > OUTBUFSIZ error cannot overlay c_len and outbuf #endif local uch pt_len[NPT]; local unsigned blocksize; local ush pt_table[256]; /* local ush c_table[4096]; */ #define c_table d_buf #if (DIST_BUFSIZE-1) < 4095 error cannot overlay c_table and d_buf #endif /*********************************************************** io.c -- input/output ***********************************************************/ local ush bitbuf; local unsigned subbitbuf; local int bitcount; local void fillbuf(n) /* Shift bitbuf n bits left, read n bits */ int n; { bitbuf <<= n; while (n > bitcount) { bitbuf |= subbitbuf << (n -= bitcount); subbitbuf = (unsigned)try_byte(); if ((int)subbitbuf == EOF) subbitbuf = 0; bitcount = CHAR_BIT; } bitbuf |= subbitbuf >> (bitcount -= n); } local unsigned getbits(n) int n; { unsigned x; x = bitbuf >> (BITBUFSIZ - n); fillbuf(n); return x; } local void init_getbits() { bitbuf = 0; subbitbuf = 0; bitcount = 0; fillbuf(BITBUFSIZ); } /*********************************************************** maketbl.c -- make table for decoding ***********************************************************/ local void make_table(nchar, bitlen, tablebits, table) int nchar; uch bitlen[]; int tablebits; ush table[]; { ush count[17], weight[17], start[18], *p; unsigned i, k, len, ch, jutbits, avail, nextcode, mask; for (i = 1; i <= 16; i++) count[i] = 0; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) for (i = 0; i < (unsigned)nchar; i++) count[bitlen[i]]++; */ for (i = 0; i < (unsigned)nchar; i++) { if (bitlen[i] > 16) error("Bad table (case a)\n"); else count[bitlen[i]]++; } start[1] = 0; for (i = 1; i <= 16; i++) start[i + 1] = start[i] + (count[i] << (16 - i)); /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) if ((start[17] & 0xffff) != 0) { error("Bad table\n"); */ if ((start[17] & 0xffff) != 0 || tablebits > 16) /* 16 for weight below */ { error("Bad table (case b)\n"); exit_code = ERROR; return; } jutbits = 16 - tablebits; for (i = 1; i <= (unsigned)tablebits; i++) { start[i] >>= jutbits; weight[i] = (unsigned) 1 << (tablebits - i); } while (i <= 16) { weight[i] = (unsigned) 1 << (16 - i); i++; } i = start[tablebits + 1] >> jutbits; if (i != 0) { /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) k = 1 << tablebits; while (i != k) table[i++] = 0; */ k = MINZIP(1 << tablebits, DIST_BUFSIZE); while (i < k) table[i++] = 0; } avail = nchar; mask = (unsigned) 1 << (15 - tablebits); for (ch = 0; ch < (unsigned)nchar; ch++) { if ((len = bitlen[ch]) == 0) continue; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) nextcode = start[len] + weight[len]; */ nextcode = MINZIP(start[len] + weight[len], DIST_BUFSIZE); if (len <= (unsigned)tablebits) { for (i = start[len]; i < nextcode; i++) table[i] = ch; } else { k = start[len]; p = &table[k >> jutbits]; i = len - tablebits; while (i != 0) { if (*p == 0) { right[avail] = left[avail] = 0; *p = avail++; } if (k & mask) p = &right[*p]; else p = &left[*p]; k <<= 1; i--; } *p = ch; } start[len] = nextcode; } } /*********************************************************** huf.c -- static Huffman ***********************************************************/ local void read_pt_len(nn, nbit, i_special) int nn; int nbit; int i_special; { int i, c, n; unsigned mask; n = getbits(nbit); if (n == 0) { c = getbits(nbit); for (i = 0; i < nn; i++) pt_len[i] = 0; for (i = 0; i < 256; i++) pt_table[i] = c; } else { i = 0; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) while (i < n) { */ while (i < MINZIP(n,NPT)) { c = bitbuf >> (BITBUFSIZ - 3); if (c == 7) { mask = (unsigned) 1 << (BITBUFSIZ - 1 - 3); while (mask & bitbuf) { mask >>= 1; c++; } } fillbuf((c < 7) ? 3 : c - 3); pt_len[i++] = c; if (i == i_special) { c = getbits(2); /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) while (--c >= 0) pt_len[i++] = 0; */ while (--c >= 0 && i < NPT) pt_len[i++] = 0; } } while (i < nn) pt_len[i++] = 0; make_table(nn, pt_len, 8, pt_table); } } local void read_c_len() { int i, c, n; unsigned mask; n = getbits(CBIT); if (n == 0) { c = getbits(CBIT); for (i = 0; i < NC; i++) c_len[i] = 0; for (i = 0; i < 4096; i++) c_table[i] = c; } else { i = 0; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) while (i < n) { */ while (i < MINZIP(n,NC)) { c = pt_table[bitbuf >> (BITBUFSIZ - 8)]; if (c >= NT) { mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8); do { if (bitbuf & mask) c = right[c]; else c = left [c]; mask >>= 1; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) } while (c >= NT); */ } while (c >= NT && (mask || c != left[c])); } fillbuf((int) pt_len[c]); if (c <= 2) { if (c == 0) c = 1; else if (c == 1) c = getbits(4) + 3; else c = getbits(CBIT) + 20; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) while (--c >= 0) c_len[i++] = 0; */ while (--c >= 0 && i < NC) c_len[i++] = 0; } else c_len[i++] = c - 2; } while (i < NC) c_len[i++] = 0; make_table(NC, c_len, 12, c_table); } } local unsigned decode_c() { unsigned j = 0, mask; if (blocksize == 0) { blocksize = getbits(16); if (blocksize == 0) { return NC; /* end of file */ } read_pt_len(NT, TBIT, 3); if (exit_code != OK) return j; read_c_len(); if (exit_code != OK) return j; read_pt_len(NP, PBIT, -1); if (exit_code != OK) return j; } blocksize--; j = c_table[bitbuf >> (BITBUFSIZ - 12)]; if (j >= NC) { mask = (unsigned) 1 << (BITBUFSIZ - 1 - 12); do { if (bitbuf & mask) j = right[j]; else j = left [j]; mask >>= 1; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) } while (j >= NC); */ } while (j >= NC && (mask || j != left[j])); } fillbuf((int) c_len[j]); return j; } local unsigned decode_p() { unsigned j, mask; j = pt_table[bitbuf >> (BITBUFSIZ - 8)]; if (j >= NP) { mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8); do { if (bitbuf & mask) j = right[j]; else j = left [j]; mask >>= 1; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) } while (j >= NP); */ } while (j >= NP && (mask || j != left[j])); } fillbuf((int) pt_len[j]); if (j != 0) j = ((unsigned) 1 << (j - 1)) + getbits((int) (j - 1)); return j; } local void huf_decode_start() { init_getbits(); blocksize = 0; } /*********************************************************** decode.c ***********************************************************/ /* changed 'j' to 'jj1' to avoid conflicts - WDP 1/1/99) */ local int jj1; /* remaining bytes to copy */ local int done; /* set at end of input */ local void decode_start() { huf_decode_start(); jj1 = 0; done = 0; } /* Decode the input and return the number of decoded bytes put in buffer */ local unsigned decode(count, buffer) unsigned count; uch buffer[]; /* The calling function must keep the number of bytes to be processed. This function decodes either 'count' bytes or 'DICSIZ' bytes, whichever is smaller, into the array 'buffer[]' of size 'DICSIZ' or more. Call decode_start() once for each new file before calling this function. */ { local unsigned i; unsigned r, c; r = 0; while (--jj1 >= 0) { buffer[r] = buffer[i]; i = (i + 1) & (DICSIZ - 1); /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) if (++r == count) return r; */ if (++r >= count) return r; } for ( ; ; ) { c = decode_c(); if (exit_code != OK) return r; if (c == NC) { done = 1; return r; } if (c <= UCHAR_MAX) { buffer[r] = c; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) if (++r == count) return r; */ if (++r >= count) return r; } else { jj1 = c - (UCHAR_MAX + 1 - THRESHOLD); i = (r - decode_p() - 1) & (DICSIZ - 1); while (--jj1 >= 0) { buffer[r] = buffer[i]; i = (i + 1) & (DICSIZ - 1); /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) if (++r == count) return r; */ if (++r >= count) return r; } } } } /* =========================================================================== * Unlzh in to out. Return OK or ERROR. */ local int unlzh(in, out) FILE *in; FILE *out; { unsigned n; ifd = in; ofd = out; decode_start(); while (!done) { n = decode((unsigned) DICSIZ, window); if (exit_code != OK) return ERROR; if (n > 0) { write_buf((char*)window, n); } } return OK; } /*=========================================================================*/ /* this marks the begining of the original file 'unlzw.c' */ /*=========================================================================*/ /* unlzw.c -- decompress files in LZW format. * The code in this file is directly derived from the public domain 'compress' * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies, * Ken Turkowski, Dave Mack and Peter Jannesen. * * This is a temporary version which will be rewritten in some future version * to accommodate in-memory decompression. */ typedef unsigned char char_type; typedef long code_int; typedef unsigned long count_int; typedef unsigned short count_short; typedef unsigned long cmp_code_int; #define MAXCODE(n) (1L << (n)) #ifndef REGISTERS # define REGISTERS 2 #endif #define REG1 #define REG2 #define REG3 #define REG4 #define REG5 #define REG6 #define REG7 #define REG8 #define REG9 #define REG10 #define REG11 #define REG12 #define REG13 #define REG14 #define REG15 #define REG16 #if REGISTERS >= 1 # undef REG1 # define REG1 register #endif #if REGISTERS >= 2 # undef REG2 # define REG2 register #endif #if REGISTERS >= 3 # undef REG3 # define REG3 register #endif #if REGISTERS >= 4 # undef REG4 # define REG4 register #endif #if REGISTERS >= 5 # undef REG5 # define REG5 register #endif #if REGISTERS >= 6 # undef REG6 # define REG6 register #endif #if REGISTERS >= 7 # undef REG7 # define REG7 register #endif #if REGISTERS >= 8 # undef REG8 # define REG8 register #endif #if REGISTERS >= 9 # undef REG9 # define REG9 register #endif #if REGISTERS >= 10 # undef REG10 # define REG10 register #endif #if REGISTERS >= 11 # undef REG11 # define REG11 register #endif #if REGISTERS >= 12 # undef REG12 # define REG12 register #endif #if REGISTERS >= 13 # undef REG13 # define REG13 register #endif #if REGISTERS >= 14 # undef REG14 # define REG14 register #endif #if REGISTERS >= 15 # undef REG15 # define REG15 register #endif #if REGISTERS >= 16 # undef REG16 # define REG16 register #endif #ifndef BYTEORDER # define BYTEORDER 0000 #endif #ifndef NOALLIGN # define NOALLIGN 0 #endif union bytes { long word; struct { #if BYTEORDER == 4321 char_type b1; char_type b2; char_type b3; char_type b4; #else #if BYTEORDER == 1234 char_type b4; char_type b3; char_type b2; char_type b1; #else # undef BYTEORDER int dummy; #endif #endif } bytes; }; #if BYTEORDER == 4321 && NOALLIGN == 1 # define input(b,o,c,n,m){ \ (c) = (*(long *)(&(b)[(o)>>3])>>((o)&0x7))&(m); \ (o) += (n); \ } #else # define input(b,o,c,n,m){ \ REG1 char_type *p = &(b)[(o)>>3]; \ (c) = ((((long)(p[0]))|((long)(p[1])<<8)| \ ((long)(p[2])<<16))>>((o)&0x7))&(m); \ (o) += (n); \ } #endif #ifndef MAXSEG_64K /* DECLARE(ush, tab_prefix, (1<>1] # define clear_tab_prefixof() \ memzero(tab_prefix0, 128), \ memzero(tab_prefix1, 128); #endif #define de_stack ((char_type *)(&d_buf[DIST_BUFSIZE-1])) #define tab_suffixof(i) tab_suffix[i] int block_mode = BLOCK_MODE; /* block compress mode -C compatible with 2.0 */ /* ============================================================================ * Decompress in to out. This routine adapts to the codes in the * file building the "string" table on-the-fly; requiring no table to * be stored in the compressed file. * IN assertions: the buffer inbuf contains already the beginning of * the compressed data, from offsets iptr to insize-1 included. * The magic header has already been checked and skipped. * bytes_in and bytes_out have been initialized. */ local int unlzw(in, out) FILE *in, *out; /* input and output file descriptors */ { REG2 char_type *stackp; REG3 code_int code; REG4 int finchar; REG5 code_int oldcode; REG6 code_int incode; REG7 long inbits; REG8 long posbits; REG9 int outpos; /* REG10 int insize; (global) */ REG11 unsigned bitmask; REG12 code_int free_ent; REG13 code_int maxcode; REG14 code_int maxmaxcode; REG15 int n_bits; REG16 int rsize; ofd = out; #ifdef MAXSEG_64K tab_prefix[0] = tab_prefix0; tab_prefix[1] = tab_prefix1; #endif maxbits = get_byte(); block_mode = maxbits & BLOCK_MODE; if ((maxbits & LZW_RESERVED) != 0) { error( "warning, unknown flags in unlzw decompression"); } maxbits &= BIT_MASK; maxmaxcode = MAXCODE(maxbits); if (maxbits > BITS) { error("compressed with too many bits; cannot handle file"); exit_code = ERROR; return ERROR; } rsize = insize; maxcode = MAXCODE(n_bits = INIT_BITS)-1; bitmask = (1<= 0 ; --code) { tab_suffixof(code) = (char_type)code; } do { REG1 int i; int e; int o; resetbuf: e = insize-(o = (posbits>>3)); for (i = 0 ; i < e ; ++i) { inbuf[i] = inbuf[i+o]; } insize = e; posbits = 0; if (insize < INBUF_EXTRA) { /* modified to use fread instead of read - WDP 10/22/97 */ /* if ((rsize = read(in, (char*)inbuf+insize, INBUFSIZ)) == EOF) { */ if ((rsize = fread((char*)inbuf+insize, 1, INBUFSIZ, in)) == EOF) { error("unexpected end of file"); exit_code = ERROR; return ERROR; } insize += rsize; bytes_in += (ulg)rsize; } inbits = ((rsize != 0) ? ((long)insize - insize%n_bits)<<3 : ((long)insize<<3)-(n_bits-1)); while (inbits > posbits) { if (free_ent > maxcode) { posbits = ((posbits-1) + ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3))); ++n_bits; if (n_bits == maxbits) { maxcode = maxmaxcode; } else { maxcode = MAXCODE(n_bits)-1; } bitmask = (1<= 256) { error("corrupt input."); exit_code = ERROR; return ERROR; } outbuf[outpos++] = (char_type)(finchar = (int)(oldcode=code)); continue; } if (code == CLEAR && block_mode) { clear_tab_prefixof(); free_ent = FIRST - 1; posbits = ((posbits-1) + ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3))); maxcode = MAXCODE(n_bits = INIT_BITS)-1; bitmask = (1<= free_ent) { /* Special case for KwKwK string. */ if (code > free_ent) { if (outpos > 0) { write_buf((char*)outbuf, outpos); bytes_out += (ulg)outpos; } error("corrupt input."); exit_code = ERROR; return ERROR; } *--stackp = (char_type)finchar; code = oldcode; } while ((cmp_code_int)code >= (cmp_code_int)256) { /* Generate output characters in reverse order */ *--stackp = tab_suffixof(code); code = tab_prefixof(code); } *--stackp = (char_type)(finchar = tab_suffixof(code)); /* And put them out in forward order */ { /* REG1 int i; already defined above (WDP) */ if (outpos+(i = (de_stack-stackp)) >= OUTBUFSIZ) { do { if (i > OUTBUFSIZ-outpos) i = OUTBUFSIZ-outpos; if (i > 0) { memcpy(outbuf+outpos, stackp, i); outpos += i; } if (outpos >= OUTBUFSIZ) { write_buf((char*)outbuf, outpos); bytes_out += (ulg)outpos; outpos = 0; } stackp+= i; } while ((i = (de_stack-stackp)) > 0); } else { memcpy(outbuf+outpos, stackp, i); outpos += i; } } if ((code = free_ent) < maxmaxcode) { /* Generate the new entry. */ tab_prefixof(code) = (unsigned short)oldcode; tab_suffixof(code) = (char_type)finchar; free_ent = code+1; } oldcode = incode; /* Remember previous code. */ } } while (rsize != 0); if (outpos > 0) { write_buf((char*)outbuf, outpos); bytes_out += (ulg)outpos; } return OK; } /*=========================================================================*/ /* This marks the beginning of the original file 'unpack.c' */ /*=========================================================================*/ /* unpack.c -- decompress files in pack format. * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. */ #define MIN(a,b) ((a) <= (b) ? (a) : (b)) /* The arguments must not have side effects. */ #define MAX_BITLEN 25 /* Maximum length of Huffman codes. (Minor modifications to the code * would be needed to support 32 bits codes, but pack never generates * more than 24 bits anyway.) */ #define LITERALS 256 /* Number of literals, excluding the End of Block (EOB) code */ #define MAX_PEEK 12 /* Maximum number of 'peek' bits used to optimize traversal of the * Huffman tree. */ local ulg orig_len; /* original uncompressed length */ local int max_len; /* maximum bit length of Huffman codes */ local uch literal[LITERALS]; /* The literal bytes present in the Huffman tree. The EOB code is not * represented. */ local int lit_base[MAX_BITLEN+1]; /* All literals of a given bit length are contiguous in literal[] and * have contiguous codes. literal[code+lit_base[len]] is the literal * for a code of len bits. */ local int leaves [MAX_BITLEN+1]; /* Number of leaves for each bit length */ local int parents[MAX_BITLEN+1]; /* Number of parents for each bit length */ local int peek_bits; /* Number of peek bits currently used */ /* local uch prefix_len[1 << MAX_PEEK]; */ #define prefix_len outbuf /* For each bit pattern b of peek_bits bits, prefix_len[b] is the length * of the Huffman code starting with a prefix of b (upper bits), or 0 * if all codes of prefix b have more than peek_bits bits. It is not * necessary to have a huge table (large MAX_PEEK) because most of the * codes encountered in the input stream are short codes (by construction). * So for most codes a single lookup will be necessary. */ #if (1< OUTBUFSIZ error cannot overlay prefix_len and outbuf #endif local ulg bitbufulg; /* Bits are added on the low part of bitbufulg and read from the high part. */ local int valid; /* number of valid bits in bitbufulg */ /* all bits above the last valid bit are always zero */ /* Set code to the next 'bits' input bits without skipping them. code * must be the name of a simple variable and bits must not have side effects. * IN assertions: bits <= 25 (so that we still have room for an extra byte * when valid is only 24), and mask = (1<> (valid-(bits))) & (mask); \ } /* Skip the given number of bits (after having peeked at them): */ #define skip_bits(bits) (valid -= (bits)) #define clear_bitbuf() (valid = 0, bitbufulg = 0) /* =========================================================================== * Read the Huffman tree. */ local void read_tree() { int len; /* bit length */ int base; /* base offset for a sequence of leaves */ int n; /* Read the original input size, MSB first */ orig_len = 0; for (n = 1; n <= 4; n++) orig_len = (orig_len << 8) | (ulg)get_byte(); max_len = (int)get_byte(); /* maximum bit length of Huffman codes */ if (max_len > MAX_BITLEN) { error("invalid compressed data -- Huffman code > 32 bits"); } /* Get the number of leaves at each bit length */ n = 0; for (len = 1; len <= max_len; len++) { leaves[len] = (int)get_byte(); n += leaves[len]; } if (n > LITERALS) { error("too many leaves in Huffman tree"); } Trace((stderr, "orig_len %ld, max_len %d, leaves %d\n", orig_len, max_len, n)); /* There are at least 2 and at most 256 leaves of length max_len. * (Pack arbitrarily rejects empty files and files consisting of * a single byte even repeated.) To fit the last leaf count in a * byte, it is offset by 2. However, the last literal is the EOB * code, and is not transmitted explicitly in the tree, so we must * adjust here by one only. */ leaves[max_len]++; /* Now read the leaves themselves */ base = 0; for (len = 1; len <= max_len; len++) { /* Remember where the literals of this length start in literal[] : */ lit_base[len] = base; /* And read the literals: */ /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) for (n = leaves[len]; n > 0; n--) { */ for (n = leaves[len]; n > 0 && base < LITERALS; n--) { literal[base++] = (uch)get_byte(); } } leaves[max_len]++; /* Now include the EOB code in the Huffman tree */ } /* =========================================================================== * Build the Huffman tree and the prefix table. */ local void build_tree_unpack() { int nodes = 0; /* number of nodes (parents+leaves) at current bit length */ int len; /* current bit length */ uch *prefixp; /* pointer in prefix_len */ for (len = max_len; len >= 1; len--) { /* The number of parent nodes at this level is half the total * number of nodes at parent level: */ nodes >>= 1; parents[len] = nodes; /* Update lit_base by the appropriate bias to skip the parent nodes * (which are not represented in the literal array): */ lit_base[len] -= nodes; /* Restore nodes to be parents+leaves: */ nodes += leaves[len]; } /* Construct the prefix table, from shortest leaves to longest ones. * The shortest code is all ones, so we start at the end of the table. */ peek_bits = MIN(max_len, MAX_PEEK); prefixp = &prefix_len[1< prefix_len) *--prefixp = (uch)len; } /* The length of all other codes is unknown: */ while (prefixp > prefix_len) *--prefixp = 0; } /* =========================================================================== * Unpack in to out. This routine does not support the old pack format * with magic header \037\037. * * IN assertions: the buffer inbuf contains already the beginning of * the compressed data, from offsets inptr to insize-1 included. * The magic header has already been checked. The output buffer is cleared. */ local int unpack(in, out) FILE *in, *out; /* input and output file descriptors */ { int len; /* Bit length of current code */ unsigned eob; /* End Of Block code */ register unsigned peek; /* lookahead bits */ unsigned peek_mask; /* Mask for peek_bits bits */ ifd = in; ofd = out; read_tree(); /* Read the Huffman tree */ build_tree_unpack(); /* Build the prefix table */ clear_bitbuf(); /* Initialize bit input */ peek_mask = (1< 0) { peek >>= peek_bits - len; /* discard the extra bits */ } else { /* Code of more than peek_bits bits, we must traverse the tree */ ulg mask = peek_mask; len = peek_bits; do { len++, mask = (mask<<1)+1; look_bits(peek, len, mask); } while (peek < (unsigned)parents[len]); /* loop as long as peek is a parent node */ } /* At this point, peek is the next complete code, of len bits */ if (peek == eob && len == max_len) break; /* end of file? */ put_ubyte(literal[peek+lit_base[len]]); Tracev((stderr,"%02d %04x %c\n", len, peek, literal[peek+lit_base[len]])); skip_bits(len); } /* for (;;) */ flush_window(); Trace((stderr, "bytes_out %ld\n", bytes_out)); if (orig_len != (ulg)bytes_out) { error("invalid compressed data--length error"); return ERROR; } return OK; } /*=======================================================================*/ /* This marks the beginning of the original file 'unzip.c' */ /*=======================================================================*/ /* unzip.c -- decompress files in gzip or pkzip format. * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. * * The code in this file is derived from the file funzip.c written * and put in the public domain by Mark Adler. */ /* This version can extract files in gzip or pkzip format. For the latter, only the first entry is extracted, and it has to be either deflated or stored. */ /* PKZIP header definitions */ #define LOCSIG 0x04034b50L /* four-byte lead-in (lsb first) */ #define LOCFLG 6 /* offset of bit flag */ #define CRPFLG 1 /* bit for encrypted entry */ #define EXTFLG 8 /* bit for extended local header */ #define LOCHOW 8 /* offset of compression method */ #define LOCTIM 10 /* file mod time (for decryption) */ #define LOCCRC 14 /* offset of crc */ #define LOCSIZ 18 /* offset of compressed size */ #define LOCLEN 22 /* offset of uncompressed length */ #define LOCFIL 26 /* offset of file name field length */ #define LOCEXT 28 /* offset of extra field length */ #define LOCHDR 30 /* size of local header, including sig */ #define EXTHDR 16 /* size of extended local header, inc sig */ /* Globals */ /* added 'static' to the following 4 lines - WDP (1/1/99) */ static int decrypt; /* flag to turn on decryption */ /* static char *key; */ /* not used--needed to link crypt.c */ static int pkzip = 0; /* set for a pkzip file */ static int ext_header = 0; /* set if extended local header */ /* =========================================================================== * Check zip file and advance inptr to the start of the compressed data. * Get ofname from the local header if necessary. */ local int check_zipfile(in) FILE *in; /* input file descriptors */ { uch *h = inbuf + inptr; /* first local header */ ifd = in; /* Check validity of local header, and skip name and extra fields */ inptr += LOCHDR + SH(h + LOCFIL) + SH(h + LOCEXT); if (inptr > insize || LG(h) != LOCSIG) { error("not a valid zip file"); exit_code = ERROR; return ERROR; } method = h[LOCHOW]; if (method != STORED && method != DEFLATED) { error("first entry not deflated or stored -- use unzip"); exit_code = ERROR; return ERROR; } /* If entry encrypted, decrypt and validate encryption header */ if ((decrypt = h[LOCFLG] & CRPFLG) != 0) { error("encrypted file -- use unzip"); exit_code = ERROR; return ERROR; } /* Save flags for unzip() */ ext_header = (h[LOCFLG] & EXTFLG) != 0; pkzip = 1; /* Get ofname and time stamp from local header (to be done) */ return OK; } /* =========================================================================== * Unzip in to out. This routine works on both gzip and pkzip files. * * IN assertions: the buffer inbuf contains already the beginning of * the compressed data, from offsets inptr to insize-1 included. * The magic header has already been checked. The output buffer is cleared. */ local int unzip(in, out) FILE *in, *out; /* input and output file descriptors */ { ulg orig_crc = 0; /* original crc */ /* orig_len has already been defined statically before */ /* ulg orig_len = 0; */ /* original uncompressed length */ int n; uch buf[EXTHDR]; /* extended local header */ ifd = in; ofd = out; updcrc(NULL, 0); /* initialize crc */ if (pkzip && !ext_header) { /* crc and length at the end otherwise */ orig_crc = LG(inbuf + LOCCRC); orig_len = LG(inbuf + LOCLEN); } /* Decompress */ if (method == DEFLATED) { int res = inflate(); if (res == 3) { error("out of memory"); return ERROR; } else if (res != 0) { error("invalid compressed data--format violated"); return ERROR; } } else if (pkzip && method == STORED) { /* 'nn' here was originally declared 'n' which conflicts with the */ /* previous local declaration of 'n'. It was changed to 'nn' on 1/4/99 */ register ulg nn = LG(inbuf + LOCLEN); if (nn != LG(inbuf + LOCSIZ) - (decrypt ? 12 : 0)) { error("invalid compressed data--length mismatch"); return ERROR; } while (nn--) { uch c = (uch)get_byte(); #ifdef CRYPT if (decrypt) zdecode(c); #endif put_ubyte(c); } flush_window(); } else { error("internal error, invalid method"); return ERROR; } /* Get the crc and original length */ if (!pkzip) { /* crc32 (see algorithm.doc) * uncompressed input size modulo 2^32 */ for (n = 0; n < 8; n++) { buf[n] = (uch)get_byte(); /* may cause an error if EOF */ } orig_crc = LG(buf); orig_len = LG(buf+4); } else if (ext_header) { /* If extended header, check it */ /* signature - 4bytes: 0x50 0x4b 0x07 0x08 * CRC-32 value * compressed size 4-bytes * uncompressed size 4-bytes */ for (n = 0; n < EXTHDR; n++) { buf[n] = (uch)get_byte(); /* may cause an error if EOF */ } orig_crc = LG(buf+4); orig_len = LG(buf+12); } /* Validate decompression */ if (orig_crc != updcrc(outbuf, 0)) { error("invalid compressed data--crc error"); return ERROR; } if (orig_len != (ulg)bytes_out) { error("invalid compressed data--length error"); return ERROR; } /* Check if there are more entries in a pkzip file */ if (pkzip && inptr + 4 < insize && LG(inbuf+inptr) == LOCSIG) { /* Don't destroy the input zip file */ error("file has more than one entry -- unchanged"); exit_code = ERROR; ext_header = pkzip = 0; return ERROR; } ext_header = pkzip = 0; /* for next file */ return OK; } /*======================================================================*/ /* This marks the start of the code originally in the file 'inflate.c' */ /*======================================================================*/ /* inflate.c -- Not copyrighted 1992 by Mark Adler version c10p1, 10 January 1993 */ /* You can do whatever you like with this source file, though I would prefer that if you modify it and redistribute it that you include comments to that effect with your name and the date. Thank you. [The history has been moved to the file ChangeLog.] */ /* Inflate deflated (PKZIP's method 8 compressed) data. The compression method searches for as much of the current string of bytes (up to a length of 258) in the previous 32K bytes. If it doesn't find any matches (of at least length 3), it codes the next byte. Otherwise, it codes the length of the matched string and its distance backwards from the current position. There is a single Huffman code that codes both single bytes (called "literals") and match lengths. A second Huffman code codes the distance information, which follows a length code. Each length or distance code actually represents a base value and a number of "extra" (sometimes zero) bits to get to add to the base value. At the end of each deflated block is a special end-of-block (EOB) literal/ length code. The decoding process is basically: get a literal/length code; if EOB then done; if a literal, emit the decoded byte; if a length then get the distance and emit the referred-to bytes from the sliding window of previously emitted data. There are (currently) three kinds of inflate blocks: stored, fixed, and dynamic. The compressor deals with some chunk of data at a time, and decides which method to use on a chunk-by-chunk basis. A chunk might typically be 32K or 64K. If the chunk is uncompressible, then the "stored" method is used. In this case, the bytes are simply stored as is, eight bits per byte, with none of the above coding. The bytes are preceded by a count, since there is no longer an EOB code. If the data is compressible, then either the fixed or dynamic methods are used. In the dynamic method, the compressed data is preceded by an encoding of the literal/length and distance Huffman codes that are to be used to decode this block. The representation is itself Huffman coded, and so is preceded by a description of that code. These code descriptions take up a little space, and so for small blocks, there is a predefined set of codes, called the fixed codes. The fixed method is used if the block codes up smaller that way (usually for quite small chunks), otherwise the dynamic method is used. In the latter case, the codes are customized to the probabilities in the current block, and so can code it much better than the pre-determined fixed codes. The Huffman codes themselves are decoded using a mutli-level table lookup, in order to maximize the speed of decoding plus the speed of building the decoding tables. See the comments below that precede the lbits and dbits tuning parameters. */ #define slide window /* Huffman code lookup table entry--this entry is four bytes for machines that have 16-bit pointers (e.g. PC's in the small or medium model). Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 means that v is a literal, 16 < e < 32 means that v is a pointer to the next table, which codes e - 16 bits, and lastly e == 99 indicates an unused code. If a code with e == 99 is looked up, this implies an error in the data. */ /* The inflate algorithm uses a sliding 32K byte window on the uncompressed stream to find repeated byte strings. This is implemented here as a circular buffer. The index is updated simply by incrementing and then and'ing with 0x7fff (32K-1). */ /* It is left to other modules to supply the 32K area. It is assumed to be usable as if it were declared "uch slide[32768];" or as just "uch *slide;" and then malloc'ed in the latter case. The definition must be in unzip.h, included above. */ /* unsigned wp; current position in slide */ #define wp outcnt #define flush_output(w) (wp=(w),flush_window()) /* Tables for deflate from PKZIP's appnote.txt. */ static unsigned border[] = { /* Order of the bit length code lengths */ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; static ush cplens[] = { /* Copy lengths for literal codes 257..285 */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; /* note: see note #13 above about the 258 in this list. */ static ush cplext[] = { /* Extra bits for literal codes 257..285 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ static ush cpdist[] = { /* Copy offsets for distance codes 0..29 */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; static ush cpdext[] = { /* Extra bits for distance codes */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; /* Macros for inflate() bit peeking and grabbing. The usage is: NEEDBITS(j) x = b & mask_bits[j]; DUMPBITS(j) where NEEDBITS makes sure that b has at least j bits in it, and DUMPBITS removes the bits from b. The macros use the variable k for the number of bits in b. Normally, b and k are register variables for speed, and are initialized at the beginning of a routine that uses these macros from a global bit buffer and count. If we assume that EOB will be the longest code, then we will never ask for bits with NEEDBITS that are beyond the end of the stream. So, NEEDBITS should not read any more bytes than are needed to meet the request. Then no bytes need to be "returned" to the buffer at the end of the last block. However, this assumption is not true for fixed blocks--the EOB code is 7 bits, but the other literal/length codes can be 8 or 9 bits. (The EOB code is shorter than other codes because fixed blocks are generally short. So, while a block always has an EOB, many other literal/length codes have a significantly lower probability of showing up at all.) However, by making the first table have a lookup of seven bits, the EOB code will be found in that first lookup, and so will not require that too many bits be pulled from the stream. */ static ulg bb; /* bit buffer */ static unsigned bk; /* bits in bit buffer */ static ush mask_bits[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff }; #ifdef CRYPT uch cc; # define NEXTBYTE() \ (decrypt ? (cc = get_byte(), zdecode(cc), cc) : get_byte()) #else # define NEXTBYTE() (uch)get_byte() #endif #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<>=(n);k-=(n);} /* Huffman code decoding is performed using a multi-level table lookup. The fastest way to decode is to simply build a lookup table whose size is determined by the longest code. However, the time it takes to build this table can also be a factor if the data being decoded is not very long. The most common codes are necessarily the shortest codes, so those codes dominate the decoding time, and hence the speed. The idea is you can have a shorter table that decodes the shorter, more probable codes, and then point to subsidiary tables for the longer codes. The time it costs to decode the longer codes is then traded against the time it takes to make longer tables. This results of this trade are in the variables lbits and dbits below. lbits is the number of bits the first level table for literal/ length codes can decode in one step, and dbits is the same thing for the distance codes. Subsequent tables are also less than or equal to those sizes. These values may be adjusted either when all of the codes are shorter than that, in which case the longest code length in bits is used, or when the shortest code is *longer* than the requested table size, in which case the length of the shortest code in bits is used. There are two different values for the two tables, since they code a different number of possibilities each. The literal/length table codes 286 possible values, or in a flat code, a little over eight bits. The distance table codes 30 possible values, or a little less than five bits, flat. The optimum values for speed end up being about one bit more than those, so lbits is 8+1 and dbits is 5+1. The optimum values may differ though from machine to machine, and possibly even between compilers. Your mileage may vary. */ static int lbits = 9; /* bits in base literal/length lookup table */ static int dbits = 6; /* bits in base distance lookup table */ /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ #define BMAX 16 /* maximum bit length of any code (16 for explode) */ #define N_MAX 288 /* maximum number of codes in any set */ static unsigned hufts; /* track memory usage */ local int huft_build(b, n, s, d, e, t, m) unsigned *b; /* code lengths in bits (all assumed <= BMAX) */ unsigned n; /* number of codes (assumed <= N_MAX) */ unsigned s; /* number of simple-valued codes (0..s-1) */ ush *d; /* list of base values for non-simple codes */ ush *e; /* list of extra bits for non-simple codes */ struct huft **t; /* result: starting table */ int *m; /* maximum lookup bits, returns actual */ /* Given a list of code lengths and a maximum table size, make a set of tables to decode that set of codes. Return zero on success, one if the given code set is incomplete (the tables are still built in this case), two if the input is invalid (all zero length codes or an oversubscribed set of lengths), and three if not enough memory. */ { unsigned a; /* counter for codes of length k */ unsigned c[BMAX+1]; /* bit length count table */ unsigned f; /* i repeats in table every f entries */ int g; /* maximum code length */ int h; /* table level */ register unsigned i; /* counter, current code */ register unsigned j; /* counter */ register int k; /* number of bits in current code */ int l; /* bits per table (returned in m) */ register unsigned *p; /* pointer into c[], b[], or v[] */ register struct huft *q; /* points to current table */ struct huft r; /* table entry for structure assignment */ struct huft *u[BMAX]; /* table stack */ unsigned v[N_MAX]; /* values in order of bit length */ register int w; /* bits before this table == (l * h) */ unsigned x[BMAX+1]; /* bit offsets, then code stack */ unsigned *xp; /* pointer into x */ int y; /* number of dummy codes added */ unsigned z; /* number of entries in current table */ /* Generate counts for each bit length */ memzero(c, sizeof(c)); p = b; i = n; do { Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), n-i, *p)); c[*p]++; /* assume all entries <= BMAX */ p++; /* Can't combine with above line (Solaris bug) */ } while (--i); if (c[0] == n) /* null input--all zero length codes */ { *t = (struct huft *)NULL; *m = 0; /* FreeBSD-SA-06:21.gzip security patch; applied 22-09-2006 (WDP) return 0; */ return 2; } /* Find minimum and maximum length, bound *m by those */ l = *m; for (j = 1; j <= BMAX; j++) if (c[j]) break; k = j; /* minimum code length */ if ((unsigned)l < j) l = j; for (i = BMAX; i; i--) if (c[i]) break; g = i; /* maximum code length */ if ((unsigned)l > i) l = i; *m = l; /* Adjust last length count to fill out codes, if needed */ for (y = 1 << j; j < i; j++, y <<= 1) if ((y -= c[j]) < 0) return 2; /* bad input: more codes than bits */ if ((y -= c[i]) < 0) return 2; c[i] += y; /* Generate starting offsets into the value table for each length */ x[1] = j = 0; p = c + 1; xp = x + 2; while (--i) { /* note that i == g from above */ *xp++ = (j += *p++); } /* Make a table of values in order of bit lengths */ p = b; i = 0; do { if ((j = *p++) != 0) v[x[j]++] = i; } while (++i < n); /* Generate the Huffman codes and for each, make the table entries */ x[0] = i = 0; /* first Huffman code is zero */ p = v; /* grab values in bit order */ h = -1; /* no tables yet--level -1 */ w = -l; /* bits decoded == (l * h) */ u[0] = (struct huft *)NULL; /* just to keep compilers happy */ q = (struct huft *)NULL; /* ditto */ z = 0; /* ditto */ /* go through the bit lengths (k already is bits in shortest code) */ for (; k <= g; k++) { a = c[k]; while (a--) { /* here i is the Huffman code of length k bits for value *p */ /* make tables up to required level */ while (k > w + l) { h++; w += l; /* previous table always l bits */ /* compute minimum size table less than or equal to l bits */ z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ { /* too few codes for k-w bit table */ f -= a + 1; /* deduct codes from patterns left */ xp = c + k; while (++j < z) /* try smaller tables up to z bits */ { if ((f <<= 1) <= *++xp) break; /* enough codes to use up j bits */ f -= *xp; /* else deduct codes from patterns */ } } z = 1 << j; /* table entries for j-bit table */ /* allocate and link in new table */ if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) == (struct huft *)NULL) { if (h) huft_free(u[0]); return 3; /* not enough memory */ } hufts += z + 1; /* track memory usage */ *t = q + 1; /* link to list for huft_free() */ *(t = &(q->v.t)) = (struct huft *)NULL; u[h] = ++q; /* table starts after link */ /* connect to last table, if there is one */ if (h) { x[h] = i; /* save pattern for backing up */ r.b = (uch)l; /* bits to dump before this table */ r.e = (uch)(16 + j); /* bits in this table */ r.v.t = q; /* pointer to this table */ j = i >> (w - l); /* (get around Turbo C bug) */ u[h-1][j] = r; /* connect to last table */ } } /* set up table entry in r */ r.b = (uch)(k - w); if (p >= v + n) { r.e = 99; /* out of values--invalid code */ } else if (*p < s) { r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ r.v.n = (ush)(*p); /* simple code is just the value */ p++; /* one compiler does not like *p++ */ } else { /* WDP added this to prevent seg fault reading a particular currupted .gz file */ if (*p > 1000000)return 4; r.e = (uch)e[*p - s]; /* non-simple--look up in lists */ r.v.n = d[*p++ - s]; } /* fill code-like entries with r */ f = 1 << (k - w); for (j = i >> w; j < z; j += f) q[j] = r; /* backwards increment the k-bit code i */ for (j = 1 << (k - 1); i & j; j >>= 1) i ^= j; i ^= j; /* backup over finished tables */ while ((i & ((1 << w) - 1)) != x[h]) { h--; /* don't need to update q */ w -= l; } } } /* Return true (1) if we were given an incomplete table */ return y != 0 && g != 1; } local int huft_free(t) struct huft *t; /* table to free */ /* Free the malloc'ed tables built by huft_build(), which makes a linked list of the tables it made, with the links in a dummy first entry of each table. */ { register struct huft *p, *q; /* Go through linked list, freeing from the malloced (t[-1]) address. */ p = t; while (p != (struct huft *)NULL) { q = (--p)->v.t; free((char*)p); p = q; } return 0; } local int inflate_codes(tl, td, bl, bd) struct huft *tl, *td; /* literal/length and distance decoder tables */ int bl, bd; /* number of bits decoded by tl[] and td[] */ /* inflate (decompress) the codes in a deflated (compressed) block. Return an error code or zero if it all goes ok. */ { register unsigned e; /* table entry flag/number of extra bits */ unsigned n, d; /* length and index for copy */ unsigned w; /* current window position */ struct huft *t; /* pointer to table entry */ unsigned ml, md; /* masks for bl and bd bits */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ register int nloop = 0; /* make local copies of globals */ b = bb; /* initialize bit buffer */ k = bk; w = wp; /* initialize window position */ /* inflate the coded data */ ml = mask_bits[bl]; /* precompute masks for speed */ md = mask_bits[bd]; for (;;) /* do until end of block */ { /* The NEEDBITS macro (which calls NEXTBYTE, which calls get_byte, which finally calls fill_inbuf) has no way to return an error in the case of unexpected EOF. The original gunzip program simply exits in this case, but that is not acceptable for CFITSIO. Therefore, we will check how many times this loop is executed and if it looks like it is in an infinite loop then we will return with an error. WDP - Nov 1999. */ nloop++; if (nloop > 500000) { error("'inflate_codes' is in infinite loop; corrupt compressed file??"); return(1); } NEEDBITS((unsigned)bl) if ((e = (t = tl + ((unsigned)b & ml))->e) > 16) do { if (e == 99) return 1; DUMPBITS(t->b) e -= 16; NEEDBITS(e) } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); DUMPBITS(t->b) if (e == 16) /* then it's a literal */ { slide[w++] = (uch)t->v.n; Tracevv((stderr, "%c", slide[w-1])); if (w == WSIZE) { flush_output(w); w = 0; } } else /* it's an EOB or a length */ { /* exit if end of block */ if (e == 15) break; /* get length of block to copy */ NEEDBITS(e) n = t->v.n + ((unsigned)b & mask_bits[e]); DUMPBITS(e); /* decode distance of block to copy */ NEEDBITS((unsigned)bd) if ((e = (t = td + ((unsigned)b & md))->e) > 16) do { if (e == 99) return 1; DUMPBITS(t->b) e -= 16; NEEDBITS(e) } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); DUMPBITS(t->b) NEEDBITS(e) d = w - t->v.n - ((unsigned)b & mask_bits[e]); DUMPBITS(e) Tracevv((stderr,"\\[%d,%d]", w-d, n)); /* do the copy */ do { n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); #if !defined(NOMEMCPY) && !defined(DEBUG) if (w - d >= e) /* (this test assumes unsigned comparison) */ { memcpy(slide + w, slide + d, e); w += e; d += e; } else /* do it slow to avoid memcpy() overlap */ #endif /* !NOMEMCPY */ do { slide[w++] = slide[d++]; Tracevv((stderr, "%c", slide[w-1])); } while (--e); if (w == WSIZE) { flush_output(w); w = 0; } } while (n); } } /* restore the globals from the locals */ wp = w; /* restore global window pointer */ bb = b; /* restore global bit buffer */ bk = k; /* done */ return 0; } local int inflate_stored() /* "decompress" an inflated type 0 (stored) block. */ { unsigned n; /* number of bytes in block */ unsigned w; /* current window position */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ /* make local copies of globals */ b = bb; /* initialize bit buffer */ k = bk; w = wp; /* initialize window position */ /* go to byte boundary */ n = k & 7; DUMPBITS(n); /* get the length and its complement */ NEEDBITS(16) n = ((unsigned)b & 0xffff); DUMPBITS(16) NEEDBITS(16) if (n != (unsigned)((~b) & 0xffff)) return 1; /* error in compressed data */ DUMPBITS(16) /* read and output the compressed data */ while (n--) { NEEDBITS(8) slide[w++] = (uch)b; if (w == WSIZE) { flush_output(w); w = 0; } DUMPBITS(8) } /* restore the globals from the locals */ wp = w; /* restore global window pointer */ bb = b; /* restore global bit buffer */ bk = k; return 0; } local int inflate_fixed() /* decompress an inflated type 1 (fixed Huffman codes) block. We should either replace this with a custom decoder, or at least precompute the Huffman tables. */ { int i; /* temporary variable */ struct huft *tl; /* literal/length code table */ struct huft *td; /* distance code table */ int bl; /* lookup bits for tl */ int bd; /* lookup bits for td */ unsigned l[288]; /* length list for huft_build */ /* set up literal table */ for (i = 0; i < 144; i++) l[i] = 8; for (; i < 256; i++) l[i] = 9; for (; i < 280; i++) l[i] = 7; for (; i < 288; i++) /* make a complete, but wrong code set */ l[i] = 8; bl = 7; if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) return i; /* set up distance table */ for (i = 0; i < 30; i++) /* make an incomplete code set */ l[i] = 5; bd = 5; if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) { huft_free(tl); return i; } /* decompress until an end-of-block code */ if (inflate_codes(tl, td, bl, bd)) return 1; /* free the decoding tables, return */ huft_free(tl); huft_free(td); return 0; } local int inflate_dynamic() /* decompress an inflated type 2 (dynamic Huffman codes) block. */ { int i; /* temporary variables */ unsigned j; unsigned l; /* last length */ unsigned m; /* mask for bit lengths table */ unsigned n; /* number of lengths to get */ struct huft *tl; /* literal/length code table */ struct huft *td; /* distance code table */ int bl; /* lookup bits for tl */ int bd; /* lookup bits for td */ unsigned nb; /* number of bit length codes */ unsigned nl; /* number of literal/length codes */ unsigned nd; /* number of distance codes */ #ifdef PKZIP_BUG_WORKAROUND unsigned ll[288+32]; /* literal/length and distance code lengths */ #else unsigned ll[286+30]; /* literal/length and distance code lengths */ #endif register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ /* make local bit buffer */ b = bb; k = bk; /* read in table lengths */ NEEDBITS(5) nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */ DUMPBITS(5) NEEDBITS(5) nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */ DUMPBITS(5) NEEDBITS(4) nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */ DUMPBITS(4) #ifdef PKZIP_BUG_WORKAROUND if (nl > 288 || nd > 32) #else if (nl > 286 || nd > 30) #endif return 1; /* bad lengths */ /* read in bit-length-code lengths */ for (j = 0; j < nb; j++) { NEEDBITS(3) ll[border[j]] = (unsigned)b & 7; DUMPBITS(3) } for (; j < 19; j++) ll[border[j]] = 0; /* build decoding table for trees--single level, 7 bit lookup */ bl = 7; if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) { if (i == 1) huft_free(tl); return i; /* incomplete code set */ } /* read in literal and distance code lengths */ n = nl + nd; m = mask_bits[bl]; i = l = 0; while ((unsigned)i < n) { NEEDBITS((unsigned)bl) j = (td = tl + ((unsigned)b & m))->b; DUMPBITS(j) j = td->v.n; if (j < 16) /* length of code in bits (0..15) */ ll[i++] = l = j; /* save last length in l */ else if (j == 16) /* repeat last length 3 to 6 times */ { NEEDBITS(2) j = 3 + ((unsigned)b & 3); DUMPBITS(2) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = l; } else if (j == 17) /* 3 to 10 zero length codes */ { NEEDBITS(3) j = 3 + ((unsigned)b & 7); DUMPBITS(3) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = 0; l = 0; } else /* j == 18: 11 to 138 zero length codes */ { NEEDBITS(7) j = 11 + ((unsigned)b & 0x7f); DUMPBITS(7) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = 0; l = 0; } } /* free decoding table for trees */ huft_free(tl); /* restore the global bit buffer */ bb = b; bk = k; /* build the decoding tables for literal/length and distance codes */ bl = lbits; if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) { if (i == 1) { error(" incomplete literal tree in inflate_dynamic"); huft_free(tl); } return i; /* incomplete code set */ } bd = dbits; if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) { if (i == 1) { error(" incomplete distance tree in inflate_dynamic"); #ifdef PKZIP_BUG_WORKAROUND i = 0; } #else huft_free(td); } huft_free(tl); return i; /* incomplete code set */ #endif } /* decompress until an end-of-block code */ if (inflate_codes(tl, td, bl, bd)) return 1; /* free the decoding tables, return */ huft_free(tl); huft_free(td); return 0; } local int inflate_block(e) int *e; /* last block flag */ /* decompress an inflated block */ { unsigned t; /* block type */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ /* make local bit buffer */ b = bb; k = bk; /* read in last block bit */ NEEDBITS(1) *e = (int)b & 1; DUMPBITS(1) /* read in block type */ NEEDBITS(2) t = (unsigned)b & 3; DUMPBITS(2) /* restore the global bit buffer */ bb = b; bk = k; /* inflate that block type */ if (t == 2) return inflate_dynamic(); if (t == 0) return inflate_stored(); if (t == 1) return inflate_fixed(); /* bad block type */ return 2; } local int inflate() /* decompress an inflated entry */ { int e; /* last block flag */ int r; /* result code */ unsigned h; /* maximum struct huft's malloc'ed */ /* initialize window, bit buffer */ wp = 0; bk = 0; bb = 0; /* decompress until the last block */ h = 0; do { hufts = 0; if ((r = inflate_block(&e)) != 0) return r; if (hufts > h) h = hufts; } while (!e); /* Undo too much lookahead. The next read will be byte aligned so we * can discard unused bits in the last meaningful byte. */ while (bk >= 8) { bk -= 8; inptr--; } /* flush out slide */ flush_output(wp); return 0; } /* *********************** */ /* start of file deflate.c */ /* *********************** */ /* deflate.c -- compress data using the deflation algorithm * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. */ /* * PURPOSE * * Identify new text as repetitions of old text within a fixed- * length sliding window trailing behind the new text. * * DISCUSSION * * The "deflation" process depends on being able to identify portions * of the input text which are identical to earlier input (within a * sliding window trailing behind the input currently being processed). * * The most straightforward technique turns out to be the fastest for * most input files: try all possible matches and select the longest. * The key feature of this algorithm is that insertions into the string * dictionary are very simple and thus fast, and deletions are avoided * completely. Insertions are performed at each input character, whereas * string matches are performed only when the previous match ends. So it * is preferable to spend more time in matches to allow very fast string * insertions and avoid deletions. The matching algorithm for small * strings is inspired from that of Rabin & Karp. A brute force approach * is used to find longer strings when a small match has been found. * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze * (by Leonid Broukhis). * A previous version of this file used a more sophisticated algorithm * (by Fiala and Greene) which is guaranteed to run in linear amortized * time, but has a larger average cost, uses more memory and is patented. * However the F&G algorithm may be faster for some highly redundant * files if the parameter max_chain_length (described below) is too large. * * ACKNOWLEDGEMENTS * * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and * I found it in 'freeze' written by Leonid Broukhis. * Thanks to many info-zippers for bug reports and testing. * * REFERENCES * * APPNOTE.TXT documentation file in PKZIP 1.93a distribution. * * A description of the Rabin and Karp algorithm is given in the book * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. * * Fiala,E.R., and Greene,D.H. * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 * * INTERFACE * * void lm_init (int pack_level, ush *flags) * Initialize the "longest match" routines for a new file * * ulg deflate (void) * Processes a new input file and return its compressed length. Sets * the compressed length, crc, deflate flags and internal file * attributes. */ /* =========================================================================== * Configuration parameters */ /* Compile with MEDIUM_MEM to reduce the memory requirements or * with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the * entire input file can be held in memory (not possible on 16 bit systems). * Warning: defining these symbols affects HASH_BITS (see below) and thus * affects the compression ratio. The compressed output * is still correct, and might even be smaller in some cases. */ #ifdef SMALL_MEM # define HASH_BITS 13 /* Number of bits used to hash strings */ #endif #ifdef MEDIUM_MEM # define HASH_BITS 14 #endif #ifndef HASH_BITS # define HASH_BITS 15 /* For portability to 16 bit machines, do not use values above 15. */ #endif /* To save space (see unlzw.c), we overlay prev+head with tab_prefix and * window with tab_suffix. Check that we can do this: */ #if (WSIZE<<1) > (1< BITS-1 error: cannot overlay head with tab_prefix1 #endif #define HASH_SIZE (unsigned)(1<= HASH_BITS */ unsigned int near prev_length; /* Length of the best match at previous step. Matches not greater than this * are discarded. This is used in the lazy match evaluation. */ unsigned near strstart; /* start of string to insert */ unsigned near match_start; /* start of matching string */ local int eofile; /* flag set at end of input file */ local unsigned lookahead; /* number of valid bytes ahead in window */ unsigned near max_chain_length; /* To speed up deflation, hash chains are never searched beyond this length. * A higher limit improves compression ratio but degrades the speed. */ local unsigned int max_lazy_match; /* Attempt to find a better match only when the current match is strictly * smaller than this value. This mechanism is used only for compression * levels >= 4. */ #define max_insert_length max_lazy_match /* Insert new strings in the hash table only if the match length * is not greater than this length. This saves time but degrades compression. * max_insert_length is used only for compression levels <= 3. */ local int compr_level; /* compression level (1..9) */ unsigned near good_match; /* Use a faster search when the previous match is longer than this */ /* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be * found for specific files. */ typedef struct config { ush good_length; /* reduce lazy search above this match length */ ush max_lazy; /* do not perform lazy search above this match length */ ush nice_length; /* quit search above this match length */ ush max_chain; } config; #ifdef FULL_SEARCH # define nice_match MAX_MATCH #else int near nice_match; /* Stop searching when current match exceeds this */ #endif local config configuration_table[10] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0}, /* store only */ /* 1 */ {4, 4, 8, 4}, /* maximum speed, no lazy matches */ /* 2 */ {4, 5, 16, 8}, /* 3 */ {4, 6, 32, 32}, /* 4 */ {4, 4, 16, 16}, /* lazy matches */ /* 5 */ {8, 16, 32, 32}, /* 6 */ {8, 16, 128, 128}, /* 7 */ {8, 32, 128, 256}, /* 8 */ {32, 128, 258, 1024}, /* 9 */ {32, 258, 258, 4096}}; /* maximum compression */ /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different * meaning. */ #define EQUAL 0 /* result of memcmp for equal strings */ /* =========================================================================== * Prototypes for local functions. */ local void fill_window OF((void)); local ulg deflate_fast OF((void)); int longest_match OF((IPos cur_match)); #ifdef ASMV void match_init OF((void)); /* asm code initialization */ #endif #ifdef DEBUG local void check_match OF((IPos start, IPos match, int length)); #endif /* =========================================================================== * Update a hash value with the given input byte * IN assertion: all calls to to UPDATE_HASH are made with consecutive * input characters, so that a running hash key can be computed from the * previous key instead of complete recalculation each time. */ #define UPDATE_HASH(h,c) (h = (((h)< 9) error("bad pack level"); compr_level = pack_level; /* Initialize the hash table. */ #if defined(MAXSEG_64K) && HASH_BITS == 15 for (j = 0; j < HASH_SIZE; j++) head[j] = NIL; #else memzero((char*)head, HASH_SIZE*sizeof(*head)); #endif /* prev will be initialized on the fly */ /* Set the default configuration parameters: */ max_lazy_match = configuration_table[pack_level].max_lazy; good_match = configuration_table[pack_level].good_length; #ifndef FULL_SEARCH nice_match = configuration_table[pack_level].nice_length; #endif max_chain_length = configuration_table[pack_level].max_chain; if (pack_level == 1) { *flags |= FAST; } else if (pack_level == 9) { *flags |= SLOW; } /* ??? reduce max_chain_length for binary files */ strstart = 0; block_start = 0L; #ifdef ASMV match_init(); /* initialize the asm code */ #endif lookahead = read_buf((char*)window, sizeof(int) <= 2 ? (unsigned)WSIZE : 2*WSIZE); if (lookahead == 0 || lookahead == (unsigned)EOF) { eofile = 1, lookahead = 0; return; } eofile = 0; /* Make sure that we always have enough lookahead. This is important * if input comes from a device such as a tty. */ while (lookahead < MIN_LOOKAHEAD && !eofile) fill_window(); ins_h = 0; for (j=0; j= 1 */ #ifndef ASMV /* For MSDOS, OS/2 and 386 Unix, an optimized version is in match.asm or * match.s. The code is functionally equivalent, so you can use the C version * if desired. */ int longest_match(cur_match) IPos cur_match; /* current match */ { unsigned chain_length = max_chain_length; /* max hash chain length */ register uch *scan = window + strstart; /* current string */ register uch *match; /* matched string */ register int len; /* length of current match */ int best_len = prev_length; /* best match length so far */ IPos limit = strstart > (IPos)MAX_DIST ? strstart - (IPos)MAX_DIST : NIL; /* Stop when cur_match becomes <= limit. To simplify the code, * we prevent matches with the string of window index 0. */ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ #if HASH_BITS < 8 || MAX_MATCH != 258 error: Code too clever #endif #ifdef UNALIGNED_OK /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ register uch *strend = window + strstart + MAX_MATCH - 1; register ush scan_start = *(ush*)scan; register ush scan_end = *(ush*)(scan+best_len-1); #else register uch *strend = window + strstart + MAX_MATCH; register uch scan_end1 = scan[best_len-1]; register uch scan_end = scan[best_len]; #endif /* Do not waste too much time if we already have a good match: */ if (prev_length >= good_match) { chain_length >>= 2; } Assert(strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead"); do { Assert(cur_match < strstart, "no future"); match = window + cur_match; /* Skip to next match if the match length cannot increase * or if the match length is less than 2: */ #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) /* This code assumes sizeof(unsigned short) == 2. Do not use * UNALIGNED_OK if your compiler uses a different size. */ if (*(ush*)(match+best_len-1) != scan_end || *(ush*)match != scan_start) continue; /* It is not necessary to compare scan[2] and match[2] since they are * always equal when the other bytes match, given that the hash keys * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at * strstart+3, +5, ... up to strstart+257. We check for insufficient * lookahead only every 4th comparison; the 128th check will be made * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is * necessary to put more guard bytes at the end of the window, or * to check more often for insufficient lookahead. */ scan++, match++; do { } while (*(ush*)(scan+=2) == *(ush*)(match+=2) && *(ush*)(scan+=2) == *(ush*)(match+=2) && *(ush*)(scan+=2) == *(ush*)(match+=2) && *(ush*)(scan+=2) == *(ush*)(match+=2) && scan < strend); /* The funny "do {}" generates better code on most compilers */ /* Here, scan <= window+strstart+257 */ Assert(scan <= window+(unsigned)(window_size-1), "wild scan"); if (*scan == *match) scan++; len = (MAX_MATCH - 1) - (int)(strend-scan); scan = strend - (MAX_MATCH-1); #else /* UNALIGNED_OK */ if (match[best_len] != scan_end || match[best_len-1] != scan_end1 || *match != *scan || *++match != scan[1]) continue; /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match++; /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); len = MAX_MATCH - (int)(strend - scan); scan = strend - MAX_MATCH; #endif /* UNALIGNED_OK */ if (len > best_len) { match_start = cur_match; best_len = len; if (len >= nice_match) break; #ifdef UNALIGNED_OK scan_end = *(ush*)(scan+best_len-1); #else scan_end1 = scan[best_len-1]; scan_end = scan[best_len]; #endif } } while ((cur_match = prev[cur_match & WMASK]) > limit && --chain_length != 0); return best_len; } #endif /* ASMV */ #ifdef DEBUG /* =========================================================================== * Check that the match at match_start is indeed a match. */ local void check_match(start, match, length) IPos start, match; int length; { /* check that the match is indeed a match */ if (memcmp((char*)window + match, (char*)window + start, length) != EQUAL) { fprintf(stderr, " start %d, match %d, length %d\n", start, match, length); error("invalid match"); } if (verbose > 1) { fprintf(stderr,"\\[%d,%d]", start-match, length); do { putc(window[start++], stderr); } while (--length != 0); } } #else # define check_match(start, match, length) #endif /* =========================================================================== * Fill the window when the lookahead becomes insufficient. * Updates strstart and lookahead, and sets eofile if end of input file. * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 * OUT assertions: at least one byte has been read, or eofile is set; * file reads are performed for at least two bytes (required for the * translate_eol option). */ local void fill_window() { register unsigned n, m; unsigned more = (unsigned)(window_size - (ulg)lookahead - (ulg)strstart); /* Amount of free space at the end of the window. */ /* If the window is almost full and there is insufficient lookahead, * move the upper half to the lower one to make room in the upper half. */ if (more == (unsigned)EOF) { /* Very unlikely, but possible on 16 bit machine if strstart == 0 * and lookahead == 1 (input done one byte at time) */ more--; } else if (strstart >= WSIZE+MAX_DIST) { /* By the IN assertion, the window is not empty so we can't confuse * more == 0 with more == 64K on a 16 bit machine. */ Assert(window_size == (ulg)2*WSIZE, "no sliding with BIG_MEM"); memcpy((char*)window, (char*)window+WSIZE, (unsigned)WSIZE); match_start -= WSIZE; strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */ block_start -= (long) WSIZE; for (n = 0; n < HASH_SIZE; n++) { m = head[n]; head[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); } for (n = 0; n < WSIZE; n++) { m = prev[n]; prev[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); /* If n is not on any hash chain, prev[n] is garbage but * its value will never be used. */ } more += WSIZE; } /* At this point, more >= 2 */ if (!eofile) { n = read_buf((char*)window+strstart+lookahead, more); if (n == 0 || n == (unsigned)EOF) { eofile = 1; } else { lookahead += n; } } } /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ #define FLUSH_BLOCK(eof) \ flush_block(block_start >= 0L ? (char*)&window[(unsigned)block_start] : \ (char*)NULL, (long)strstart - block_start, (eof)) /* =========================================================================== * Processes a new input file and return its compressed length. This * function does not perform lazy evaluationof matches and inserts * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ local ulg deflate_fast() { IPos hash_head; /* head of the hash chain */ int flush; /* set if current block must be flushed */ unsigned match_length = 0; /* length of best match */ prev_length = MIN_MATCH-1; while (lookahead != 0) { /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ INSERT_STRING(strstart, hash_head); /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ if (hash_head != NIL && strstart - hash_head <= MAX_DIST) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ match_length = longest_match (hash_head); /* longest_match() sets match_start */ if (match_length > lookahead) match_length = lookahead; } if (match_length >= MIN_MATCH) { check_match(strstart, match_start, match_length); flush = ct_tally(strstart-match_start, match_length - MIN_MATCH); lookahead -= match_length; /* Insert new strings in the hash table only if the match length * is not too large. This saves time but degrades compression. */ if (match_length <= max_insert_length) { match_length--; /* string at strstart already in hash table */ do { strstart++; INSERT_STRING(strstart, hash_head); /* strstart never exceeds WSIZE-MAX_MATCH, so there are * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH * these bytes are garbage, but it does not matter since * the next lookahead bytes will be emitted as literals. */ } while (--match_length != 0); strstart++; } else { strstart += match_length; match_length = 0; ins_h = window[strstart]; UPDATE_HASH(ins_h, window[strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif } } else { /* No match, output a literal byte */ Tracevv((stderr,"%c",window[strstart])); flush = ct_tally (0, window[strstart]); lookahead--; strstart++; } if (flush) FLUSH_BLOCK(0), block_start = strstart; /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ while (lookahead < MIN_LOOKAHEAD && !eofile) fill_window(); } return FLUSH_BLOCK(1); /* eof */ } /* =========================================================================== * Same as above, but achieves better compression. We use a lazy * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ ulg deflate() { IPos hash_head; /* head of hash chain */ IPos prev_match; /* previous match */ int flush; /* set if current block must be flushed */ int match_available = 0; /* set if previous match exists */ register unsigned match_length = MIN_MATCH-1; /* length of best match */ #ifdef DEBUG extern long isize; /* byte length of input file, for debug only */ #endif if (compr_level <= 3) return deflate_fast(); /* optimized for speed */ /* Process the input block. */ while (lookahead != 0) { /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ INSERT_STRING(strstart, hash_head); /* Find the longest match, discarding those <= prev_length. */ prev_length = match_length, prev_match = match_start; match_length = MIN_MATCH-1; if (hash_head != NIL && prev_length < max_lazy_match && strstart - hash_head <= MAX_DIST) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ match_length = longest_match (hash_head); /* longest_match() sets match_start */ if (match_length > lookahead) match_length = lookahead; /* Ignore a length 3 match if it is too distant: */ if (match_length == MIN_MATCH && strstart-match_start > TOO_FAR){ /* If prev_match is also MIN_MATCH, match_start is garbage * but we will ignore the current match anyway. */ match_length--; } } /* If there was a match at the previous step and the current * match is not better, output the previous match: */ if (prev_length >= MIN_MATCH && match_length <= prev_length) { check_match(strstart-1, prev_match, prev_length); flush = ct_tally(strstart-1-prev_match, prev_length - MIN_MATCH); /* Insert in hash table all strings up to the end of the match. * strstart-1 and strstart are already inserted. */ lookahead -= prev_length-1; prev_length -= 2; do { strstart++; INSERT_STRING(strstart, hash_head); /* strstart never exceeds WSIZE-MAX_MATCH, so there are * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH * these bytes are garbage, but it does not matter since the * next lookahead bytes will always be emitted as literals. */ } while (--prev_length != 0); match_available = 0; match_length = MIN_MATCH-1; strstart++; if (flush) FLUSH_BLOCK(0), block_start = strstart; } else if (match_available) { /* If there was no match at the previous position, output a * single literal. If there was a match but the current match * is longer, truncate the previous match to a single literal. */ Tracevv((stderr,"%c",window[strstart-1])); if (ct_tally (0, window[strstart-1])) { FLUSH_BLOCK(0), block_start = strstart; } strstart++; lookahead--; } else { /* There is no previous match to compare with, wait for * the next step to decide. */ match_available = 1; strstart++; lookahead--; } Assert (strstart <= isize && lookahead <= isize, "a bit too far"); /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ while (lookahead < MIN_LOOKAHEAD && !eofile) fill_window(); } if (match_available) ct_tally (0, window[strstart-1]); return FLUSH_BLOCK(1); /* eof */ } /* ********************** */ /* start of file trees.c */ /* ********************** */ /* trees.c -- output deflated data using Huffman coding * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. */ /* * PURPOSE * * Encode various sets of source values using variable-length * binary code trees. * * DISCUSSION * * The PKZIP "deflation" process uses several Huffman trees. The more * common source values are represented by shorter bit sequences. * * Each code tree is stored in the ZIP file in a compressed form * which is itself a Huffman encoding of the lengths of * all the code strings (in ascending order by source values). * The actual code strings are reconstructed from the lengths in * the UNZIP process, as described in the "application note" * (APPNOTE.TXT) distributed as part of PKWARE's PKZIP program. * * REFERENCES * * Lynch, Thomas J. * Data Compression: Techniques and Applications, pp. 53-55. * Lifetime Learning Publications, 1985. ISBN 0-534-03418-7. * * Storer, James A. * Data Compression: Methods and Theory, pp. 49-50. * Computer Science Press, 1988. ISBN 0-7167-8156-5. * * Sedgewick, R. * Algorithms, p290. * Addison-Wesley, 1983. ISBN 0-201-06672-6. * * INTERFACE * * void ct_init (ush *attr, int *methodp) * Allocate the match buffer, initialize the various tables and save * the location of the internal file attribute (ascii/binary) and * method (DEFLATE/STORE) * * void ct_tally (int dist, int lc); * Save the match info and tally the frequency counts. * * long flush_block (char *buf, ulg stored_len, int eof) * Determine the best encoding for the current block: dynamic trees, * static trees or store, and output the encoded block to the zip * file. Returns the total compressed length for the file so far. * */ /* =========================================================================== * Constants */ #define MAX_BITS 15 /* All codes must not exceed MAX_BITS bits */ #define MAX_BL_BITS 7 /* Bit length codes must not exceed MAX_BL_BITS bits */ #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ #define LITERALS 256 /* number of literal bytes 0..255 */ #define END_BLOCK 256 /* end of block literal code */ #define L_CODES (LITERALS+1+LENGTH_CODES) /* number of Literal or Length codes, including the END_BLOCK code */ #define D_CODES 30 /* number of distance codes */ #define BL_CODES 19 /* number of codes used to transfer the bit lengths */ local int near extra_lbits[LENGTH_CODES] /* extra bits for each length code */ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; local int near extra_dbits[D_CODES] /* extra bits for each distance code */ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; local int near extra_blbits[BL_CODES]/* extra bits for each bit length code */ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 /* The three kinds of block type */ #ifndef LIT_BUFSIZE # ifdef SMALL_MEM # define LIT_BUFSIZE 0x2000 # else # ifdef MEDIUM_MEM # define LIT_BUFSIZE 0x4000 # else # define LIT_BUFSIZE 0x8000 # endif # endif #endif #ifndef DIST_BUFSIZE # define DIST_BUFSIZE LIT_BUFSIZE #endif /* Sizes of match buffers for literals/lengths and distances. There are * 4 reasons for limiting LIT_BUFSIZE to 64K: * - frequencies can be kept in 16 bit counters * - if compression is not successful for the first block, all input data is * still in the window so we can still emit a stored block even when input * comes from standard input. (This can also be done for all blocks if * LIT_BUFSIZE is not greater than 32K.) * - if compression is not successful for a file smaller than 64K, we can * even emit a stored file instead of a stored block (saving 5 bytes). * - creating new Huffman trees less frequently may not provide fast * adaptation to changes in the input data statistics. (Take for * example a binary file with poorly compressible code followed by * a highly compressible string table.) Smaller buffer sizes give * fast adaptation but have of course the overhead of transmitting trees * more frequently. * - I can't count above 4 * The current code is general and allows DIST_BUFSIZE < LIT_BUFSIZE (to save * memory at the expense of compression). Some optimizations would be possible * if we rely on DIST_BUFSIZE == LIT_BUFSIZE. */ #if LIT_BUFSIZE > INBUFSIZ error cannot overlay l_buf and inbuf #endif #define REP_3_6 16 /* repeat previous bit length 3-6 times (2 bits of repeat count) */ #define REPZ_3_10 17 /* repeat a zero length 3-10 times (3 bits of repeat count) */ #define REPZ_11_138 18 /* repeat a zero length 11-138 times (7 bits of repeat count) */ /* =========================================================================== * Local data */ /* Data structure describing a single value and its code string. */ typedef struct ct_data { union { ush freq; /* frequency count */ ush code; /* bit string */ } fc; union { ush dad; /* father node in Huffman tree */ ush len; /* length of bit string */ } dl; } ct_data; #define Freq fc.freq #define Code fc.code #define Dad dl.dad #define Len dl.len #define HEAP_SIZE (2*L_CODES+1) /* maximum heap size */ local ct_data near dyn_ltree[HEAP_SIZE]; /* literal and length tree */ local ct_data near dyn_dtree[2*D_CODES+1]; /* distance tree */ local ct_data near static_ltree[L_CODES+2]; /* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However * The codes 286 and 287 are needed to build a canonical tree (see ct_init * below). */ local ct_data near static_dtree[D_CODES]; /* The static distance tree. (Actually a trivial tree since all codes use * 5 bits.) */ local ct_data near bl_tree[2*BL_CODES+1]; /* Huffman tree for the bit lengths */ typedef struct tree_desc { ct_data near *dyn_tree; /* the dynamic tree */ ct_data near *static_tree; /* corresponding static tree or NULL */ int near *extra_bits; /* extra bits for each code or NULL */ int extra_base; /* base index for extra_bits */ int elems; /* max number of elements in the tree */ int max_length; /* max bit length for the codes */ int max_code; /* largest code with non zero frequency */ } tree_desc; local tree_desc near l_desc = {dyn_ltree, static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS, 0}; local tree_desc near d_desc = {dyn_dtree, static_dtree, extra_dbits, 0, D_CODES, MAX_BITS, 0}; local tree_desc near bl_desc = {bl_tree, (ct_data near *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS, 0}; local ush near bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ local uch near bl_order[BL_CODES] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; /* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. */ local int near heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ local int heap_len; /* number of elements in the heap */ local int heap_max; /* element of largest frequency */ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. * The same heap array is used to build all trees. */ local uch near depth[2*L_CODES+1]; /* Depth of each subtree used as tie breaker for trees of equal frequency */ local uch length_code[MAX_MATCH-MIN_MATCH+1]; /* length code for each normalized match length (0 == MIN_MATCH) */ local uch dist_code[512]; /* distance codes. The first 256 values correspond to the distances * 3 .. 258, the last 256 values correspond to the top 8 bits of * the 15 bit distances. */ local int near base_length[LENGTH_CODES]; /* First normalized length for each code (0 = MIN_MATCH) */ local int near base_dist[D_CODES]; /* First normalized distance for each code (0 = distance of 1) */ #define l_buf inbuf /* DECLARE(uch, l_buf, LIT_BUFSIZE); buffer for literals or lengths */ /* DECLARE(ush, d_buf, DIST_BUFSIZE); buffer for distances */ local uch near flag_buf[(LIT_BUFSIZE/8)]; /* flag_buf is a bit array distinguishing literals from lengths in * l_buf, thus indicating the presence or absence of a distance. */ local unsigned last_lit; /* running index in l_buf */ local unsigned last_dist; /* running index in d_buf */ local unsigned last_flags; /* running index in flag_buf */ local uch flags; /* current flags not yet saved in flag_buf */ local uch flag_bit; /* current bit used in flags */ /* bits are filled in flags starting at bit 0 (least significant). * Note: these flags are overkill in the current code since we don't * take advantage of DIST_BUFSIZE == LIT_BUFSIZE. */ local ulg opt_len; /* bit length of current block with optimal trees */ local ulg static_len; /* bit length of current block with static trees */ local ulg compressed_len; /* total bit length of compressed file */ local ulg input_len; /* total byte length of input file */ /* input_len is for debugging only since we can get it by other means. */ int *file_method; /* pointer to DEFLATE or STORE */ #ifdef DEBUG extern ulg bits_sent; /* bit length of the compressed data */ extern long isize; /* byte length of input file */ #endif extern long block_start; /* window offset of current block */ extern unsigned near strstart; /* window offset of current string */ /* =========================================================================== * Local (static) routines in this file. */ local void init_block OF((void)); local void pqdownheap OF((ct_data near *tree, int k)); local void gen_bitlen OF((tree_desc near *desc)); local void gen_codes OF((ct_data near *tree, int max_code)); local void build_tree OF((tree_desc near *desc)); local void scan_tree OF((ct_data near *tree, int max_code)); local void send_tree OF((ct_data near *tree, int max_code)); local int build_bl_tree OF((void)); local void send_all_trees OF((int lcodes, int dcodes, int blcodes)); local void compress_block OF((ct_data near *ltree, ct_data near *dtree)); # define send_code(c, tree) send_bits(tree[c].Code, tree[c].Len) /* Send a code of the given tree. c and tree must not have side effects */ #define d_code(dist) \ ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and * must not have side effects. dist_code[256] and dist_code[257] are never * used. */ #define MAX(a,b) (a >= b ? a : b) /* the arguments must not have side effects */ /* =========================================================================== * Allocate the match buffer, initialize the various tables and save the * location of the internal file attribute (ascii/binary) and method * (DEFLATE/STORE). */ void ct_init(attr, methodp) ush *attr; /* pointer to internal file attribute */ int *methodp; /* pointer to compression method */ { int n; /* iterates over tree elements */ int bits; /* bit counter */ int length; /* length value */ int code; /* code value */ int dist; /* distance index */ file_method = methodp; compressed_len = input_len = 0L; if (static_dtree[0].Len != 0) return; /* ct_init already called */ /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0; for (code = 0; code < LENGTH_CODES-1; code++) { base_length[code] = length; for (n = 0; n < (1< dist code (0..29) */ dist = 0; for (code = 0 ; code < 16; code++) { base_dist[code] = dist; for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ for ( ; code < D_CODES; code++) { base_dist[code] = dist << 7; for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { dist_code[256 + dist++] = (uch)code; } } Assert (dist == 256, "ct_init: 256+dist != 512"); /* Construct the codes of the static literal tree */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; n = 0; while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; /* Codes 286 and 287 do not exist, but we must include them in the * tree construction to get a canonical Huffman tree (longest code * all ones) */ gen_codes((ct_data near *)static_ltree, L_CODES+1); /* The static distance tree is trivial: */ for (n = 0; n < D_CODES; n++) { static_dtree[n].Len = 5; static_dtree[n].Code = bi_reverse(n, 5); } /* Initialize the first block of the first file: */ init_block(); } /* =========================================================================== * Initialize a new block. */ local void init_block() { int n; /* iterates over tree elements */ /* Initialize the trees. */ for (n = 0; n < L_CODES; n++) dyn_ltree[n].Freq = 0; for (n = 0; n < D_CODES; n++) dyn_dtree[n].Freq = 0; for (n = 0; n < BL_CODES; n++) bl_tree[n].Freq = 0; dyn_ltree[END_BLOCK].Freq = 1; opt_len = static_len = 0L; last_lit = last_dist = last_flags = 0; flags = 0; flag_bit = 1; } #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ /* =========================================================================== * Remove the smallest element from the heap and recreate the heap with * one less element. Updates heap and heap_len. */ #define pqremove(tree, top) \ {\ top = heap[SMALLEST]; \ heap[SMALLEST] = heap[heap_len--]; \ pqdownheap(tree, SMALLEST); \ } /* =========================================================================== * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */ #define smaller(tree, n, m) \ (tree[n].Freq < tree[m].Freq || \ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) /* =========================================================================== * Restore the heap property by moving down the tree starting at node k, * exchanging a node with the smallest of its two sons if necessary, stopping * when the heap property is re-established (each father smaller than its * two sons). */ local void pqdownheap(tree, k) ct_data near *tree; /* the tree to restore */ int k; /* node to move down */ { int v = heap[k]; int j = k << 1; /* left son of k */ while (j <= heap_len) { /* Set j to the smallest of the two sons: */ if (j < heap_len && smaller(tree, heap[j+1], heap[j])) j++; /* Exit if v is smaller than both sons */ if (smaller(tree, v, heap[j])) break; /* Exchange v with the smallest son */ heap[k] = heap[j]; k = j; /* And continue down the tree, setting j to the left son of k */ j <<= 1; } heap[k] = v; } /* =========================================================================== * Compute the optimal bit lengths for a tree and update the total bit length * for the current block. * IN assertion: the fields freq and dad are set, heap[heap_max] and * above are the tree nodes sorted by increasing frequency. * OUT assertions: the field len is set to the optimal bit length, the * array bl_count contains the frequencies for each bit length. * The length opt_len is updated; static_len is also updated if stree is * not null. */ local void gen_bitlen(desc) tree_desc near *desc; /* the tree descriptor */ { ct_data near *tree = desc->dyn_tree; int near *extra = desc->extra_bits; int base = desc->extra_base; int max_code = desc->max_code; int max_length = desc->max_length; ct_data near *stree = desc->static_tree; int h; /* heap index */ int n, m; /* iterate over the tree elements */ int bits; /* bit length */ int xbits; /* extra bits */ ush f; /* frequency */ int overflow = 0; /* number of elements with bit length too large */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; /* In a first pass, compute the optimal bit lengths (which may * overflow in the case of the bit length tree). */ tree[heap[heap_max]].Len = 0; /* root of the heap */ for (h = heap_max+1; h < HEAP_SIZE; h++) { n = heap[h]; bits = tree[tree[n].Dad].Len + 1; if (bits > max_length) bits = max_length, overflow++; tree[n].Len = (ush)bits; /* We overwrite tree[n].Dad which is no longer needed */ if (n > max_code) continue; /* not a leaf node */ bl_count[bits]++; xbits = 0; if (n >= base) xbits = extra[n-base]; f = tree[n].Freq; opt_len += (ulg)f * (bits + xbits); if (stree) static_len += (ulg)f * (stree[n].Len + xbits); } if (overflow == 0) return; Trace((stderr,"\nbit length overflow\n")); /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ do { bits = max_length-1; while (bl_count[bits] == 0) bits--; bl_count[bits]--; /* move one leaf down the tree */ bl_count[bits+1] += 2; /* move one overflow item as its brother */ bl_count[max_length]--; /* The brother of the overflow item also moves one step up, * but this does not affect bl_count[max_length] */ overflow -= 2; } while (overflow > 0); /* Now recompute all bit lengths, scanning in increasing frequency. * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all * lengths instead of fixing only the wrong ones. This idea is taken * from 'ar' written by Haruhiko Okumura.) */ for (bits = max_length; bits != 0; bits--) { n = bl_count[bits]; while (n != 0) { m = heap[--h]; if (m > max_code) continue; if (tree[m].Len != (unsigned) bits) { Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); opt_len += ((long)bits-(long)tree[m].Len)*(long)tree[m].Freq; tree[m].Len = (ush)bits; } n--; } } } /* =========================================================================== * Generate the codes for a given tree and bit counts (which need not be * optimal). * IN assertion: the array bl_count contains the bit length statistics for * the given tree and the field len is set for all tree elements. * OUT assertion: the field code is set for all tree elements of non * zero code length. */ local void gen_codes (tree, max_code) ct_data near *tree; /* the tree to decorate */ int max_code; /* largest code with non zero frequency */ { ush next_code[MAX_BITS+1]; /* next code value for each bit length */ ush code = 0; /* running code value */ int bits; /* bit index */ int n; /* code index */ /* The distribution counts are first used to generate the code values * without bit reversal. */ for (bits = 1; bits <= MAX_BITS; bits++) { next_code[bits] = code = (code + bl_count[bits-1]) << 1; } /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. */ Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; ct_data near *stree = desc->static_tree; int elems = desc->elems; int n, m; /* iterate over heap elements */ int max_code = -1; /* largest code with non zero frequency */ int node = elems; /* next internal node of the tree */ int new; /* WDP added this, instead of declaring it below */ /* Construct the initial heap, with least frequent element in * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. * heap[0] is not used. */ heap_len = 0, heap_max = HEAP_SIZE; for (n = 0; n < elems; n++) { if (tree[n].Freq != 0) { heap[++heap_len] = max_code = n; depth[n] = 0; } else { tree[n].Len = 0; } } /* The pkzip format requires that at least one distance code exists, * and that at least one bit should be sent even if there is only one * possible code. So to avoid special checks later on we force at least * two codes of non zero frequency. */ while (heap_len < 2) { /* int new = heap[++heap_len] = (max_code < 2 ? ++max_code : 0); */ new = heap[++heap_len] = (max_code < 2 ? ++max_code : 0); tree[new].Freq = 1; depth[new] = 0; opt_len--; if (stree) static_len -= stree[new].Len; /* new is 0 or 1 so it does not have extra bits */ } desc->max_code = max_code; /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, * establish sub-heaps of increasing lengths: */ for (n = heap_len/2; n >= 1; n--) pqdownheap(tree, n); /* Construct the Huffman tree by repeatedly combining the least two * frequent nodes. */ do { pqremove(tree, n); /* n = node of least frequency */ m = heap[SMALLEST]; /* m = node of next least frequency */ heap[--heap_max] = n; /* keep the nodes sorted by frequency */ heap[--heap_max] = m; /* Create a new node father of n and m */ tree[node].Freq = tree[n].Freq + tree[m].Freq; depth[node] = (uch) (MAX(depth[n], depth[m]) + 1); tree[n].Dad = tree[m].Dad = (ush)node; #ifdef DUMP_BL_TREE if (tree == bl_tree) { fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); } #endif /* and insert the new node in the heap */ heap[SMALLEST] = node++; pqdownheap(tree, SMALLEST); } while (heap_len >= 2); heap[--heap_max] = heap[SMALLEST]; /* At this point, the fields freq and dad are set. We can now * generate the bit lengths. */ gen_bitlen((tree_desc near *)desc); /* The field len is now set, we can generate the bit codes */ gen_codes ((ct_data near *)tree, max_code); } /* =========================================================================== * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. Updates opt_len to take into account the repeat * counts. (The contribution of the bit length codes will be added later * during the construction of bl_tree.) */ local void scan_tree (tree, max_code) ct_data near *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ if (nextlen == 0) max_count = 138, min_count = 3; tree[max_code+1].Len = (ush)0xffff; /* guard */ for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { bl_tree[curlen].Freq += count; } else if (curlen != 0) { if (curlen != prevlen) bl_tree[curlen].Freq++; bl_tree[REP_3_6].Freq++; } else if (count <= 10) { bl_tree[REPZ_3_10].Freq++; } else { bl_tree[REPZ_11_138].Freq++; } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ local void send_tree (tree, max_code) ct_data near *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ /* tree[max_code+1].Len = -1; */ /* guard already set */ if (nextlen == 0) max_count = 138, min_count = 3; for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { do { send_code(curlen, bl_tree); } while (--count != 0); } else if (curlen != 0) { if (curlen != prevlen) { send_code(curlen, bl_tree); count--; } Assert(count >= 3 && count <= 6, " 3_6?"); send_code(REP_3_6, bl_tree); send_bits(count-3, 2); } else if (count <= 10) { send_code(REPZ_3_10, bl_tree); send_bits(count-3, 3); } else { send_code(REPZ_11_138, bl_tree); send_bits(count-11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */ local int build_bl_tree() { int max_blindex; /* index of last bit length code of non zero freq */ /* Determine the bit length frequencies for literal and distance trees */ scan_tree((ct_data near *)dyn_ltree, l_desc.max_code); scan_tree((ct_data near *)dyn_dtree, d_desc.max_code); /* Build the bit length tree: */ build_tree((tree_desc near *)(&bl_desc)); /* opt_len now includes the length of the tree representations, except * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. */ /* Determine the number of bit length codes to send. The pkzip format * requires that at least 4 bit length codes be sent. (appnote.txt says * 3 but the actual value used is 4.) */ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { if (bl_tree[bl_order[max_blindex]].Len != 0) break; } /* Update opt_len to include the bit length tree and counts */ opt_len += 3*(max_blindex+1) + 5+5+4; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", opt_len, static_len)); return max_blindex; } /* =========================================================================== * Send the header for a block using dynamic Huffman trees: the counts, the * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ local void send_all_trees(lcodes, dcodes, blcodes) int lcodes, dcodes, blcodes; /* number of codes for each tree */ { int rank; /* index in bl_order */ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); Tracev((stderr, "\nbl counts: ")); send_bits(lcodes-257, 5); /* not +255 as stated in appnote.txt */ send_bits(dcodes-1, 5); send_bits(blcodes-4, 4); /* not -3 as stated in appnote.txt */ for (rank = 0; rank < blcodes; rank++) { Tracev((stderr, "\nbl code %2d ", bl_order[rank])); send_bits(bl_tree[bl_order[rank]].Len, 3); } Tracev((stderr, "\nbl tree: sent %ld", bits_sent)); send_tree((ct_data near *)dyn_ltree, lcodes-1); /* send the literal tree */ Tracev((stderr, "\nlit tree: sent %ld", bits_sent)); send_tree((ct_data near *)dyn_dtree, dcodes-1); /* send the distance tree */ Tracev((stderr, "\ndist tree: sent %ld", bits_sent)); } /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. This function * returns the total compressed length for the file so far. */ ulg flush_block(buf, stored_len, eof) char *buf; /* input block, or NULL if too old */ ulg stored_len; /* length of input block */ int eof; /* true if this is the last block for a file */ { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex; /* index of last bit length code of non zero freq */ flag_buf[last_flags] = flags; /* Save the flags for the last 8 items */ /* Construct the literal and distance trees */ build_tree((tree_desc near *)(&l_desc)); Tracev((stderr, "\nlit data: dyn %ld, stat %ld", opt_len, static_len)); build_tree((tree_desc near *)(&d_desc)); Tracev((stderr, "\ndist data: dyn %ld, stat %ld", opt_len, static_len)); /* At this point, opt_len and static_len are the total bit lengths of * the compressed block data, excluding the tree representations. */ /* Build the bit length tree for the above two trees, and get the index * in bl_order of the last bit length code to send. */ max_blindex = build_bl_tree(); /* Determine the best encoding. Compute first the block length in bytes */ opt_lenb = (opt_len+3+7)>>3; static_lenb = (static_len+3+7)>>3; input_len += stored_len; /* for debugging only */ Trace((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", opt_lenb, opt_len, static_lenb, static_len, stored_len, last_lit, last_dist)); if (static_lenb <= opt_lenb) opt_lenb = static_lenb; /* If compression failed and this is the first and last block, * and if the zip file can be seeked (to rewrite the local header), * the whole file is transformed into a stored file: */ #ifdef FORCE_METHOD if (level == 1 && eof && compressed_len == 0L) { /* force stored file */ #else if (stored_len <= opt_lenb && eof && compressed_len == 0L && seekable()) { #endif /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ if (buf == (char*)0) error ("block vanished"); copy_block(buf, (unsigned)stored_len, 0); /* without header */ compressed_len = stored_len << 3; *file_method = STORED; #ifdef FORCE_METHOD } else if (level == 2 && buf != (char*)0) { /* force stored block */ #else } else if (stored_len+4 <= opt_lenb && buf != (char*)0) { /* 4: two words for the lengths */ #endif /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. * Otherwise we can't have processed more than WSIZE input bytes since * the last block flush, because compression would have been * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ send_bits((STORED_BLOCK<<1)+eof, 3); /* send block type */ compressed_len = (compressed_len + 3 + 7) & ~7L; compressed_len += (stored_len + 4) << 3; copy_block(buf, (unsigned)stored_len, 1); /* with header */ #ifdef FORCE_METHOD } else if (level == 3) { /* force static trees */ #else } else if (static_lenb == opt_lenb) { #endif send_bits((STATIC_TREES<<1)+eof, 3); compress_block((ct_data near *)static_ltree, (ct_data near *)static_dtree); compressed_len += 3 + static_len; } else { send_bits((DYN_TREES<<1)+eof, 3); send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1); compress_block((ct_data near *)dyn_ltree, (ct_data near *)dyn_dtree); compressed_len += 3 + opt_len; } Assert (compressed_len == bits_sent, "bad compressed size"); init_block(); if (eof) { Assert (input_len == isize, "bad input size"); bi_windup(); compressed_len += 7; /* align on byte boundary */ } Tracev((stderr,"\ncomprlen %lu(%lu) ", compressed_len>>3, compressed_len-7*eof)); return compressed_len >> 3; } /* =========================================================================== * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ int ct_tally (dist, lc) int dist; /* distance of matched string */ int lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ { l_buf[last_lit++] = (uch)lc; if (dist == 0) { /* lc is the unmatched char */ dyn_ltree[lc].Freq++; } else { /* Here, lc is the match length - MIN_MATCH */ dist--; /* dist = match distance - 1 */ Assert((ush)dist < (ush)MAX_DIST && (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && (ush)d_code(dist) < (ush)D_CODES, "ct_tally: bad match"); dyn_ltree[length_code[lc]+LITERALS+1].Freq++; dyn_dtree[d_code(dist)].Freq++; d_buf[last_dist++] = (ush)dist; flags |= flag_bit; } flag_bit <<= 1; /* Output the flags if they fill a byte: */ if ((last_lit & 7) == 0) { flag_buf[last_flags++] = flags; flags = 0, flag_bit = 1; } /* Try to guess if it is profitable to stop the current block here */ if (level > 2 && (last_lit & 0xfff) == 0) { /* Compute an upper bound for the compressed length */ ulg out_length = (ulg)last_lit*8L; ulg in_length = (ulg)strstart-block_start; int dcode; for (dcode = 0; dcode < D_CODES; dcode++) { out_length += (ulg)dyn_dtree[dcode].Freq*(5L+extra_dbits[dcode]); } out_length >>= 3; Trace((stderr,"\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", last_lit, last_dist, in_length, out_length, 100L - out_length*100L/in_length)); if (last_dist < last_lit/2 && out_length < in_length/2) return 1; } return (last_lit == LIT_BUFSIZE-1 || last_dist == DIST_BUFSIZE); /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. */ } /* =========================================================================== * Send the block data compressed using the given Huffman trees */ local void compress_block(ltree, dtree) ct_data near *ltree; /* literal tree */ ct_data near *dtree; /* distance tree */ { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ unsigned lx = 0; /* running index in l_buf */ unsigned dx = 0; /* running index in d_buf */ unsigned fx = 0; /* running index in flag_buf */ uch flag = 0; /* current flags */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (last_lit != 0) do { if ((lx & 7) == 0) flag = flag_buf[fx++]; lc = l_buf[lx++]; if ((flag & 1) == 0) { send_code(lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); } else { /* Here, lc is the match length - MIN_MATCH */ code = length_code[lc]; send_code(code+LITERALS+1, ltree); /* send the length code */ extra = extra_lbits[code]; if (extra != 0) { lc -= base_length[code]; send_bits(lc, extra); /* send the extra length bits */ } dist = d_buf[dx++]; /* Here, dist is the match distance - 1 */ code = d_code(dist); Assert (code < D_CODES, "bad d_code"); send_code(code, dtree); /* send the distance code */ extra = extra_dbits[code]; if (extra != 0) { dist -= base_dist[code]; send_bits(dist, extra); /* send the extra distance bits */ } } /* literal or match pair ? */ flag >>= 1; } while (lx < last_lit); send_code(END_BLOCK, ltree); } /* ********************** */ /* start of file bits.c */ /* ********************** */ /* bits.c -- output variable-length bit strings * Copyright (C) 1992-1993 Jean-loup Gailly * This is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, see the file COPYING. */ /* * PURPOSE * * Output variable-length bit strings. Compression can be done * to a file or to memory. (The latter is not supported in this version.) * * DISCUSSION * * The PKZIP "deflate" file format interprets compressed file data * as a sequence of bits. Multi-bit strings in the file may cross * byte boundaries without restriction. * * The first bit of each byte is the low-order bit. * * The routines in this file allow a variable-length bit value to * be output right-to-left (useful for literal values). For * left-to-right output (useful for code strings from the tree routines), * the bits must have been reversed first with bi_reverse(). * * For in-memory compression, the compressed bit stream goes directly * into the requested output buffer. The input data is read in blocks * by the mem_read() function. The buffer is limited to 64K on 16 bit * machines. * * INTERFACE * * void bi_init (FILE *zipfile) * Initialize the bit string routines. * * void send_bits (int value, int length) * Write out a bit string, taking the source bits right to * left. * * int bi_reverse (int value, int length) * Reverse the bits of a bit string, taking the source bits left to * right and emitting them right to left. * * void bi_windup (void) * Write out any remaining bits in an incomplete byte. * * void copy_block(char *buf, unsigned len, int header) * Copy a stored block to the zip file, storing first the length and * its one's complement if requested. * */ /* #include "tailor.h" */ /* #include "gzip.h" */ /* #include "crypt.h" */ /* =========================================================================== * Local data used by the "bit string" routines. */ local file_t zfile; /* output gzip file */ local unsigned short bi_buf; /* Output buffer. bits are inserted starting at the bottom (least significant * bits). */ #define Buf_size (8 * 2*sizeof(char)) /* Number of bits used within bi_buf. (bi_buf might be implemented on * more than 16 bits on some systems.) */ local int bi_valid; /* Number of valid bits in bi_buf. All bits above the last valid bit * are always zero. */ /* int (*read_buf) OF((char *buf, unsigned size)); */ /* Current input function. Set to mem_read for in-memory compression */ #ifdef DEBUG ulg bits_sent; /* bit length of the compressed data */ #endif /* =========================================================================== * Initialize the bit string routines. */ void bi_init (zipfile) file_t zipfile; /* output zip file, NO_FILE for in-memory compression */ { zfile = zipfile; bi_buf = 0; bi_valid = 0; #ifdef DEBUG bits_sent = 0L; #endif /* Set the defaults for file compression. They are set by memcompress * for in-memory compression. */ read_buf = file_read; /* if (zfile != NO_FILE) { read_buf = file_read; } */ } /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ void send_bits(value, length) int value; /* value to send */ int length; /* number of bits */ { #ifdef DEBUG Tracev((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); bits_sent += (ulg)length; #endif /* If not enough room in bi_buf, use (valid) bits from bi_buf and * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) * unused bits in value. */ if (bi_valid > (int)Buf_size - length) { bi_buf |= (value << bi_valid); put_short(bi_buf); bi_buf = (ush)value >> (Buf_size - bi_valid); bi_valid += length - Buf_size; } else { bi_buf |= value << bi_valid; bi_valid += length; } } /* =========================================================================== * Reverse the first len bits of a code, using straightforward code (a faster * method would use a table) * IN assertion: 1 <= len <= 15 */ unsigned bi_reverse(code, len) unsigned code; /* the value to invert */ int len; /* its bit length */ { register unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; } while (--len > 0); return res >> 1; } /* =========================================================================== * Write out any remaining bits in an incomplete byte. */ void bi_windup() { if (bi_valid > 8) { put_short(bi_buf); } else if (bi_valid > 0) { put_byte(bi_buf); } bi_buf = 0; bi_valid = 0; #ifdef DEBUG bits_sent = (bits_sent+7) & ~7; #endif } /* =========================================================================== * Copy a stored block to the zip file, storing first the length and its * one's complement if requested. */ void copy_block(buf, len, header) char *buf; /* the input data */ unsigned len; /* its length */ int header; /* true if block header must be written */ { bi_windup(); /* align on byte boundary */ if (header) { put_short((ush)len); put_short((ush)~len); #ifdef DEBUG bits_sent += 2*16; #endif } #ifdef DEBUG bits_sent += (ulg)len<<3; #endif while (len--) { #ifdef CRYPT int t; if (key) zencode(*buf, t); #endif put_byte(*buf++); } } indi-0.5/src/cfitsio/putcolsb.c0000644000175000017500000010356710610474375014362 0ustar jrjr/* This file, putcolsb.c, contains routines that write data elements to */ /* a FITS image or table with signed char (signed byte) datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprsb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ signed char *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; signed char nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TSBYTE, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclsb(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnsb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ signed char *array, /* I - array of values that are written */ signed char nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; signed char nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TSBYTE, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnsb(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ signed char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dsb(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ signed char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TSBYTE, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclsb(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclsb(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpsssb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ signed char *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TSBYTE, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclsb(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpsb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ signed char *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclsb(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclsb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ signed char *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TBYTE): /* convert the raw data before writing to FITS file */ ffs1fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TLONGLONG): ffs1fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TSHORT): ffs1fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONG): ffs1fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffs1fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffs1fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (strchr(tform,'A')) { /* write raw input bytes without conversion */ /* This case is a hack to let users write a stream */ /* of bytes directly to the 'A' format column */ if (incre == twidth) ffpbyt(fptr, ntodo, &array[next], status); else ffpbytoff(fptr, twidth, ntodo/twidth, incre - twidth, &array[next], status); break; } else if (cform[1] != 's') /* "%s" format is a string */ { ffs1fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpclsb).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnsb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ signed char *array, /* I - array of values to write */ signed char nulvalue, /* I - flag for undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclsb(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood + 1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclsb(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad + 1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclsb(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fi1(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == -128.) { /* Instead of adding 128, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(unsigned char *) &input[ii] ) ^ 0x80; } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ( ((double) input[ii]) - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fi2(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; /* just copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (((double) input[ii]) - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fi4(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (((double) input[ii]) - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fi8(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fr4(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) (( ( (double) input[ii] ) - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fr8(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = ( ( (double) input[ii] ) - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffs1fstr(signed char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } indi-0.5/src/cfitsio/getcole.c0000644000175000017500000020322310610474374014136 0ustar jrjr/* This file, getcole.c, contains routines that read data elements from */ /* a FITS image or table, with float datatype */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpve( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float nulval, /* I - value for undefined pixels */ float *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; float nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TFLOAT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcle(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfe( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TFLOAT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcle(fptr, 2, row, firstelem, nelem, 1, 2, 0.F, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2de(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ float nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ float *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3de(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3de(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ float nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ float *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; LONGLONG narray, nfits; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; float nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TFLOAT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcle(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcle(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsve(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ float nulval, /* I - value to set undefined pixels */ float *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; float nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsve is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TFLOAT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsve: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgcle(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfe(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ float *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; float nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsve is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TFLOAT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsve: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcle(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpe( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ float *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcle(fptr, 1, row, firstelem, nelem, 1, 1, 0.F, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcve(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float nulval, /* I - value for null pixels */ float *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvc(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float nulval, /* I - value for null pixels */ float *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. TSCAL and ZERO should not be used with complex values. */ { char cdummy; /* a complex value is interpreted as a pair of float values, thus */ /* need to multiply the first element and number of elements by 2 */ ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem *2, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfe(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { float dummy = 0; ffgcle(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfc(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ float *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. TSCAL and ZERO should not be used with complex values. */ { long ii, jj; float dummy = 0; char *carray; /* a complex value is interpreted as a pair of float values, thus */ /* need to multiply the first element and number of elements by 2 */ /* allocate temporary array */ carray = (char *) calloc( (size_t) (nelem * 2), 1); ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 2, dummy, array, carray, anynul, status); for (ii = 0, jj = 0; jj < nelem; ii += 2, jj++) { if (carray[ii] || carray[ii + 1]) nularray[jj] = 1; else nularray[jj] = 0; } free(carray); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcle( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ float nulval, /* I - value for null pixels if nultyp = 1 */ float *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TFLOAT) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, &array[next], status); if (convert) fffr4r4(&array[next], ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1r4((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2r4((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4r4((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8r4( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8r4((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstrr4((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgcle).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgcle).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1r4(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (( (double) input[ii] ) * scale + zero); } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = (float) (( (double) input[ii] ) * scale + zero); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2r4(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = (float) (input[ii] * scale + zero); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4r4(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = (float) (input[ii] * scale + zero); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8r4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { output[ii] = (float) (input[ii] * scale + zero); } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4r4(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { memcpy(output, input, ntodo * sizeof(float) ); } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else { nullarray[ii] = 1; /* explicitly set value in case output contains a NaN */ output[ii] = FLOATNULLVALUE; } } else /* it's an underflow */ output[ii] = 0; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else { nullarray[ii] = 1; /* explicitly set value in case output contains a NaN */ output[ii] = FLOATNULLVALUE; } } else /* it's an underflow */ output[ii] = (float) zero; } else output[ii] = (float) (input[ii] * scale + zero); } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8r4(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { output[ii] = (float) (input[ii] * scale + zero); } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else output[ii] = (float) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = (float) zero; } else output[ii] = (float) (input[ii] * scale + zero); } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstrr4(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ float nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ float *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); output[ii] = (float) (dvalue * scale + zero); /* apply the scaling */ } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } indi-0.5/src/cfitsio/getcolb.c0000644000175000017500000022524610610474374014144 0ustar jrjr/* This file, getcolb.c, contains routines that read data elements from */ /* a FITS image or table, with unsigned char (unsigned byte) data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned char nulval, /* I - value for undefined pixels */ unsigned char *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; unsigned char nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TBYTE, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclb(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned char *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TBYTE, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclb(fptr, 2, row, firstelem, nelem, 1, 2, 0, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2db(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned char nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3db(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3db(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned char nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; LONGLONG narray, nfits; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; unsigned char nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TBYTE, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclb(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclb(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned char nulval, /* I - value to set undefined pixels */ unsigned char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii, i0, i1, i2, i3, i4, i5, i6, i7, i8, row, rstr, rstp, rinc; long str[9], stp[9], incr[9], dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; unsigned char nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvb is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TBYTE, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvb: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgclb(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned char *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; unsigned char nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvb is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TBYTE, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvb: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclb(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ unsigned char *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclb(fptr, 1, row, firstelem, nelem, 1, 1, 0, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned char nulval, /* I - value for null pixels */ unsigned char *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned char *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { unsigned char dummy = 0; ffgclb(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclb( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ unsigned char nulval, /* I - value for null pixels if nultyp = 1 */ unsigned char *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre, ntodo; long ii, xwidth; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; union u_tag { char charval; unsigned char ucharval; } u; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status); /* special case */ if (tcode == TLOGICAL && elemincre == 1) { u.ucharval = nulval; ffgcll(fptr, colnum, firstrow, firstelem, nelem, nultyp, u.charval, (char *) array, nularray, anynul, status); return(*status); } if (strchr(tform,'A') != NULL) { if (*status == BAD_ELEM_NUM) { /* ignore this error message */ *status = 0; ffcmsg(); /* clear error stack */ } /* interpret a 'A' ASCII column as a 'B' byte column ('8A' == '8B') */ /* This is an undocumented 'feature' in CFITSIO */ /* we have to reset some of the values returned by ffgcpr */ tcode = TBYTE; incre = 1; /* each element is 1 byte wide */ repeat = twidth; /* total no. of chars in the col */ twidth = 1; /* width of each element */ scale = 1.0; /* no scaling */ zero = 0.0; tnull = NULL_UNDEFINED; /* don't test for nulls */ maxelem = DBUFFSIZE; } if (*status > 0) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING && hdutype == ASCII_TBL) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default, check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TBYTE) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, &array[next], status); if (convert) fffi1i1(&array[next], ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2i1((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4i1((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8i1( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4i1((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8i1((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); /* interpret the string as an ASCII formated number */ fffstri1((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read bytes from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgclb).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgclb).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgextn( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG offset, /* I - byte offset from start of extension data */ LONGLONG nelem, /* I - number of elements to read */ void *buffer, /* I - stream of bytes to read */ int *status) /* IO - error status */ /* Read a stream of bytes from the current FITS HDU. This primative routine is mainly for reading non-standard "conforming" extensions and should not be used for standard IMAGE, TABLE or BINTABLE extensions. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* move to write position */ ffmbyt(fptr, (fptr->Fptr)->datastart+ offset, IGNORE_EOF, status); /* read the buffer */ ffgbyt(fptr, nelem, buffer, status); return(*status); } /*--------------------------------------------------------------------------*/ int fffi1i1(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { /* this routine is normally not called in this case */ memcpy(output, input, ntodo ); } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2i1(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4i1(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8i1(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4i1(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { /* use redundant boolean logic in following statement */ /* to suppress irritating Borland compiler warning message */ if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8i1(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char nullval,/* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output,/* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstri1(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ unsigned char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } indi-0.5/src/cfitsio/fits_hcompress.c0000644000175000017500000012510610610474374015547 0ustar jrjr/* ######################################################################### These routines to apply the H-compress compression algorithm to a 2-D Fits image were written by R. White at the STScI and were obtained from the STScI at http://www.stsci.edu/software/hcompress.html This source file is a concatination of the following sources files in the original distribution htrans.c digitize.c encode.c qwrite.c doencode.c bit_output.c qtree_encode.c The following modifications have been made to the original code: - commented out redundant "include" statements - added the noutchar global variable - changed all the 'extern' declarations to 'static', since all the routines are in the same source file - changed the first parameter in encode (and in lower level routines from a file stream to a char array - modifid the encode routine to return the size of the compressed array of bytes - changed calls to printf and perror to call the CFITSIO ffpmsg routine - modified the mywrite routine, and lower level byte writing routines, to copy the output bytes to a char array, instead of writing them to a file stream - replace "exit" statements with "return" statements - changed the function declarations to the more modern ANSI C style ############################################################################ */ #include #include #include #include #include "fitsio2.h" static long noutchar; static long noutmax; static int htrans(int a[],int nx,int ny); static void digitize(int a[], int nx, int ny, int scale); static int encode(char *outfile, long *nlen, int a[], int nx, int ny, int scale); static void shuffle(int a[], int n, int n2, int tmp[]); static int htrans64(LONGLONG a[],int nx,int ny); static void digitize64(LONGLONG a[], int nx, int ny, int scale); static int encode64(char *outfile, long *nlen, LONGLONG a[], int nx, int ny, int scale); static void shuffle64(LONGLONG a[], int n, int n2, LONGLONG tmp[]); static void writeint(char *outfile, int a); static void writelonglong(char *outfile, LONGLONG a); static int qwrite(char *outfile, char *a, int n); static int doencode(char *outfile, int a[], int nx, int ny, unsigned char nbitplanes[3]); static int doencode64(char *outfile, LONGLONG a[], int nx, int ny, unsigned char nbitplanes[3]); static int mywrite(char *file, char buffer[], int n); static int qtree_encode(char *outfile, int a[], int n, int nqx, int nqy, int nbitplanes); static int qtree_encode64(char *outfile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes); static void start_outputing_bits(); static void done_outputing_bits(char *outfile); static void output_nbits(char *outfile, int bits, int n); static void qtree_onebit(int a[], int n, int nx, int ny, unsigned char b[], int bit); static void qtree_onebit64(LONGLONG a[], int n, int nx, int ny, unsigned char b[], int bit); static void qtree_reduce(unsigned char a[], int n, int nx, int ny, unsigned char b[]); static int bufcopy(unsigned char a[], int n, unsigned char buffer[], int *b, int bmax); static void write_bdirect(char *outfile, int a[], int n,int nqx, int nqy, unsigned char scratch[], int bit); static void write_bdirect64(char *outfile, LONGLONG a[], int n,int nqx, int nqy, unsigned char scratch[], int bit); #define output_nybble(outfile,c) output_nbits(outfile,c,4) #define output_huffman(outfile,c) output_nbits(outfile,code[c],ncode[c]) /* ---------------------------------------------------------------------- */ int fits_hcompress(int *a, int ny, int nx, int scale, char *output, long *nbytes, int *status) { /* compress the input image using the H-compress algorithm a - input image array nx - size of X axis of image ny - size of Y axis of image scale - quantization scale factor. Larger values results in more (lossy) compression scale = 0 does lossless compression output - pre-allocated array to hold the output compressed stream of bytes nbyts - input value = size of the output buffer; returned value = size of the compressed byte stream, in bytes NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat; if (*status > 0) return(*status); /* H-transform */ stat = htrans(a, nx, ny); if (stat) { *status = stat; return(*status); } /* digitize */ digitize(a, nx, ny, scale); /* encode and write to output array */ noutmax = *nbytes; /* input value is the allocated size of the array */ *nbytes = 0; /* reset */ stat = encode(output, nbytes, a, nx, ny, scale); *status = stat; return(*status); } /* ---------------------------------------------------------------------- */ int fits_hcompress64(LONGLONG *a, int ny, int nx, int scale, char *output, long *nbytes, int *status) { /* compress the input image using the H-compress algorithm a - input image array nx - size of X axis of image ny - size of Y axis of image scale - quantization scale factor. Larger values results in more (lossy) compression scale = 0 does lossless compression output - pre-allocated array to hold the output compressed stream of bytes nbyts - size of the compressed byte stream, in bytes NOTE: the nx and ny dimensions as defined within this code are reversed from the usual FITS notation. ny is the fastest varying dimension, which is usually considered the X axis in the FITS image display */ int stat; if (*status > 0) return(*status); /* H-transform */ stat = htrans64(a, nx, ny); if (stat) { *status = stat; return(*status); } /* digitize */ digitize64(a, nx, ny, scale); /* encode and write to output array */ noutmax = *nbytes; /* input value is the allocated size of the array */ *nbytes = 0; /* reset */ stat = encode64(output, nbytes, a, nx, ny, scale); *status = stat; return(*status); } /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* htrans.c H-transform of NX x NY integer image * * Programmer: R. White Date: 11 May 1992 */ /* ######################################################################### */ static int htrans(int a[],int nx,int ny) { int nmax, log2n, h0, hx, hy, hc, nxtop, nytop, i, j, k; int oddx, oddy; int shift, mask, mask2, prnd, prnd2, nrnd2; int s10, s00; int *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<> shift; hx = (a[s10+1] + a[s10] - a[s00+1] - a[s00]) >> shift; hy = (a[s10+1] - a[s10] + a[s00+1] - a[s00]) >> shift; hc = (a[s10+1] - a[s10] - a[s00+1] + a[s00]) >> shift; /* * Throw away the 2 bottom bits of h0, bottom bit of hx,hy. * To get rounding to be same for positive and negative * numbers, nrnd2 = prnd2 - 1. */ a[s10+1] = hc; a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00+1] = ( (hy>=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = (a[s10] + a[s00]) << (1-shift); hx = (a[s10] - a[s00]) << (1-shift); a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 1; s10 += 1; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = i*ny; for (j = 0; j=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00] << (2-shift); a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; } } /* * now shuffle in each dimension to group coefficients by order */ for (i = 0; i>1; nytop = (nytop+1)>>1; /* * divisor doubles after first reduction */ shift = 1; /* * masks, rounding values double after each iteration */ mask = mask2; prnd = prnd2; mask2 = mask2 << 1; prnd2 = prnd2 << 1; nrnd2 = prnd2 - 1; } free(tmp); return(0); } /* ######################################################################### */ static int htrans64(LONGLONG a[],int nx,int ny) { int nmax, log2n, nxtop, nytop, i, j, k; int oddx, oddy; int shift; int s10, s00; LONGLONG h0, hx, hy, hc, prnd, prnd2, nrnd2, mask, mask2; LONGLONG *tmp; /* * log2n is log2 of max(nx,ny) rounded up to next power of 2 */ nmax = (nx>ny) ? nx : ny; log2n = (int) (log((float) nmax)/log(2.0)+0.5); if ( nmax > (1<> shift; hx = (a[s10+1] + a[s10] - a[s00+1] - a[s00]) >> shift; hy = (a[s10+1] - a[s10] + a[s00+1] - a[s00]) >> shift; hc = (a[s10+1] - a[s10] - a[s00+1] + a[s00]) >> shift; /* * Throw away the 2 bottom bits of h0, bottom bit of hx,hy. * To get rounding to be same for positive and negative * numbers, nrnd2 = prnd2 - 1. */ a[s10+1] = hc; a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00+1] = ( (hy>=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; s10 += 2; } if (oddy) { /* * do last element in row if row length is odd * s00+1, s10+1 are off edge */ h0 = (a[s10] + a[s00]) << (1-shift); hx = (a[s10] - a[s00]) << (1-shift); a[s10 ] = ( (hx>=0) ? (hx+prnd) : hx ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 1; s10 += 1; } } if (oddx) { /* * do last row if column length is odd * s10, s10+1 are off edge */ s00 = i*ny; for (j = 0; j=0) ? (hy+prnd) : hy ) & mask ; a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; s00 += 2; } if (oddy) { /* * do corner element if both row and column lengths are odd * s00+1, s10, s10+1 are off edge */ h0 = a[s00] << (2-shift); a[s00 ] = ( (h0>=0) ? (h0+prnd2) : (h0+nrnd2) ) & mask2; } } /* * now shuffle in each dimension to group coefficients by order */ for (i = 0; i>1; nytop = (nytop+1)>>1; /* * divisor doubles after first reduction */ shift = 1; /* * masks, rounding values double after each iteration */ mask = mask2; prnd = prnd2; mask2 = mask2 << 1; prnd2 = prnd2 << 1; nrnd2 = prnd2 - 1; } free(tmp); return(0); } /* ######################################################################### */ static void shuffle(int a[], int n, int n2, int tmp[]) { /* int a[]; array to shuffle int n; number of elements to shuffle int n2; second dimension int tmp[]; scratch storage */ int i; int *p1, *p2, *pt; /* * copy odd elements to tmp */ pt = tmp; p1 = &a[n2]; for (i=1; i < n; i += 2) { *pt = *p1; pt += 1; p1 += (n2+n2); } /* * compress even elements into first half of A */ p1 = &a[n2]; p2 = &a[n2+n2]; for (i=2; i0) ? (*p+d) : (*p-d))/scale; } /* ######################################################################### */ static void digitize64(LONGLONG a[], int nx, int ny, int scale) { LONGLONG d, *p, scale64; /* * round to multiple of scale */ if (scale <= 1) return; d=(scale+1)/2-1; scale64 = scale; /* use a 64-bit int for efficiency in the big loop */ for (p=a; p <= &a[nx*ny-1]; p++) *p = ((*p>0) ? (*p+d) : (*p-d))/scale64; } /* ######################################################################### */ /* ######################################################################### */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* encode.c encode H-transform and write to outfile * * Programmer: R. White Date: 2 February 1994 */ static char code_magic[2] = { (char)0xDD, (char)0x99 }; /* ######################################################################### */ static int encode(char *outfile, long *nlength, int a[], int nx, int ny, int scale) { /* FILE *outfile; - change outfile to a char array */ /* long * nlength returned length (in bytes) of the encoded array) int a[]; input H-transform array (nx,ny) int nx,ny; size of H-transform array int scale; scale factor for digitization */ int nel, nx2, ny2, i, j, k, q, vmax[3], nsign, bits_to_go; unsigned char nbitplanes[3]; unsigned char *signbits; int stat = 0; noutchar = 0; /* initialize the number of compressed bytes that have been written */ nel = nx*ny; /* * write magic value */ qwrite(outfile, code_magic, sizeof(code_magic)); writeint(outfile, nx); /* size of image */ writeint(outfile, ny); writeint(outfile, scale); /* scale factor for digitization */ /* * write first value of A (sum of all pixels -- the only value * which does not compress well) */ writelonglong(outfile, (LONGLONG) a[0]); a[0] = 0; /* * allocate array for sign bits and save values, 8 per byte */ signbits = (unsigned char *) malloc((nel+7)/8); if (signbits == (unsigned char *) NULL) { /* fprintf(stderr, "encode: insufficient memory\n"); exit(-1); */ ffpmsg("encode: insufficient memory"); return(DATA_COMPRESSION_ERR); } nsign = 0; bits_to_go = 8; signbits[0] = 0; for (i=0; i 0) { /* * positive element, put zero at end of buffer */ signbits[nsign] <<= 1; bits_to_go -= 1; } else if (a[i] < 0) { /* * negative element, shift in a one */ signbits[nsign] <<= 1; signbits[nsign] |= 1; bits_to_go -= 1; /* * replace a by absolute value */ a[i] = -a[i]; } if (bits_to_go == 0) { /* * filled up this byte, go to the next one */ bits_to_go = 8; nsign += 1; signbits[nsign] = 0; } } if (bits_to_go != 8) { /* * some bits in last element * move bits in last byte to bottom and increment nsign */ signbits[nsign] <<= bits_to_go; nsign += 1; } /* * calculate number of bit planes for 3 quadrants * * quadrant 0=bottom left, 1=bottom right or top left, 2=top right, */ for (q=0; q<3; q++) { vmax[q] = 0; } /* * get maximum absolute value in each quadrant */ nx2 = (nx+1)/2; ny2 = (ny+1)/2; j=0; /* column counter */ k=0; /* row counter */ for (i=0; i=ny2) + (k>=nx2); if (vmax[q] < a[i]) vmax[q] = a[i]; if (++j >= ny) { j = 0; k += 1; } } /* * now calculate number of bits for each quadrant */ for (q = 0; q < 3; q++) { nbitplanes[q] = (int) (log((float) (vmax[q]+1))/log(2.0)+0.5); if ( (vmax[q]+1) > (1< 0) { if ( 0 == qwrite(outfile, (char *) signbits, nsign)) { free(signbits); *nlength = noutchar; ffpmsg("encode: output buffer too small"); return(DATA_COMPRESSION_ERR); } } free(signbits); *nlength = noutchar; if (noutchar >= noutmax) { ffpmsg("encode: output buffer too small"); return(DATA_COMPRESSION_ERR); } return(stat); } /* ######################################################################### */ static int encode64(char *outfile, long *nlength, LONGLONG a[], int nx, int ny, int scale) { /* FILE *outfile; - change outfile to a char array */ /* long * nlength returned length (in bytes) of the encoded array) LONGLONG a[]; input H-transform array (nx,ny) int nx,ny; size of H-transform array int scale; scale factor for digitization */ int nel, nx2, ny2, i, j, k, q, nsign, bits_to_go; LONGLONG vmax[3]; unsigned char nbitplanes[3]; unsigned char *signbits; int stat = 0; noutchar = 0; /* initialize the number of compressed bytes that have been written */ nel = nx*ny; /* * write magic value */ qwrite(outfile, code_magic, sizeof(code_magic)); writeint(outfile, nx); /* size of image */ writeint(outfile, ny); writeint(outfile, scale); /* scale factor for digitization */ /* * write first value of A (sum of all pixels -- the only value * which does not compress well) */ writelonglong(outfile, a[0]); a[0] = 0; /* * allocate array for sign bits and save values, 8 per byte */ signbits = (unsigned char *) malloc((nel+7)/8); if (signbits == (unsigned char *) NULL) { /* fprintf(stderr, "encode: insufficient memory\n"); exit(-1); */ ffpmsg("encode64: insufficient memory"); return(DATA_COMPRESSION_ERR); } nsign = 0; bits_to_go = 8; signbits[0] = 0; for (i=0; i 0) { /* * positive element, put zero at end of buffer */ signbits[nsign] <<= 1; bits_to_go -= 1; } else if (a[i] < 0) { /* * negative element, shift in a one */ signbits[nsign] <<= 1; signbits[nsign] |= 1; bits_to_go -= 1; /* * replace a by absolute value */ a[i] = -a[i]; } if (bits_to_go == 0) { /* * filled up this byte, go to the next one */ bits_to_go = 8; nsign += 1; signbits[nsign] = 0; } } if (bits_to_go != 8) { /* * some bits in last element * move bits in last byte to bottom and increment nsign */ signbits[nsign] <<= bits_to_go; nsign += 1; } /* * calculate number of bit planes for 3 quadrants * * quadrant 0=bottom left, 1=bottom right or top left, 2=top right, */ for (q=0; q<3; q++) { vmax[q] = 0; } /* * get maximum absolute value in each quadrant */ nx2 = (nx+1)/2; ny2 = (ny+1)/2; i = 0; for (k=0; k=ny2) + (k>=nx2); vmax[q] |= a[i]; i++; } } /* * now calculate number of bits for each quadrant */ /* this is a more efficient way to do this, */ for (q = 0; q < 3; q++) { for (nbitplanes[q] = 0; vmax[q]>0; vmax[q] = vmax[q]>>1, nbitplanes[q]++) ; } /* for (q = 0; q < 3; q++) { nbitplanes[q] = log((float) (vmax[q]+1))/log(2.0)+0.5; if ( (vmax[q]+1) > (((LONGLONG) 1)< 0) { if ( 0 == qwrite(outfile, (char *) signbits, nsign)) { free(signbits); *nlength = noutchar; ffpmsg("encode: output buffer too small"); return(DATA_COMPRESSION_ERR); } } free(signbits); *nlength = noutchar; if (noutchar >= noutmax) { ffpmsg("encode64: output buffer too small"); return(DATA_COMPRESSION_ERR); } return(stat); } /* ######################################################################### */ /* ######################################################################### */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* qwrite.c Write binary data * * Programmer: R. White Date: 11 March 1991 */ /* ######################################################################### */ static void writeint(char *outfile, int a) { int i; unsigned char b[4]; /* Write integer A one byte at a time to outfile. * * This is portable from Vax to Sun since it eliminates the * need for byte-swapping. */ for (i=3; i>=0; i--) { b[i] = a & 0x000000ff; a >>= 8; } for (i=0; i<4; i++) qwrite(outfile, (char *) &b[i],1); } /* ######################################################################### */ static void writelonglong(char *outfile, LONGLONG a) { int i; unsigned char b[8]; /* Write integer A one byte at a time to outfile. * * This is portable from Vax to Sun since it eliminates the * need for byte-swapping. */ for (i=7; i>=0; i--) { b[i] = (unsigned char) (a & 0x000000ff); a >>= 8; } for (i=0; i<8; i++) qwrite(outfile, (char *) &b[i],1); } /* ######################################################################### */ static int qwrite(char *outfile, char *a, int n) { int nwrite; nwrite = mywrite(outfile, a, n); return(nwrite); /* added by WDP to prevent compiler warning */ } /* ######################################################################### */ static int mywrite(char *file, char buffer[], int n) { /* * write n bytes from buffer into file * returns number of bytes read (=n) if successful, <=0 if not */ if (noutchar + n > noutmax) return(0); /* buffer overflow */ memcpy(&file[noutchar], buffer, n); noutchar += n; return(n); } /* ######################################################################### */ /* ######################################################################### */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* doencode.c Encode 2-D array and write stream of characters on outfile * * This version assumes that A is positive. * * Programmer: R. White Date: 7 May 1991 */ /* ######################################################################### */ static int doencode(char *outfile, int a[], int nx, int ny, unsigned char nbitplanes[3]) { /* char *outfile; output data stream int a[]; Array of values to encode int nx,ny; Array dimensions [nx][ny] unsigned char nbitplanes[3]; Number of bit planes in quadrants */ int nx2, ny2, stat = 0; nx2 = (nx+1)/2; ny2 = (ny+1)/2; /* * Initialize bit output */ start_outputing_bits(); /* * write out the bit planes for each quadrant */ stat = qtree_encode(outfile, &a[0], ny, nx2, ny2, nbitplanes[0]); if (!stat) stat = qtree_encode(outfile, &a[ny2], ny, nx2, ny/2, nbitplanes[1]); if (!stat) stat = qtree_encode(outfile, &a[ny*nx2], ny, nx/2, ny2, nbitplanes[1]); if (!stat) stat = qtree_encode(outfile, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2]); /* * Add zero as an EOF symbol */ output_nybble(outfile, 0); done_outputing_bits(outfile); return(stat); } /* ######################################################################### */ static int doencode64(char *outfile, LONGLONG a[], int nx, int ny, unsigned char nbitplanes[3]) { /* char *outfile; output data stream LONGLONG a[]; Array of values to encode int nx,ny; Array dimensions [nx][ny] unsigned char nbitplanes[3]; Number of bit planes in quadrants */ int nx2, ny2, stat = 0; nx2 = (nx+1)/2; ny2 = (ny+1)/2; /* * Initialize bit output */ start_outputing_bits(); /* * write out the bit planes for each quadrant */ stat = qtree_encode64(outfile, &a[0], ny, nx2, ny2, nbitplanes[0]); if (!stat) stat = qtree_encode64(outfile, &a[ny2], ny, nx2, ny/2, nbitplanes[1]); if (!stat) stat = qtree_encode64(outfile, &a[ny*nx2], ny, nx/2, ny2, nbitplanes[1]); if (!stat) stat = qtree_encode64(outfile, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2]); /* * Add zero as an EOF symbol */ output_nybble(outfile, 0); done_outputing_bits(outfile); return(stat); } /* ######################################################################### */ /* ######################################################################### */ /* Copyright (c) 1993 Association of Universities for Research * in Astronomy. All rights reserved. Produced under National * Aeronautics and Space Administration Contract No. NAS5-26555. */ /* BIT OUTPUT ROUTINES */ static LONGLONG bitcount; /* THE BIT BUFFER */ static int buffer2; /* Bits buffered for output */ static int bits_to_go2; /* Number of bits free in buffer */ /* ######################################################################### */ /* INITIALIZE FOR BIT OUTPUT */ static void start_outputing_bits() { buffer2 = 0; /* Buffer is empty to start */ bits_to_go2 = 8; /* with */ bitcount = 0; } /* ######################################################################### */ /* OUTPUT N BITS (N must be <= 8) */ static void output_nbits(char *outfile, int bits, int n) { /* * insert bits at end of buffer */ buffer2 <<= n; buffer2 |= ( bits & ((1<>(-bits_to_go2)) & 0xff,outfile); */ outfile[noutchar] = ((buffer2>>(-bits_to_go2)) & 0xff); if (noutchar < noutmax) noutchar++; bits_to_go2 += 8; } bitcount += n; } /* ######################################################################### */ /* FLUSH OUT THE LAST BITS */ static void done_outputing_bits(char *outfile) { if(bits_to_go2 < 8) { /* putc(buffer2<nqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<= 0; bit--) { /* * initial bit buffer */ b = 0; bitbuffer = 0; bits_to_go3 = 0; /* * on first pass copy A to scratch array */ qtree_onebit(a,n,nqx,nqy,scratch,bit); nx = (nqx+1)>>1; ny = (nqy+1)>>1; /* * copy non-zero values to output buffer, which will be written * in reverse order */ if (bufcopy(scratch,nx*ny,buffer,&b,bmax)) { /* * quadtree is expanding data, * change warning code and just fill buffer with bit-map */ write_bdirect(outfile,a,n,nqx,nqy,scratch,bit); goto bitplane_done; } /* * do log2n reductions */ for (k = 1; k>1; ny = (ny+1)>>1; if (bufcopy(scratch,nx*ny,buffer,&b,bmax)) { write_bdirect(outfile,a,n,nqx,nqy,scratch,bit); goto bitplane_done; } } /* * OK, we've got the code in buffer * Write quadtree warning code, then write buffer in reverse order */ output_nybble(outfile,0xF); if (b==0) { if (bits_to_go3>0) { /* * put out the last few bits */ output_nbits(outfile, bitbuffer & ((1<0) { /* * put out the last few bits */ output_nbits(outfile, bitbuffer & ((1<=0; i--) { output_nbits(outfile,buffer[i],8); } } bitplane_done: ; } free(buffer); free(scratch); return(0); } /* ######################################################################### */ static int qtree_encode64(char *outfile, LONGLONG a[], int n, int nqx, int nqy, int nbitplanes) { /* LONGLONG a[]; int n; physical dimension of row in a int nqx; length of row int nqy; length of column (<=n) int nbitplanes; number of bit planes to output */ int log2n, i, k, bit, b, nqmax, nqx2, nqy2, nx, ny; int bmax; /* this potentially needs to be made a 64-bit int to support large arrays */ unsigned char *scratch, *buffer; /* * log2n is log2 of max(nqx,nqy) rounded up to next power of 2 */ nqmax = (nqx>nqy) ? nqx : nqy; log2n = (int) (log((float) nqmax)/log(2.0)+0.5); if (nqmax > (1<= 0; bit--) { /* * initial bit buffer */ b = 0; bitbuffer = 0; bits_to_go3 = 0; /* * on first pass copy A to scratch array */ qtree_onebit64(a,n,nqx,nqy,scratch,bit); nx = (nqx+1)>>1; ny = (nqy+1)>>1; /* * copy non-zero values to output buffer, which will be written * in reverse order */ if (bufcopy(scratch,nx*ny,buffer,&b,bmax)) { /* * quadtree is expanding data, * change warning code and just fill buffer with bit-map */ write_bdirect64(outfile,a,n,nqx,nqy,scratch,bit); goto bitplane_done; } /* * do log2n reductions */ for (k = 1; k>1; ny = (ny+1)>>1; if (bufcopy(scratch,nx*ny,buffer,&b,bmax)) { write_bdirect64(outfile,a,n,nqx,nqy,scratch,bit); goto bitplane_done; } } /* * OK, we've got the code in buffer * Write quadtree warning code, then write buffer in reverse order */ output_nybble(outfile,0xF); if (b==0) { if (bits_to_go3>0) { /* * put out the last few bits */ output_nbits(outfile, bitbuffer & ((1<0) { /* * put out the last few bits */ output_nbits(outfile, bitbuffer & ((1<=0; i--) { output_nbits(outfile,buffer[i],8); } } bitplane_done: ; } free(buffer); free(scratch); return(0); } /* ######################################################################### */ /* * copy non-zero codes from array to buffer */ static int bufcopy(unsigned char a[], int n, unsigned char buffer[], int *b, int bmax) { int i; for (i = 0; i < n; i++) { if (a[i] != 0) { /* * add Huffman code for a[i] to buffer */ bitbuffer |= code[a[i]] << bits_to_go3; bits_to_go3 += ncode[a[i]]; if (bits_to_go3 >= 8) { buffer[*b] = bitbuffer & 0xFF; *b += 1; /* * return warning code if we fill buffer */ if (*b >= bmax) return(1); bitbuffer >>= 8; bits_to_go3 -= 8; } } } return(0); } /* ######################################################################### */ /* * Do first quadtree reduction step on bit BIT of array A. * Results put into B. * */ static void qtree_onebit(int a[], int n, int nx, int ny, unsigned char b[], int bit) { int i, j, k; int b0, b1, b2, b3; int s10, s00; /* * use selected bit to get amount to shift */ b0 = 1<> bit; k += 1; s00 += 2; s10 += 2; } if (j < ny) { /* * row size is odd, do last element in row * s00+1,s10+1 are off edge */ b[k] = ( ((a[s10 ]<<1) & b1) | ((a[s00 ]<<3) & b3) ) >> bit; k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10,s10+1 are off edge */ s00 = n*i; for (j = 0; j> bit; k += 1; s00 += 2; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[k] = ( ((a[s00 ]<<3) & b3) ) >> bit; k += 1; } } } /* ######################################################################### */ /* * Do first quadtree reduction step on bit BIT of array A. * Results put into B. * */ static void qtree_onebit64(LONGLONG a[], int n, int nx, int ny, unsigned char b[], int bit) { int i, j, k; LONGLONG b0, b1, b2, b3; int s10, s00; /* * use selected bit to get amount to shift */ b0 = ((LONGLONG) 1)<> bit); k += 1; s00 += 2; s10 += 2; } if (j < ny) { /* * row size is odd, do last element in row * s00+1,s10+1 are off edge */ b[k] = (unsigned char) (( ((a[s10 ]<<1) & b1) | ((a[s00 ]<<3) & b3) ) >> bit); k += 1; } } if (i < nx) { /* * column size is odd, do last row * s10,s10+1 are off edge */ s00 = n*i; for (j = 0; j> bit); k += 1; s00 += 2; } if (j < ny) { /* * both row and column size are odd, do corner element * s00+1, s10, s10+1 are off edge */ b[k] = (unsigned char) (( ((a[s00 ]<<3) & b3) ) >> bit); k += 1; } } } /* ######################################################################### */ /* * do one quadtree reduction step on array a * results put into b (which may be the same as a) */ static void qtree_reduce(unsigned char a[], int n, int nx, int ny, unsigned char b[]) { int i, j, k; int s10, s00; k = 0; /* k is index of b[i/2,j/2] */ for (i = 0; i 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpcls).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); if (blanks) free(blanks); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ if (blanks) free(blanks); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcns( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ char **array, /* I - array of values to write */ char *nulvalue, /* I - string representing a null value */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels flagged as null will be replaced by the appropriate null value in the output FITS file. */ { long repeat, width, ngood = 0, nbad = 0, ii; LONGLONG first, fstelm, fstrow; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } /* get the vector repeat length of the column */ ffgtcl(fptr, colnum, NULL, &repeat, &width, status); if ((fptr->Fptr)->hdutype == BINARY_TBL) repeat = repeat / width; /* convert from chars to unit strings */ /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (strcmp(nulvalue, array[ii])) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpcls(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) return(*status); ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpcls(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } return(*status); } indi-0.5/src/cfitsio/iraffits.c0000644000175000017500000015156010610474375014332 0ustar jrjr/*------------------------------------------------------------------------*/ /* */ /* These routines have been modified by William Pence for use by CFITSIO */ /* The original files were provided by Doug Mink */ /*------------------------------------------------------------------------*/ /* File imhfile.c * August 6, 1998 * By Doug Mink, based on Mike VanHilst's readiraf.c * Module: imhfile.c (IRAF .imh image file reading and writing) * Purpose: Read and write IRAF image files (and translate headers) * Subroutine: irafrhead (filename, lfhead, fitsheader, lihead) * Read IRAF image header * Subroutine: irafrimage (fitsheader) * Read IRAF image pixels (call after irafrhead) * Subroutine: same_path (pixname, hdrname) * Put filename and header path together * Subroutine: iraf2fits (hdrname, irafheader, nbiraf, nbfits) * Convert IRAF image header to FITS image header * Subroutine: irafgeti4 (irafheader, offset) * Get 4-byte integer from arbitrary part of IRAF header * Subroutine: irafgetc2 (irafheader, offset) * Get character string from arbitrary part of IRAF v.1 header * Subroutine: irafgetc (irafheader, offset) * Get character string from arbitrary part of IRAF header * Subroutine: iraf2str (irafstring, nchar) * Convert 2-byte/char IRAF string to 1-byte/char string * Subroutine: irafswap (bitpix,string,nbytes) * Swap bytes in string in place, with FITS bits/pixel code * Subroutine: irafswap2 (string,nbytes) * Swap bytes in string in place * Subroutine irafswap4 (string,nbytes) * Reverse bytes of Integer*4 or Real*4 vector in place * Subroutine irafswap8 (string,nbytes) * Reverse bytes of Real*8 vector in place * Copyright: 2000 Smithsonian Astrophysical Observatory * You may do anything you like with this file except remove * this copyright. The Smithsonian Astrophysical Observatory * makes no representations about the suitability of this * software for any purpose. It is provided "as is" without * express or implied warranty. */ #include /* define stderr, FD, and NULL */ #include #include /* stddef.h is apparently needed to define size_t */ #include #define FILE_NOT_OPENED 104 /* Parameters from iraf/lib/imhdr.h for IRAF version 1 images */ #define SZ_IMPIXFILE 79 /* name of pixel storage file */ #define SZ_IMHDRFILE 79 /* length of header storage file */ #define SZ_IMTITLE 79 /* image title string */ #define LEN_IMHDR 2052 /* length of std header */ /* Parameters from iraf/lib/imhdr.h for IRAF version 2 images */ #define SZ_IM2PIXFILE 255 /* name of pixel storage file */ #define SZ_IM2HDRFILE 255 /* name of header storage file */ #define SZ_IM2TITLE 383 /* image title string */ #define LEN_IM2HDR 2046 /* length of std header */ /* Offsets into header in bytes for parameters in IRAF version 1 images */ #define IM_HDRLEN 12 /* Length of header in 4-byte ints */ #define IM_PIXTYPE 16 /* Datatype of the pixels */ #define IM_NDIM 20 /* Number of dimensions */ #define IM_LEN 24 /* Length (as stored) */ #define IM_PHYSLEN 52 /* Physical length (as stored) */ #define IM_PIXOFF 88 /* Offset of the pixels */ #define IM_CTIME 108 /* Time of image creation */ #define IM_MTIME 112 /* Time of last modification */ #define IM_LIMTIME 116 /* Time of min,max computation */ #define IM_MAX 120 /* Maximum pixel value */ #define IM_MIN 124 /* Maximum pixel value */ #define IM_PIXFILE 412 /* Name of pixel storage file */ #define IM_HDRFILE 572 /* Name of header storage file */ #define IM_TITLE 732 /* Image name string */ /* Offsets into header in bytes for parameters in IRAF version 2 images */ #define IM2_HDRLEN 6 /* Length of header in 4-byte ints */ #define IM2_PIXTYPE 10 /* Datatype of the pixels */ #define IM2_SWAPPED 14 /* Pixels are byte swapped */ #define IM2_NDIM 18 /* Number of dimensions */ #define IM2_LEN 22 /* Length (as stored) */ #define IM2_PHYSLEN 50 /* Physical length (as stored) */ #define IM2_PIXOFF 86 /* Offset of the pixels */ #define IM2_CTIME 106 /* Time of image creation */ #define IM2_MTIME 110 /* Time of last modification */ #define IM2_LIMTIME 114 /* Time of min,max computation */ #define IM2_MAX 118 /* Maximum pixel value */ #define IM2_MIN 122 /* Maximum pixel value */ #define IM2_PIXFILE 126 /* Name of pixel storage file */ #define IM2_HDRFILE 382 /* Name of header storage file */ #define IM2_TITLE 638 /* Image name string */ /* Codes from iraf/unix/hlib/iraf.h */ #define TY_CHAR 2 #define TY_SHORT 3 #define TY_INT 4 #define TY_LONG 5 #define TY_REAL 6 #define TY_DOUBLE 7 #define TY_COMPLEX 8 #define TY_POINTER 9 #define TY_STRUCT 10 #define TY_USHORT 11 #define TY_UBYTE 12 #define LEN_PIXHDR 1024 #define MAXINT 2147483647 /* Biggest number that can fit in long */ static int isirafswapped(char *irafheader, int offset); static int irafgeti4(char *irafheader, int offset); static char *irafgetc2(char *irafheader, int offset, int nc); static char *irafgetc(char *irafheader, int offset, int nc); static char *iraf2str(char *irafstring, int nchar); static char *irafrdhead(char *filename, int *lihead); static int irafrdimage (char **buffptr, size_t *buffsize, size_t *filesize, int *status); static int iraftofits (char *hdrname, char *irafheader, int nbiraf, char **buffptr, size_t *nbfits, size_t *fitssize, int *status); static char *same_path(char *pixname, char *hdrname); static int swaphead=0; /* =1 to swap data bytes of IRAF header values */ static int swapdata=0; /* =1 to swap bytes in IRAF data pixels */ static void irafswap(int bitpix, char *string, int nbytes); static void irafswap2(char *string, int nbytes); static void irafswap4(char *string, int nbytes); static void irafswap8(char *string, int nbytes); static int pix_version (char *irafheader); static int irafncmp (char *irafheader, char *teststring, int nc); static int machswap(void); static int head_version (char *irafheader); static int hgeti4(char* hstring, char* keyword, int* val); static int hgets(char* hstring, char* keyword, int lstr, char* string); static char* hgetc(char* hstring, char* keyword); static char* ksearch(char* hstring, char* keyword); static char *blsearch (char* hstring, char* keyword); static char *strsrch (char* s1, char* s2); static char *strnsrch ( char* s1,char* s2,int ls1); static void hputi4(char* hstring,char* keyword, int ival); static void hputs(char* hstring,char* keyword,char* cval); static void hputcom(char* hstring,char* keyword,char* comment); static void hputl(char* hstring,char* keyword,int lval); static void hputc(char* hstring,char* keyword,char* cval); int iraf2mem(char *filename, char **buffptr, size_t *buffsize, size_t *filesize, int *status); void ffpmsg(const char *err_message); /*--------------------------------------------------------------------------*/ int iraf2mem(char *filename, /* name of input file */ char **buffptr, /* O - memory pointer (initially NULL) */ size_t *buffsize, /* O - size of mem buffer, in bytes */ size_t *filesize, /* O - size of FITS file, in bytes */ int *status) /* IO - error status */ /* Driver routine that reads an IRAF image into memory, also converting it into FITS format. */ { char *irafheader; int lenirafhead; *buffptr = NULL; *buffsize = 0; *filesize = 0; /* read IRAF header into dynamically created char array (free it later!) */ irafheader = irafrdhead(filename, &lenirafhead); if (!irafheader) { return(*status = FILE_NOT_OPENED); } /* convert IRAF header to FITS header in memory */ iraftofits(filename, irafheader, lenirafhead, buffptr, buffsize, filesize, status); /* don't need the IRAF header any more */ free(irafheader); if (*status > 0) return(*status); *filesize = (((*filesize - 1) / 2880 ) + 1 ) * 2880; /* multiple of 2880 */ /* append the image data onto the FITS header */ irafrdimage(buffptr, buffsize, filesize, status); return(*status); } /*--------------------------------------------------------------------------*/ /* Subroutine: irafrdhead (was irafrhead in D. Mink's original code) * Purpose: Open and read the iraf .imh file. * Returns: NULL if failure, else pointer to IRAF .imh image header * Notes: The imhdr format is defined in iraf/lib/imhdr.h, some of * which defines or mimicked, above. */ static char *irafrdhead ( char *filename, /* Name of IRAF header file */ int *lihead) /* Length of IRAF image header in bytes (returned) */ { FILE *fd; int nbr; char *irafheader; char errmsg[81]; long nbhead; int nihead; *lihead = 0; /* open the image header file */ fd = fopen (filename, "rb"); if (fd == NULL) { ffpmsg("unable to open IRAF header file:"); ffpmsg(filename); return (NULL); } /* Find size of image header file */ if (fseek(fd, 0, 2) != 0) /* move to end of the file */ { ffpmsg("IRAFRHEAD: cannot seek in file:"); ffpmsg(filename); return(NULL); } nbhead = ftell(fd); /* position = size of file */ if (nbhead < 0) { ffpmsg("IRAFRHEAD: cannot get pos. in file:"); ffpmsg(filename); return(NULL); } if (fseek(fd, 0, 0) != 0) /* move back to beginning */ { ffpmsg("IRAFRHEAD: cannot seek to beginning of file:"); ffpmsg(filename); return(NULL); } /* allocate initial sized buffer */ nihead = nbhead + 5000; irafheader = (char *) calloc (1, nihead); if (irafheader == NULL) { sprintf(errmsg, "IRAFRHEAD Cannot allocate %d-byte header", nihead); ffpmsg(errmsg); ffpmsg(filename); return (NULL); } *lihead = nihead; /* Read IRAF header */ nbr = fread (irafheader, 1, nbhead, fd); fclose (fd); /* Reject if header less than minimum length */ if (nbr < LEN_PIXHDR) { sprintf(errmsg, "IRAFRHEAD header file: %d / %d bytes read.", nbr,LEN_PIXHDR); ffpmsg(errmsg); ffpmsg(filename); free (irafheader); return (NULL); } return (irafheader); } /*--------------------------------------------------------------------------*/ static int irafrdimage ( char **buffptr, /* FITS image header (filled) */ size_t *buffsize, /* allocated size of the buffer */ size_t *filesize, /* actual size of the FITS file */ int *status) { FILE *fd; char *bang; int nax = 1, naxis1 = 1, naxis2 = 1, naxis3 = 1, naxis4 = 1, npaxis1 = 1, npaxis2; int bitpix, bytepix, i; char *fitsheader, *image; int nbr, nbimage, nbaxis, nbl, nbx, nbdiff; char *pixheader; char *linebuff; int imhver, lpixhead = 0; char pixname[SZ_IM2PIXFILE+1]; char errmsg[81]; size_t newfilesize; fitsheader = *buffptr; /* pointer to start of header */ image = fitsheader + *filesize; /* pointer to start of the data */ /* Convert pixel file name to character string */ hgets (fitsheader, "PIXFILE", SZ_IM2PIXFILE, pixname); hgeti4 (fitsheader, "PIXOFF", &lpixhead); /* Open pixel file, ignoring machine name if present */ if ((bang = strchr (pixname, '!')) != NULL ) fd = fopen (bang + 1, "rb"); else fd = fopen (pixname, "rb"); /* Print error message and exit if pixel file is not found */ if (!fd) { ffpmsg("IRAFRIMAGE: Cannot open IRAF pixel file:"); ffpmsg(pixname); return (*status = FILE_NOT_OPENED); } /* Read pixel header */ pixheader = (char *) calloc (lpixhead, 1); if (pixheader == NULL) { ffpmsg("IRAFRIMAGE: Cannot alloc memory for pixel header"); ffpmsg(pixname); fclose (fd); return (*status = FILE_NOT_OPENED); } nbr = fread (pixheader, 1, lpixhead, fd); /* Check size of pixel header */ if (nbr < lpixhead) { sprintf(errmsg, "IRAF pixel file: %d / %d bytes read.", nbr,LEN_PIXHDR); ffpmsg(errmsg); free (pixheader); fclose (fd); return (*status = FILE_NOT_OPENED); } /* check pixel header magic word */ imhver = pix_version (pixheader); if (imhver < 1) { ffpmsg("File not valid IRAF pixel file:"); ffpmsg(pixname); free (pixheader); fclose (fd); return (*status = FILE_NOT_OPENED); } free (pixheader); /* Find number of bytes to read */ hgeti4 (fitsheader,"NAXIS",&nax); hgeti4 (fitsheader,"NAXIS1",&naxis1); hgeti4 (fitsheader,"NPAXIS1",&npaxis1); if (nax > 1) { hgeti4 (fitsheader,"NAXIS2",&naxis2); hgeti4 (fitsheader,"NPAXIS2",&npaxis2); } if (nax > 2) hgeti4 (fitsheader,"NAXIS3",&naxis3); if (nax > 3) hgeti4 (fitsheader,"NAXIS4",&naxis4); hgeti4 (fitsheader,"BITPIX",&bitpix); if (bitpix < 0) bytepix = -bitpix / 8; else bytepix = bitpix / 8; nbimage = naxis1 * naxis2 * naxis3 * naxis4 * bytepix; newfilesize = *filesize + nbimage; /* header + data */ newfilesize = (((newfilesize - 1) / 2880 ) + 1 ) * 2880; if (newfilesize > *buffsize) /* need to allocate more memory? */ { fitsheader = (char *) realloc (*buffptr, newfilesize); if (fitsheader == NULL) { sprintf(errmsg, "IRAFRIMAGE Cannot allocate %d-byte image buffer", (int) (*filesize)); ffpmsg(errmsg); ffpmsg(pixname); fclose (fd); return (*status = FILE_NOT_OPENED); } } *buffptr = fitsheader; *buffsize = newfilesize; image = fitsheader + *filesize; *filesize = newfilesize; /* Read IRAF image all at once if physical and image dimensions are the same */ if (npaxis1 == naxis1) nbr = fread (image, 1, nbimage, fd); /* Read IRAF image one line at a time if physical and image dimensions differ */ else { nbdiff = (npaxis1 - naxis1) * bytepix; nbaxis = naxis1 * bytepix; linebuff = image; nbr = 0; if (naxis2 == 1 && naxis3 > 1) naxis2 = naxis3; for (i = 0; i < naxis2; i++) { nbl = fread (linebuff, 1, nbaxis, fd); nbr = nbr + nbl; nbx = fseek (fd, nbdiff, 1); linebuff = linebuff + nbaxis; } } fclose (fd); /* Check size of image */ if (nbr < nbimage) { sprintf(errmsg, "IRAF pixel file: %d / %d bytes read.", nbr,nbimage); ffpmsg(errmsg); ffpmsg(pixname); return (*status = FILE_NOT_OPENED); } /* Byte-reverse image, if necessary */ if (swapdata) irafswap (bitpix, image, nbimage); return (*status); } /*--------------------------------------------------------------------------*/ /* Return IRAF image format version number from magic word in IRAF header*/ static int head_version ( char *irafheader) /* IRAF image header from file */ { /* Check header file magic word */ if (irafncmp (irafheader, "imhdr", 5) != 0 ) { if (strncmp (irafheader, "imhv2", 5) != 0) return (0); else return (2); } else return (1); } /*--------------------------------------------------------------------------*/ /* Return IRAF image format version number from magic word in IRAF pixel file */ static int pix_version ( char *irafheader) /* IRAF image header from file */ { /* Check pixel file header magic word */ if (irafncmp (irafheader, "impix", 5) != 0) { if (strncmp (irafheader, "impv2", 5) != 0) return (0); else return (2); } else return (1); } /*--------------------------------------------------------------------------*/ /* Verify that file is valid IRAF imhdr or impix by checking first 5 chars * Returns: 0 on success, 1 on failure */ static int irafncmp ( char *irafheader, /* IRAF image header from file */ char *teststring, /* C character string to compare */ int nc) /* Number of characters to compate */ { char *line; if ((line = iraf2str (irafheader, nc)) == NULL) return (1); if (strncmp (line, teststring, nc) == 0) { free (line); return (0); } else { free (line); return (1); } } /*--------------------------------------------------------------------------*/ /* Convert IRAF image header to FITS image header, returning FITS header */ static int iraftofits ( char *hdrname, /* IRAF header file name (may be path) */ char *irafheader, /* IRAF image header */ int nbiraf, /* Number of bytes in IRAF header */ char **buffptr, /* pointer to the FITS header */ size_t *nbfits, /* allocated size of the FITS header buffer */ size_t *fitssize, /* Number of bytes in FITS header (returned) */ /* = number of bytes to the end of the END keyword */ int *status) { char *objname; /* object name from FITS file */ int lstr, i, j, k, ib, nax, nbits; char *pixname, *newpixname, *bang, *chead; char *fitsheader; int nblock, nlines; char *fhead, *fhead1, *fp, endline[81]; char irafchar; char fitsline[81]; int pixtype; int imhver, n, imu, pixoff, impixoff, immax, immin, imtime; int imndim, imlen, imphyslen, impixtype; char errmsg[81]; /* Set up last line of FITS header */ (void)strncpy (endline,"END", 3); for (i = 3; i < 80; i++) endline[i] = ' '; endline[80] = 0; /* Check header magic word */ imhver = head_version (irafheader); if (imhver < 1) { ffpmsg("File not valid IRAF image header"); ffpmsg(hdrname); return(*status = FILE_NOT_OPENED); } if (imhver == 2) { nlines = 24 + ((nbiraf - LEN_IM2HDR) / 81); imndim = IM2_NDIM; imlen = IM2_LEN; imphyslen = IM2_PHYSLEN; impixtype = IM2_PIXTYPE; impixoff = IM2_PIXOFF; imtime = IM2_MTIME; immax = IM2_MAX; immin = IM2_MIN; } else { nlines = 24 + ((nbiraf - LEN_IMHDR) / 162); imndim = IM_NDIM; imlen = IM_LEN; imphyslen = IM_PHYSLEN; impixtype = IM_PIXTYPE; impixoff = IM_PIXOFF; imtime = IM_MTIME; immax = IM_MAX; immin = IM_MIN; } /* Initialize FITS header */ nblock = (nlines * 80) / 2880; *nbfits = (nblock + 5) * 2880 + 4; fitsheader = (char *) calloc (*nbfits, 1); if (fitsheader == NULL) { sprintf(errmsg, "IRAF2FITS Cannot allocate %d-byte FITS header", (int) (*nbfits)); ffpmsg(hdrname); return (*status = FILE_NOT_OPENED); } fhead = fitsheader; *buffptr = fitsheader; (void)strncpy (fitsheader, endline, 80); hputl (fitsheader, "SIMPLE", 1); fhead = fhead + 80; /* check if the IRAF file is in big endian (sun) format (= 0) or not. */ /* This is done by checking the 4 byte integer in the header that */ /* represents the iraf pixel type. This 4-byte word is guaranteed to */ /* have the least sig byte != 0 and the most sig byte = 0, so if the */ /* first byte of the word != 0, then the file in little endian format */ /* like on an Alpha machine. */ swaphead = isirafswapped(irafheader, impixtype); if (imhver == 1) swapdata = swaphead; /* vers 1 data has same swapness as header */ else swapdata = irafgeti4 (irafheader, IM2_SWAPPED); /* Set pixel size in FITS header */ pixtype = irafgeti4 (irafheader, impixtype); switch (pixtype) { case TY_CHAR: nbits = 8; break; case TY_UBYTE: nbits = 8; break; case TY_SHORT: nbits = 16; break; case TY_USHORT: nbits = -16; break; case TY_INT: case TY_LONG: nbits = 32; break; case TY_REAL: nbits = -32; break; case TY_DOUBLE: nbits = -64; break; default: sprintf(errmsg,"Unsupported IRAF data type: %d", pixtype); ffpmsg(errmsg); ffpmsg(hdrname); return (*status = FILE_NOT_OPENED); } hputi4 (fitsheader,"BITPIX",nbits); hputcom (fitsheader,"BITPIX", "IRAF .imh pixel type"); fhead = fhead + 80; /* Set image dimensions in FITS header */ nax = irafgeti4 (irafheader, imndim); hputi4 (fitsheader,"NAXIS",nax); hputcom (fitsheader,"NAXIS", "IRAF .imh naxis"); fhead = fhead + 80; n = irafgeti4 (irafheader, imlen); hputi4 (fitsheader, "NAXIS1", n); hputcom (fitsheader,"NAXIS1", "IRAF .imh image naxis[1]"); fhead = fhead + 80; if (nax > 1) { n = irafgeti4 (irafheader, imlen+4); hputi4 (fitsheader, "NAXIS2", n); hputcom (fitsheader,"NAXIS2", "IRAF .imh image naxis[2]"); fhead = fhead + 80; } if (nax > 2) { n = irafgeti4 (irafheader, imlen+8); hputi4 (fitsheader, "NAXIS3", n); hputcom (fitsheader,"NAXIS3", "IRAF .imh image naxis[3]"); fhead = fhead + 80; } if (nax > 3) { n = irafgeti4 (irafheader, imlen+12); hputi4 (fitsheader, "NAXIS4", n); hputcom (fitsheader,"NAXIS4", "IRAF .imh image naxis[4]"); fhead = fhead + 80; } /* Set object name in FITS header */ if (imhver == 2) objname = irafgetc (irafheader, IM2_TITLE, SZ_IM2TITLE); else objname = irafgetc2 (irafheader, IM_TITLE, SZ_IMTITLE); if ((lstr = strlen (objname)) < 8) { for (i = lstr; i < 8; i++) objname[i] = ' '; objname[8] = 0; } hputs (fitsheader,"OBJECT",objname); hputcom (fitsheader,"OBJECT", "IRAF .imh title"); free (objname); fhead = fhead + 80; /* Save physical axis lengths so image file can be read */ n = irafgeti4 (irafheader, imphyslen); hputi4 (fitsheader, "NPAXIS1", n); hputcom (fitsheader,"NPAXIS1", "IRAF .imh physical naxis[1]"); fhead = fhead + 80; if (nax > 1) { n = irafgeti4 (irafheader, imphyslen+4); hputi4 (fitsheader, "NPAXIS2", n); hputcom (fitsheader,"NPAXIS2", "IRAF .imh physical naxis[2]"); fhead = fhead + 80; } if (nax > 2) { n = irafgeti4 (irafheader, imphyslen+8); hputi4 (fitsheader, "NPAXIS3", n); hputcom (fitsheader,"NPAXIS3", "IRAF .imh physical naxis[3]"); fhead = fhead + 80; } if (nax > 3) { n = irafgeti4 (irafheader, imphyslen+12); hputi4 (fitsheader, "NPAXIS4", n); hputcom (fitsheader,"NPAXIS4", "IRAF .imh physical naxis[4]"); fhead = fhead + 80; } /* Save image header filename in header */ hputs (fitsheader,"IMHFILE",hdrname); hputcom (fitsheader,"IMHFILE", "IRAF header file name"); fhead = fhead + 80; /* Save image pixel file pathname in header */ if (imhver == 2) pixname = irafgetc (irafheader, IM2_PIXFILE, SZ_IM2PIXFILE); else pixname = irafgetc2 (irafheader, IM_PIXFILE, SZ_IMPIXFILE); if (strncmp(pixname, "HDR", 3) == 0 ) { newpixname = same_path (pixname, hdrname); free (pixname); pixname = newpixname; } if (strchr (pixname, '/') == NULL && strchr (pixname, '$') == NULL) { newpixname = same_path (pixname, hdrname); free (pixname); pixname = newpixname; } if ((bang = strchr (pixname, '!')) != NULL ) hputs (fitsheader,"PIXFILE",bang+1); else hputs (fitsheader,"PIXFILE",pixname); free (pixname); hputcom (fitsheader,"PIXFILE", "IRAF .pix pixel file"); fhead = fhead + 80; /* Save image offset from star of pixel file */ pixoff = irafgeti4 (irafheader, impixoff); pixoff = (pixoff - 1) * 2; hputi4 (fitsheader, "PIXOFF", pixoff); hputcom (fitsheader,"PIXOFF", "IRAF .pix pixel offset (Do not change!)"); fhead = fhead + 80; /* Save IRAF file format version in header */ hputi4 (fitsheader,"IMHVER",imhver); hputcom (fitsheader,"IMHVER", "IRAF .imh format version (1 or 2)"); fhead = fhead + 80; /* Save flag as to whether to swap IRAF data for this file and machine */ if (swapdata) hputl (fitsheader, "PIXSWAP", 1); else hputl (fitsheader, "PIXSWAP", 0); hputcom (fitsheader,"PIXSWAP", "IRAF pixels, FITS byte orders differ if T"); fhead = fhead + 80; /* Add user portion of IRAF header to FITS header */ fitsline[80] = 0; if (imhver == 2) { imu = LEN_IM2HDR; chead = irafheader; j = 0; for (k = 0; k < 80; k++) fitsline[k] = ' '; for (i = imu; i < nbiraf; i++) { irafchar = chead[i]; if (irafchar == 0) break; else if (irafchar == 10) { (void)strncpy (fhead, fitsline, 80); /* fprintf (stderr,"%80s\n",fitsline); */ if (strncmp (fitsline, "OBJECT ", 7) != 0) { fhead = fhead + 80; } for (k = 0; k < 80; k++) fitsline[k] = ' '; j = 0; } else { if (j > 80) { if (strncmp (fitsline, "OBJECT ", 7) != 0) { (void)strncpy (fhead, fitsline, 80); /* fprintf (stderr,"%80s\n",fitsline); */ j = 9; fhead = fhead + 80; } for (k = 0; k < 80; k++) fitsline[k] = ' '; } if (irafchar > 32 && irafchar < 127) fitsline[j] = irafchar; j++; } } } else { imu = LEN_IMHDR; chead = irafheader; if (swaphead == 1) ib = 0; else ib = 1; for (k = 0; k < 80; k++) fitsline[k] = ' '; j = 0; for (i = imu; i < nbiraf; i=i+2) { irafchar = chead[i+ib]; if (irafchar == 0) break; else if (irafchar == 10) { if (strncmp (fitsline, "OBJECT ", 7) != 0) { (void)strncpy (fhead, fitsline, 80); fhead = fhead + 80; } /* fprintf (stderr,"%80s\n",fitsline); */ j = 0; for (k = 0; k < 80; k++) fitsline[k] = ' '; } else { if (j > 80) { if (strncmp (fitsline, "OBJECT ", 7) != 0) { (void)strncpy (fhead, fitsline, 80); j = 9; fhead = fhead + 80; } /* fprintf (stderr,"%80s\n",fitsline); */ for (k = 0; k < 80; k++) fitsline[k] = ' '; } if (irafchar > 32 && irafchar < 127) fitsline[j] = irafchar; j++; } } } /* Add END to last line */ (void)strncpy (fhead, endline, 80); /* Find end of last 2880-byte block of header */ fhead = ksearch (fitsheader, "END") + 80; nblock = *nbfits / 2880; fhead1 = fitsheader + (nblock * 2880); *fitssize = fhead - fitsheader; /* no. of bytes to end of END keyword */ /* Pad rest of header with spaces */ strncpy (endline," ",3); for (fp = fhead; fp < fhead1; fp = fp + 80) { (void)strncpy (fp, endline,80); } return (*status); } /*--------------------------------------------------------------------------*/ /* Put filename and header path together */ static char *same_path ( char *pixname, /* IRAF pixel file pathname */ char *hdrname) /* IRAF image header file pathname */ { int len; char *newpixname; newpixname = (char *) calloc (SZ_IM2PIXFILE, sizeof (char)); /* Pixel file is in same directory as header */ if (strncmp(pixname, "HDR$", 4) == 0 ) { (void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE); /* find the end of the pathname */ len = strlen (newpixname); #ifndef VMS while( (len > 0) && (newpixname[len-1] != '/') ) #else while( (len > 0) && (newpixname[len-1] != ']') && (newpixname[len-1] != ':') ) #endif len--; /* add name */ newpixname[len] = '\0'; (void)strncat (newpixname, &pixname[4], SZ_IM2PIXFILE-strlen(newpixname)-1); } /* Bare pixel file with no path is assumed to be same as HDR$filename */ else if (strchr (pixname, '/') == NULL && strchr (pixname, '$') == NULL) { (void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE); /* find the end of the pathname */ len = strlen (newpixname); #ifndef VMS while( (len > 0) && (newpixname[len-1] != '/') ) #else while( (len > 0) && (newpixname[len-1] != ']') && (newpixname[len-1] != ':') ) #endif len--; /* add name */ newpixname[len] = '\0'; (void)strncat (newpixname, pixname, SZ_IM2PIXFILE-strlen(newpixname)-1); } /* Pixel file has same name as header file, but with .pix extension */ else if (strncmp (pixname, "HDR", 3) == 0) { /* load entire header name string into name buffer */ (void)strncpy (newpixname, hdrname, SZ_IM2PIXFILE); len = strlen (newpixname); newpixname[len-3] = 'p'; newpixname[len-2] = 'i'; newpixname[len-1] = 'x'; } return (newpixname); } /*--------------------------------------------------------------------------*/ static int isirafswapped ( char *irafheader, /* IRAF image header */ int offset) /* Number of bytes to skip before number */ /* check if the IRAF file is in big endian (sun) format (= 0) or not */ /* This is done by checking the 4 byte integer in the header that */ /* represents the iraf pixel type. This 4-byte word is guaranteed to */ /* have the least sig byte != 0 and the most sig byte = 0, so if the */ /* first byte of the word != 0, then the file in little endian format */ /* like on an Alpha machine. */ { int swapped; if (irafheader[offset] != 0) swapped = 1; else swapped = 0; return (swapped); } /*--------------------------------------------------------------------------*/ static int irafgeti4 ( char *irafheader, /* IRAF image header */ int offset) /* Number of bytes to skip before number */ { char *ctemp, *cheader; int temp; cheader = irafheader; ctemp = (char *) &temp; if (machswap() != swaphead) { ctemp[3] = cheader[offset]; ctemp[2] = cheader[offset+1]; ctemp[1] = cheader[offset+2]; ctemp[0] = cheader[offset+3]; } else { ctemp[0] = cheader[offset]; ctemp[1] = cheader[offset+1]; ctemp[2] = cheader[offset+2]; ctemp[3] = cheader[offset+3]; } return (temp); } /*--------------------------------------------------------------------------*/ /* IRAFGETC2 -- Get character string from arbitrary part of v.1 IRAF header */ static char *irafgetc2 ( char *irafheader, /* IRAF image header */ int offset, /* Number of bytes to skip before string */ int nc) /* Maximum number of characters in string */ { char *irafstring, *string; irafstring = irafgetc (irafheader, offset, 2*(nc+1)); string = iraf2str (irafstring, nc); free (irafstring); return (string); } /*--------------------------------------------------------------------------*/ /* IRAFGETC -- Get character string from arbitrary part of IRAF header */ static char *irafgetc ( char *irafheader, /* IRAF image header */ int offset, /* Number of bytes to skip before string */ int nc) /* Maximum number of characters in string */ { char *ctemp, *cheader; int i; cheader = irafheader; ctemp = (char *) calloc (nc+1, 1); if (ctemp == NULL) { ffpmsg("IRAFGETC Cannot allocate memory for string variable"); return (NULL); } for (i = 0; i < nc; i++) { ctemp[i] = cheader[offset+i]; if (ctemp[i] > 0 && ctemp[i] < 32) ctemp[i] = ' '; } return (ctemp); } /*--------------------------------------------------------------------------*/ /* Convert IRAF 2-byte/char string to 1-byte/char string */ static char *iraf2str ( char *irafstring, /* IRAF 2-byte/character string */ int nchar) /* Number of characters in string */ { char *string; int i, j; string = (char *) calloc (nchar+1, 1); if (string == NULL) { ffpmsg("IRAF2STR Cannot allocate memory for string variable"); return (NULL); } /* the chars are in bytes 1, 3, 5, ... if bigendian format (SUN) */ /* else in bytes 0, 2, 4, ... if little endian format (Alpha) */ if (irafstring[0] != 0) j = 0; else j = 1; /* Convert appropriate byte of input to output character */ for (i = 0; i < nchar; i++) { string[i] = irafstring[j]; j = j + 2; } return (string); } /*--------------------------------------------------------------------------*/ /* IRAFSWAP -- Reverse bytes of any type of vector in place */ static void irafswap ( int bitpix, /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ char *string, /* Address of starting point of bytes to swap */ int nbytes) /* Number of bytes to swap */ { switch (bitpix) { case 16: if (nbytes < 2) return; irafswap2 (string,nbytes); break; case 32: if (nbytes < 4) return; irafswap4 (string,nbytes); break; case -16: if (nbytes < 2) return; irafswap2 (string,nbytes); break; case -32: if (nbytes < 4) return; irafswap4 (string,nbytes); break; case -64: if (nbytes < 8) return; irafswap8 (string,nbytes); break; } return; } /*--------------------------------------------------------------------------*/ /* IRAFSWAP2 -- Swap bytes in string in place */ static void irafswap2 ( char *string, /* Address of starting point of bytes to swap */ int nbytes) /* Number of bytes to swap */ { char *sbyte, temp, *slast; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp = sbyte[0]; sbyte[0] = sbyte[1]; sbyte[1] = temp; sbyte= sbyte + 2; } return; } /*--------------------------------------------------------------------------*/ /* IRAFSWAP4 -- Reverse bytes of Integer*4 or Real*4 vector in place */ static void irafswap4 ( char *string, /* Address of Integer*4 or Real*4 vector */ int nbytes) /* Number of bytes to reverse */ { char *sbyte, *slast; char temp0, temp1, temp2, temp3; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp3 = sbyte[0]; temp2 = sbyte[1]; temp1 = sbyte[2]; temp0 = sbyte[3]; sbyte[0] = temp0; sbyte[1] = temp1; sbyte[2] = temp2; sbyte[3] = temp3; sbyte = sbyte + 4; } return; } /*--------------------------------------------------------------------------*/ /* IRAFSWAP8 -- Reverse bytes of Real*8 vector in place */ static void irafswap8 ( char *string, /* Address of Real*8 vector */ int nbytes) /* Number of bytes to reverse */ { char *sbyte, *slast; char temp[8]; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp[7] = sbyte[0]; temp[6] = sbyte[1]; temp[5] = sbyte[2]; temp[4] = sbyte[3]; temp[3] = sbyte[4]; temp[2] = sbyte[5]; temp[1] = sbyte[6]; temp[0] = sbyte[7]; sbyte[0] = temp[0]; sbyte[1] = temp[1]; sbyte[2] = temp[2]; sbyte[3] = temp[3]; sbyte[4] = temp[4]; sbyte[5] = temp[5]; sbyte[6] = temp[6]; sbyte[7] = temp[7]; sbyte = sbyte + 8; } return; } /*--------------------------------------------------------------------------*/ static int machswap (void) { char *ctest; int itest; itest = 1; ctest = (char *)&itest; if (*ctest) return (1); else return (0); } /*--------------------------------------------------------------------------*/ /* the following routines were originally in hget.c */ /*--------------------------------------------------------------------------*/ static int lhead0 = 0; /*--------------------------------------------------------------------------*/ /* Extract long value for variable from FITS header string */ static int hgeti4 (hstring,keyword,ival) char *hstring; /* character string containing FITS header information in the format = {/ } */ char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ int *ival; { char *value; double dval; int minint; char val[30]; /* Get value and comment from header string */ value = hgetc (hstring,keyword); /* Translate value from ASCII to binary */ if (value != NULL) { minint = -MAXINT - 1; strcpy (val, value); dval = atof (val); if (dval+0.001 > MAXINT) *ival = MAXINT; else if (dval >= 0) *ival = (int) (dval + 0.001); else if (dval-0.001 < minint) *ival = minint; else *ival = (int) (dval - 0.001); return (1); } else { return (0); } } /*-------------------------------------------------------------------*/ /* Extract string value for variable from FITS header string */ static int hgets (hstring, keyword, lstr, str) char *hstring; /* character string containing FITS header information in the format = {/ } */ char *keyword; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ int lstr; /* Size of str in characters */ char *str; /* String (returned) */ { char *value; int lval; /* Get value and comment from header string */ value = hgetc (hstring,keyword); if (value != NULL) { lval = strlen (value); if (lval < lstr) strcpy (str, value); else if (lstr > 1) strncpy (str, value, lstr-1); else str[0] = value[0]; return (1); } else return (0); } /*-------------------------------------------------------------------*/ /* Extract character value for variable from FITS header string */ static char * hgetc (hstring,keyword0) char *hstring; /* character string containing FITS header information in the format = {/ } */ char *keyword0; /* character string containing the name of the keyword the value of which is returned. hget searches for a line beginning with this string. if "[n]" is present, the n'th token in the value is returned. (the first 8 characters must be unique) */ { static char cval[80]; char *value; char cwhite[2]; char squot[2], dquot[2], lbracket[2], rbracket[2], slash[2], comma[2]; char keyword[81]; /* large for ESO hierarchical keywords */ char line[100]; char *vpos, *cpar = NULL; char *q1, *q2 = NULL, *v1, *v2, *c1, *brack1, *brack2; int ipar, i; squot[0] = 39; squot[1] = 0; dquot[0] = 34; dquot[1] = 0; lbracket[0] = 91; lbracket[1] = 0; comma[0] = 44; comma[1] = 0; rbracket[0] = 93; rbracket[1] = 0; slash[0] = 47; slash[1] = 0; /* Find length of variable name */ strncpy (keyword,keyword0, sizeof(keyword)-1); brack1 = strsrch (keyword,lbracket); if (brack1 == NULL) brack1 = strsrch (keyword,comma); if (brack1 != NULL) { *brack1 = '\0'; brack1++; } /* Search header string for variable name */ vpos = ksearch (hstring,keyword); /* Exit if not found */ if (vpos == NULL) { return (NULL); } /* Initialize line to nulls */ for (i = 0; i < 100; i++) line[i] = 0; /* In standard FITS, data lasts until 80th character */ /* Extract entry for this variable from the header */ strncpy (line,vpos,80); /* check for quoted value */ q1 = strsrch (line,squot); c1 = strsrch (line,slash); if (q1 != NULL) { if (c1 != NULL && q1 < c1) q2 = strsrch (q1+1,squot); else if (c1 == NULL) q2 = strsrch (q1+1,squot); else q1 = NULL; } else { q1 = strsrch (line,dquot); if (q1 != NULL) { if (c1 != NULL && q1 < c1) q2 = strsrch (q1+1,dquot); else if (c1 == NULL) q2 = strsrch (q1+1,dquot); else q1 = NULL; } else { q1 = NULL; q2 = line + 10; } } /* Extract value and remove excess spaces */ if (q1 != NULL) { v1 = q1 + 1;; v2 = q2; c1 = strsrch (q2,"/"); } else { v1 = strsrch (line,"=") + 1; c1 = strsrch (line,"/"); if (c1 != NULL) v2 = c1; else v2 = line + 79; } /* Ignore leading spaces */ while (*v1 == ' ' && v1 < v2) { v1++; } /* Drop trailing spaces */ *v2 = '\0'; v2--; while (*v2 == ' ' && v2 > v1) { *v2 = '\0'; v2--; } if (!strcmp (v1, "-0")) v1++; strcpy (cval,v1); value = cval; /* If keyword has brackets, extract appropriate token from value */ if (brack1 != NULL) { brack2 = strsrch (brack1,rbracket); if (brack2 != NULL) *brack2 = '\0'; ipar = atoi (brack1); if (ipar > 0) { cwhite[0] = ' '; cwhite[1] = '\0'; for (i = 1; i <= ipar; i++) { cpar = strtok (v1,cwhite); v1 = NULL; } if (cpar != NULL) { strcpy (cval,cpar); } else value = NULL; } } return (value); } /*-------------------------------------------------------------------*/ /* Find beginning of fillable blank line before FITS header keyword line */ static char * blsearch (hstring,keyword) /* Find entry for keyword keyword in FITS header string hstring. (the keyword may have a maximum of eight letters) NULL is returned if the keyword is not found */ char *hstring; /* character string containing fits-style header information in the format = {/ } the default is that each entry is 80 characters long; however, lines may be of arbitrary length terminated by nulls, carriage returns or linefeeds, if packed is true. */ char *keyword; /* character string containing the name of the variable to be returned. ksearch searches for a line beginning with this string. The string may be a character literal or a character variable terminated by a null or '$'. it is truncated to 8 characters. */ { char *loc, *headnext, *headlast, *pval, *lc, *line; char *bval; int icol, nextchar, lkey, nleft, lhstr; pval = 0; /* Search header string for variable name */ if (lhead0) lhstr = lhead0; else { lhstr = 0; while (lhstr < 57600 && hstring[lhstr] != 0) lhstr++; } headlast = hstring + lhstr; headnext = hstring; pval = NULL; while (headnext < headlast) { nleft = headlast - headnext; loc = strnsrch (headnext, keyword, nleft); /* Exit if keyword is not found */ if (loc == NULL) { break; } icol = (loc - hstring) % 80; lkey = strlen (keyword); nextchar = (int) *(loc + lkey); /* If this is not in the first 8 characters of a line, keep searching */ if (icol > 7) headnext = loc + 1; /* If parameter name in header is longer, keep searching */ else if (nextchar != 61 && nextchar > 32 && nextchar < 127) headnext = loc + 1; /* If preceeding characters in line are not blanks, keep searching */ else { line = loc - icol; for (lc = line; lc < loc; lc++) { if (*lc != ' ') headnext = loc + 1; } /* Return pointer to start of line if match */ if (loc >= headnext) { pval = line; break; } } } /* Return NULL if keyword is found at start of FITS header string */ if (pval == NULL) return (pval); /* Return NULL if found the first keyword in the header */ if (pval == hstring) return (NULL); /* Find last nonblank line before requested keyword */ bval = pval - 80; while (!strncmp (bval," ",8)) bval = bval - 80; bval = bval + 80; /* Return pointer to calling program if blank lines found */ if (bval < pval) return (bval); else return (NULL); } /*-------------------------------------------------------------------*/ /* Find FITS header line containing specified keyword */ static char *ksearch (hstring,keyword) /* Find entry for keyword keyword in FITS header string hstring. (the keyword may have a maximum of eight letters) NULL is returned if the keyword is not found */ char *hstring; /* character string containing fits-style header information in the format = {/ } the default is that each entry is 80 characters long; however, lines may be of arbitrary length terminated by nulls, carriage returns or linefeeds, if packed is true. */ char *keyword; /* character string containing the name of the variable to be returned. ksearch searches for a line beginning with this string. The string may be a character literal or a character variable terminated by a null or '$'. it is truncated to 8 characters. */ { char *loc, *headnext, *headlast, *pval, *lc, *line; int icol, nextchar, lkey, nleft, lhstr; pval = 0; /* Search header string for variable name */ if (lhead0) lhstr = lhead0; else { lhstr = 0; while (lhstr < 57600 && hstring[lhstr] != 0) lhstr++; } headlast = hstring + lhstr; headnext = hstring; pval = NULL; while (headnext < headlast) { nleft = headlast - headnext; loc = strnsrch (headnext, keyword, nleft); /* Exit if keyword is not found */ if (loc == NULL) { break; } icol = (loc - hstring) % 80; lkey = strlen (keyword); nextchar = (int) *(loc + lkey); /* If this is not in the first 8 characters of a line, keep searching */ if (icol > 7) headnext = loc + 1; /* If parameter name in header is longer, keep searching */ else if (nextchar != 61 && nextchar > 32 && nextchar < 127) headnext = loc + 1; /* If preceeding characters in line are not blanks, keep searching */ else { line = loc - icol; for (lc = line; lc < loc; lc++) { if (*lc != ' ') headnext = loc + 1; } /* Return pointer to start of line if match */ if (loc >= headnext) { pval = line; break; } } } /* Return pointer to calling program */ return (pval); } /*-------------------------------------------------------------------*/ /* Find string s2 within null-terminated string s1 */ static char * strsrch (s1, s2) char *s1; /* String to search */ char *s2; /* String to look for */ { int ls1; ls1 = strlen (s1); return (strnsrch (s1, s2, ls1)); } /*-------------------------------------------------------------------*/ /* Find string s2 within string s1 */ static char * strnsrch (s1, s2, ls1) char *s1; /* String to search */ char *s2; /* String to look for */ int ls1; /* Length of string being searched */ { char *s,*s1e; char cfirst,clast; int i,ls2; /* Return null string if either pointer is NULL */ if (s1 == NULL || s2 == NULL) return (NULL); /* A zero-length pattern is found in any string */ ls2 = strlen (s2); if (ls2 ==0) return (s1); /* Only a zero-length string can be found in a zero-length string */ if (ls1 ==0) return (NULL); cfirst = s2[0]; clast = s2[ls2-1]; s1e = s1 + ls1 - ls2 + 1; s = s1; while (s < s1e) { /* Search for first character in pattern string */ if (*s == cfirst) { /* If single character search, return */ if (ls2 == 1) return (s); /* Search for last character in pattern string if first found */ if (s[ls2-1] == clast) { /* If two-character search, return */ if (ls2 == 2) return (s); /* If 3 or more characters, check for rest of search string */ i = 1; while (i < ls2 && s[i] == s2[i]) i++; /* If entire string matches, return */ if (i >= ls2) return (s); } } s++; } return (NULL); } /*-------------------------------------------------------------------*/ /* the following routines were originally in hget.c */ /*-------------------------------------------------------------------*/ /* HPUTI4 - Set int keyword = ival in FITS header string */ static void hputi4 (hstring,keyword,ival) char *hstring; /* character string containing FITS-style header information in the format = {/ } each entry is padded with spaces to 80 characters */ char *keyword; /* character string containing the name of the variable to be returned. hput searches for a line beginning with this string, and if there isn't one, creates one. The first 8 characters of keyword must be unique. */ int ival; /* int number */ { char value[30]; /* Translate value from binary to ASCII */ sprintf (value,"%d",ival); /* Put value into header string */ hputc (hstring,keyword,value); /* Return to calling program */ return; } /*-------------------------------------------------------------------*/ /* HPUTL - Set keyword = F if lval=0, else T, in FITS header string */ static void hputl (hstring, keyword,lval) char *hstring; /* FITS header */ char *keyword; /* Keyword name */ int lval; /* logical variable (0=false, else true) */ { char value[8]; /* Translate value from binary to ASCII */ if (lval) strcpy (value, "T"); else strcpy (value, "F"); /* Put value into header string */ hputc (hstring,keyword,value); /* Return to calling program */ return; } /*-------------------------------------------------------------------*/ /* HPUTS - Set character string keyword = 'cval' in FITS header string */ static void hputs (hstring,keyword,cval) char *hstring; /* FITS header */ char *keyword; /* Keyword name */ char *cval; /* character string containing the value for variable keyword. trailing and leading blanks are removed. */ { char squot = 39; char value[70]; int lcval; /* find length of variable string */ lcval = strlen (cval); if (lcval > 67) lcval = 67; /* Put quotes around string */ value[0] = squot; strncpy (&value[1],cval,lcval); value[lcval+1] = squot; value[lcval+2] = 0; /* Put value into header string */ hputc (hstring,keyword,value); /* Return to calling program */ return; } /*---------------------------------------------------------------------*/ /* HPUTC - Set character string keyword = value in FITS header string */ static void hputc (hstring,keyword,value) char *hstring; char *keyword; char *value; /* character string containing the value for variable keyword. trailing and leading blanks are removed. */ { char squot = 39; char line[100]; char newcom[50]; char blank[80]; char *v, *vp, *v1, *v2, *q1, *q2, *c1, *ve; int lkeyword, lcom, lval, lc, i; for (i = 0; i < 80; i++) blank[i] = ' '; /* find length of keyword and value */ lkeyword = strlen (keyword); lval = strlen (value); /* If COMMENT or HISTORY, always add it just before the END */ if (lkeyword == 7 && (strncmp (keyword,"COMMENT",7) == 0 || strncmp (keyword,"HISTORY",7) == 0)) { /* Find end of header */ v1 = ksearch (hstring,"END"); v2 = v1 + 80; /* Move END down one line */ strncpy (v2, v1, 80); /* Insert keyword */ strncpy (v1,keyword,7); /* Pad with spaces */ for (vp = v1+lkeyword; vp < v2; vp++) *vp = ' '; /* Insert comment */ strncpy (v1+9,value,lval); return; } /* Otherwise search for keyword */ else v1 = ksearch (hstring,keyword); /* If parameter is not found, find a place to put it */ if (v1 == NULL) { /* First look for blank lines before END */ v1 = blsearch (hstring, "END"); /* Otherwise, create a space for it at the end of the header */ if (v1 == NULL) { ve = ksearch (hstring,"END"); v1 = ve; v2 = v1 + 80; strncpy (v2, ve, 80); } else v2 = v1 + 80; lcom = 0; newcom[0] = 0; } /* Otherwise, extract the entry for this keyword from the header */ else { strncpy (line, v1, 80); line[80] = 0; v2 = v1 + 80; /* check for quoted value */ q1 = strchr (line, squot); if (q1 != NULL) q2 = strchr (q1+1,squot); else q2 = line; /* extract comment and remove trailing spaces */ c1 = strchr (q2,'/'); if (c1 != NULL) { lcom = 80 - (c1 - line); strncpy (newcom, c1+1, lcom); vp = newcom + lcom - 1; while (vp-- > newcom && *vp == ' ') *vp = 0; lcom = strlen (newcom); } else { newcom[0] = 0; lcom = 0; } } /* Fill new entry with spaces */ for (vp = v1; vp < v2; vp++) *vp = ' '; /* Copy keyword to new entry */ strncpy (v1, keyword, lkeyword); /* Add parameter value in the appropriate place */ vp = v1 + 8; *vp = '='; vp = v1 + 9; *vp = ' '; vp = vp + 1; if (*value == squot) { strncpy (vp, value, lval); if (lval+12 > 31) lc = lval + 12; else lc = 30; } else { vp = v1 + 30 - lval; strncpy (vp, value, lval); lc = 30; } /* Add comment in the appropriate place */ if (lcom > 0) { if (lc+2+lcom > 80) lcom = 78 - lc; vp = v1 + lc + 2; /* Jul 16 1997: was vp = v1 + lc * 2 */ *vp = '/'; vp = vp + 1; strncpy (vp, newcom, lcom); for (v = vp + lcom; v < v2; v++) *v = ' '; } return; } /*-------------------------------------------------------------------*/ /* HPUTCOM - Set comment for keyword or on line in FITS header string */ static void hputcom (hstring,keyword,comment) char *hstring; char *keyword; char *comment; { char squot; char line[100]; int lkeyword, lcom; char *vp, *v1, *v2, *c0 = NULL, *c1, *q1, *q2; squot = 39; /* Find length of variable name */ lkeyword = strlen (keyword); /* If COMMENT or HISTORY, always add it just before the END */ if (lkeyword == 7 && (strncmp (keyword,"COMMENT",7) == 0 || strncmp (keyword,"HISTORY",7) == 0)) { /* Find end of header */ v1 = ksearch (hstring,"END"); v2 = v1 + 80; strncpy (v2, v1, 80); /* blank out new line and insert keyword */ for (vp = v1; vp < v2; vp++) *vp = ' '; strncpy (v1, keyword, lkeyword); } /* search header string for variable name */ else { v1 = ksearch (hstring,keyword); v2 = v1 + 80; /* if parameter is not found, return without doing anything */ if (v1 == NULL) { return; } /* otherwise, extract entry for this variable from the header */ strncpy (line, v1, 80); /* check for quoted value */ q1 = strchr (line,squot); if (q1 != NULL) q2 = strchr (q1+1,squot); else q2 = NULL; if (q2 == NULL || q2-line < 31) c0 = v1 + 31; else c0 = v1 + (q2-line) + 2; /* allan: 1997-09-30, was c0=q2+2 */ strncpy (c0, "/ ",2); } /* create new entry */ lcom = strlen (comment); if (lcom > 0) { c1 = c0 + 2; if (c1+lcom > v2) lcom = v2 - c1; strncpy (c1, comment, lcom); } } indi-0.5/src/cfitsio/imcompress.c0000644000175000017500000040516210610474375014704 0ustar jrjr# include # include # include # include # include "fitsio2.h" /*--------------------------------------------------------------------------*/ int fits_set_compression_type(fitsfile *fptr, /* I - FITS file pointer */ int ctype, /* image compression type code; */ /* allowed values: RICE_1, GZIP_1, PLIO_1, HCOMPRESS_1 */ int *status) /* IO - error status */ { /* This routine specifies the image compression algorithm that should be used when writing a FITS image. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ (fptr->Fptr)->request_compress_type = ctype; return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_tile_dim(fitsfile *fptr, /* I - FITS file pointer */ int ndim, /* number of dimensions in the compressed image */ long *dims, /* size of image compression tile in each dimension */ /* default tile size = (NAXIS1, 1, 1, ...) */ int *status) /* IO - error status */ { /* This routine specifies the size (dimension) of the image compression tiles that should be used when writing a FITS image. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ int ii; if (ndim < 0 || ndim > MAX_COMPRESS_DIM) { *status = BAD_DIMEN; return(*status); } for (ii = 0; ii < ndim; ii++) { (fptr->Fptr)->request_tilesize[ii] = dims[ii]; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_noise_bits(fitsfile *fptr, /* I - FITS file pointer */ int noisebits, /* noise_bits parameter value */ /* (default = 4) */ int *status) /* IO - error status */ { /* This routine specifies the value of the noice_bits parameter that should be used when compressing floating point images. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ if (noisebits < 1 || noisebits > 16) { *status = DATA_COMPRESSION_ERR; return(*status); } (fptr->Fptr)->request_noise_nbits = noisebits; return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_hcomp_scale(fitsfile *fptr, /* I - FITS file pointer */ int scale, /* hcompress scale parameter value */ /* (default = 4) */ int *status) /* IO - error status */ { /* This routine specifies the value of the hcompress scale parameter that The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ (fptr->Fptr)->request_hcomp_scale = scale; return(*status); } /*--------------------------------------------------------------------------*/ int fits_set_hcomp_smooth(fitsfile *fptr, /* I - FITS file pointer */ int smooth, /* hcompress smooth parameter value */ /* if scale > 1 and smooth != 0, then */ /* the image will be smoothed when it is */ /* decompressed to remove some of the */ /* 'blockiness' in the image produced */ /* by the lossy compression */ int *status) /* IO - error status */ { /* This routine specifies the value of the hcompress scale parameter that The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ (fptr->Fptr)->request_hcomp_smooth = smooth; return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_compression_type(fitsfile *fptr, /* I - FITS file pointer */ int *ctype, /* image compression type code; */ /* allowed values: RICE_1, GZIP_1, PLIO_1, HCOMPRESS_1 */ int *status) /* IO - error status */ { /* This routine returns the image compression algorithm that should be used when writing a FITS image. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ *ctype = (fptr->Fptr)->request_compress_type; return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_tile_dim(fitsfile *fptr, /* I - FITS file pointer */ int ndim, /* number of dimensions in the compressed image */ long *dims, /* size of image compression tile in each dimension */ /* default tile size = (NAXIS1, 1, 1, ...) */ int *status) /* IO - error status */ { /* This routine returns the size (dimension) of the image compression tiles that should be used when writing a FITS image. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ int ii; if (ndim < 0 || ndim > MAX_COMPRESS_DIM) { *status = BAD_DIMEN; return(*status); } for (ii = 0; ii < ndim; ii++) { dims[ii] = (fptr->Fptr)->request_tilesize[ii]; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_noise_bits(fitsfile *fptr, /* I - FITS file pointer */ int *noisebits, /* noise_bits parameter value */ /* (default = 4) */ int *status) /* IO - error status */ { /* This routine returns the value of the noice_bits parameter that should be used when compressing floating point images. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ *noisebits = (fptr->Fptr)->request_noise_nbits; return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_hcomp_scale(fitsfile *fptr, /* I - FITS file pointer */ int *scale, /* Hcompress scale parameter value */ int *status) /* IO - error status */ { /* This routine returns the value of the noice_bits parameter that should be used when compressing floating point images. The image is divided into tiles, and each tile is compressed and stored in a row of at variable length binary table column. */ *scale = (fptr->Fptr)->request_hcomp_scale; return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_hcomp_smooth(fitsfile *fptr, /* I - FITS file pointer */ int *smooth, /* Hcompress smooth parameter value */ int *status) /* IO - error status */ { *smooth = (fptr->Fptr)->request_hcomp_smooth; return(*status); } /*--------------------------------------------------------------------------*/ int fits_img_compress(fitsfile *infptr, /* pointer to image to be compressed */ fitsfile *outfptr, /* empty HDU for output compressed image */ int *status) /* IO - error status */ /* This routine initializes the output table, copies all the keywords, and loops through the input image, compressing the data and writing the compressed tiles to the output table. */ { int bitpix, naxis; long naxes[MAX_COMPRESS_DIM]; if (*status > 0) return(*status); /* get datatype and size of input image */ if (fits_get_img_param(infptr, MAX_COMPRESS_DIM, &bitpix, &naxis, naxes, status) > 0) return(*status); if (naxis < 1 || naxis > MAX_COMPRESS_DIM) { ffpmsg("Image cannot be compressed: NAXIS out of range"); return(*status = BAD_NAXIS); } /* initialize output table */ if (imcomp_init_table(outfptr, bitpix, naxis, naxes, 0, status) > 0) return (*status); /* Copy the image header keywords to the table header. */ if (imcomp_copy_img2comp(infptr, outfptr, status) > 0) return (*status); /* turn off any intensity scaling (defined by BSCALE and BZERO */ /* keywords) so that unscaled values will be read by CFITSIO */ ffpscl(infptr, 1.0, 0.0, status); /* force a rescan of the output file keywords, so that */ /* the compression parameters will be copied to the internal */ /* fitsfile structure used by CFITSIO */ ffrdef(outfptr, status); /* Read each image tile, compress, and write to a table row. */ imcomp_compress_image (infptr, outfptr, status); /* force another rescan of the output file keywords, to */ /* update PCOUNT and TFORMn = '1PB(iii)' keyword values. */ ffrdef(outfptr, status); return (*status); } /*--------------------------------------------------------------------------*/ int fits_compress_img(fitsfile *infptr, /* pointer to image to be compressed */ fitsfile *outfptr, /* empty HDU for output compressed image */ int compress_type, /* compression type code */ /* RICE_1, HCOMPRESS_1, etc. */ long *intilesize, /* size in each dimension of the tiles */ /* NULL pointer means tile by rows */ int blocksize, /* compression parameter: blocksize */ int nbits, /* compression parameter: nbits */ int *status) /* IO - error status */ /* !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! This routine is obsolete and should not be used. Currently the ftools 'fimgzip' task calls this; it should be modified to call fits_img_compress instead. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! This routine initializes the output table, copies all the keywords, and loops through the input image, compressing the data and writing the compressed tiles to the output table. */ { int bitpix, naxis; long naxes[MAX_COMPRESS_DIM]; if (*status > 0) return(*status); /* get datatype and size of input image */ if (fits_get_img_param(infptr, MAX_COMPRESS_DIM, &bitpix, &naxis, naxes, status) > 0) return(*status); if (naxis < 1 || naxis > MAX_COMPRESS_DIM) { ffpmsg("Image cannot be compressed: NAXIS out of range"); return(*status = BAD_NAXIS); } /* initialize output table */ if (imcomp_init_table(outfptr, bitpix, naxis, naxes, 0, status) > 0) return (*status); /* Copy the image header keywords to the table header. */ if (imcomp_copy_imheader(infptr, outfptr, status) > 0) return (*status); /* turn off any intensity scaling (defined by BSCALE and BZERO */ /* keywords) so that unscaled values will be read by CFITSIO */ ffpscl(infptr, 1.0, 0.0, status); /* force a rescan of the output file keywords, so that */ /* the compression parameters will be copied to the internal */ /* fitsfile structure used by CFITSIO */ ffrdef(outfptr, status); /* Read each image tile, compress, and write to a table row. */ imcomp_compress_image (infptr, outfptr, status); /* force another rescan of the output file keywords, to */ /* update PCOUNT and TFORMn = '1PB(iii)' keyword values. */ ffrdef(outfptr, status); return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_init_table(fitsfile *outfptr, int inbitpix, int naxis, long *naxes, int writebitpix, /* write the ZBITPIX, ZNAXIS, and ZNAXES keyword? */ int *status) /* create a BINTABLE extension for the output compressed image. */ { char keyname[FLEN_KEYWORD], zcmptype[12]; int ii, jj, minspace, tempsize, remain, leftspace, ncols, bitpix; long nrows; char *ttype[] = {"COMPRESSED_DATA", "UNCOMPRESSED_DATA", "ZSCALE", "ZZERO"}; char *tform[4]; char tf0[4], tf1[4], tf2[4], tf3[4]; char *tunit[] = {"\0", "\0", "\0", "\0" }; char comm[FLEN_COMMENT]; if (*status > 0) return(*status); /* test for the 2 special cases that represent unsigned integers */ if (inbitpix == USHORT_IMG) bitpix = SHORT_IMG; else if (inbitpix == ULONG_IMG) bitpix = LONG_IMG; else bitpix = inbitpix; /* reset default tile dimensions too if required */ if ((outfptr->Fptr)->request_compress_type == HCOMPRESS_1) { if (((outfptr->Fptr)->request_tilesize[0] == 0) && ((outfptr->Fptr)->request_tilesize[1] == 1) ){ for (ii = 0; ii < 2 && ii < naxis; ii++) { /* only reset the 1st 2 dimensions */ if (naxes[ii] <= 600) { /* use the full dimension of the image as the tile dimension */ (outfptr->Fptr)->request_tilesize[ii] = naxes[ii]; } else { /* look for an even tile size in the range 200 - 600 */ /* This is a brute force algorithm; probably more efficient ways to do this */ minspace = naxes[ii]; tempsize = naxes[ii]; for (jj = 600; jj >= 200; jj -= 2) { remain = naxes[ii] % jj; if (!remain) { /* found an even multiple tile size */ tempsize = jj; break; } else { leftspace = jj - remain; if (leftspace < minspace) { /* save the best case found so far */ minspace = leftspace; tempsize = jj; } } } /* end of for jj loop */ (outfptr->Fptr)->request_tilesize[ii] = tempsize; } } /* end of for ii loop */ } } /* end, if HCOMPRESS_1 */ for (ii = 0; ii < naxis; ii++) { if ((outfptr->Fptr)->request_tilesize[ii] <= 0) { /* tile size of 0 means use the image size of that dimension */ (outfptr->Fptr)->request_tilesize[ii] = naxes[ii]; } } /* (only used to quantize floating point images) */ if ((outfptr->Fptr)->request_noise_nbits < 1) /* use default value if input is not legal */ (outfptr->Fptr)->request_noise_nbits = 4; /* ---- set up array of TFORM strings -------------------------------*/ strcpy(tf0, "1PB"); strcpy(tf2, "1D"); strcpy(tf3, "1D"); tform[0] = tf0; tform[1] = tf1; tform[2] = tf2; tform[3] = tf3; /* calculate number of rows in output table */ nrows = 1; for (ii = 0; ii < naxis; ii++) { nrows = nrows * ((naxes[ii] - 1)/ ((outfptr->Fptr)->request_tilesize[ii]) + 1); } if (bitpix < 0 ) /* floating point image */ ncols = 4; else ncols = 1; /* default table has just one 'COMPRESSED_DATA' column */ if ((outfptr->Fptr)->request_compress_type == RICE_1) { strcpy(zcmptype, "RICE_1"); } else if ((outfptr->Fptr)->request_compress_type == GZIP_1) { strcpy(zcmptype, "GZIP_1"); } else if ((outfptr->Fptr)->request_compress_type == PLIO_1) { strcpy(zcmptype, "PLIO_1"); /* the PLIO compression algorithm outputs short integers, not bytes */ strcpy(tform[0], "1PI"); } else if ((outfptr->Fptr)->request_compress_type == HCOMPRESS_1) { strcpy(zcmptype, "HCOMPRESS_1"); } else { ffpmsg("unknown compression type (imcomp_init_table)"); return(*status = DATA_COMPRESSION_ERR); } /* set correct datatype for any tiles that cannot be compressed */ if (bitpix == SHORT_IMG) strcpy(tform[1], "1PI"); else if (bitpix == LONG_IMG) strcpy(tform[1], "1PJ"); else if (bitpix == FLOAT_IMG) strcpy(tform[1], "1PE"); else if (bitpix == DOUBLE_IMG) strcpy(tform[1], "1PD"); /* create the bintable extension to contain the compressed image */ ffcrtb(outfptr, BINARY_TBL, nrows, ncols, ttype, tform, tunit, 0, status); /* Add standard header keywords. */ ffpkyl (outfptr, "ZIMAGE", 1, "extension contains compressed image", status); if (writebitpix) { /* write the keywords defining the datatype and dimensions of */ /* the uncompressed image. These keywords may get created */ /* later, copied from the input uncompressed image */ ffpkyj (outfptr, "ZBITPIX", bitpix, "data type of original image", status); ffpkyj (outfptr, "ZNAXIS", naxis, "dimension of original image", status); for (ii = 0; ii < naxis; ii++) { sprintf (keyname, "ZNAXIS%d", ii+1); ffpkyj (outfptr, keyname, naxes[ii], "length of original image axis", status); } } for (ii = 0; ii < naxis; ii++) { sprintf (keyname, "ZTILE%d", ii+1); ffpkyj (outfptr, keyname, (outfptr->Fptr)->request_tilesize[ii], "size of tiles to be compressed", status); } ffpkys (outfptr, "ZCMPTYPE", zcmptype, "compression algorithm", status); /* write any algorithm-specific keywords */ if ((outfptr->Fptr)->request_compress_type == RICE_1) { ffpkys (outfptr, "ZNAME1", "BLOCKSIZE", "compression block size", status); /* for now at least, the block size is always 32 */ ffpkyj (outfptr, "ZVAL1", 32, "pixels per block", status); if (bitpix < 0 ) /* floating point image */ { ffpkys (outfptr, "ZNAME2", "NOISEBIT", "floating point quantization level", status); ffpkyj (outfptr, "ZVAL2", (long) (outfptr->Fptr)->request_noise_nbits, "floating point quantization level", status); } } else if ((outfptr->Fptr)->request_compress_type == HCOMPRESS_1) { ffpkys (outfptr, "ZNAME1", "SCALE", "HCOMPRESS scale factor", status); ffpkyj (outfptr, "ZVAL1", (long) (outfptr->Fptr)->request_hcomp_scale, "HCOMPRESS scale factor", status); ffpkys (outfptr, "ZNAME2", "SMOOTH", "HCOMPRESS smooth option", status); ffpkyj (outfptr, "ZVAL2", (long) (outfptr->Fptr)->request_hcomp_smooth, "HCOMPRESS smooth option", status); if (bitpix < 0 ) /* floating point image */ { ffpkys (outfptr, "ZNAME3", "NOISEBIT", "floating point quantization level", status); ffpkyj (outfptr, "ZVAL3", (long) (outfptr->Fptr)->request_noise_nbits, "floating point quantization level", status); } } else { if (bitpix < 0 ) /* floating point image */ { ffpkys (outfptr, "ZNAME1", "NOISEBIT", "floating point quantization level", status); ffpkyj (outfptr, "ZVAL1", (long) (outfptr->Fptr)->request_noise_nbits, "floating point quantization level", status); } } /* Write the BSCALE and BZERO keywords, if an unsigned integer image */ if (inbitpix == USHORT_IMG) { strcpy(comm, "offset data range to that of unsigned short"); ffpkyg(outfptr, "BZERO", 32768., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(outfptr, "BSCALE", 1.0, 0, comm, status); } else if (inbitpix == ULONG_IMG) { strcpy(comm, "offset data range to that of unsigned long"); ffpkyg(outfptr, "BZERO", 2147483648., 0, comm, status); strcpy(comm, "default scaling factor"); ffpkyg(outfptr, "BSCALE", 1.0, 0, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_calc_max_elem (int comptype, int nx, int zbitpix, int blocksize) /* This function returns the maximum number of bytes in a compressed image line. nx = maximum number of pixels in a tile blocksize is only relevant for RICE compression */ { if (comptype == RICE_1) { return (sizeof(float) * nx + nx / blocksize + 2 + 4); } else if (comptype == GZIP_1) { /* gzip usually compressed by at least a factor of 2 */ /* If this size turns out to be too small, then the gzip */ /* compression routine will allocate more space as required */ return(nx * sizeof(int) / 2); } else if (comptype == HCOMPRESS_1) { /* Imperical evidence suggests in the worst case, the compressed stream could be up to 10% larger than the original image. Add 26 byte overhead, only significant for very small tiles Possible improvement: may need to allow a larger size for 32-bit images */ if (zbitpix == 16 || zbitpix == 8) return( (int) (nx * 2.2 + 26)); /* will be compressing 16-bit int array */ else return( (int) (nx * 4.4 + 26)); /* will be compressing 32-bit int array */ } else return(nx * sizeof(int)); } /*--------------------------------------------------------------------------*/ int imcomp_compress_image (fitsfile *infptr, fitsfile *outfptr, int *status) /* This routine does the following: - reads an image one tile at a time - if it is a float or double image, then it quantizes the pixels - compresses the integer pixel values - writes the compressed byte stream to the FITS file. If the tile cannot be quantized than the raw float or double values are written to the output table. */ { double *tiledata = 0; int anynul, gotnulls = 0, datatype, tstatus, colnum; long ii, row, nelem, offset; int naxis; long maxtilelen, tilelen, incre[] = {1, 1, 1, 1, 1, 1}; long naxes[MAX_COMPRESS_DIM], fpixel[MAX_COMPRESS_DIM]; long lpixel[MAX_COMPRESS_DIM], tile[MAX_COMPRESS_DIM]; long tilesize[MAX_COMPRESS_DIM]; long i0, i1, i2, i3, i4, i5; char card[FLEN_CARD]; if (*status > 0) return(*status); maxtilelen = (outfptr->Fptr)->maxtilelen; /* allocate buffer to hold 1 tile of data */ /* if the hcompress algorithm is being used on BITPIX = 32, -32, or -64 */ /* image, then we need to allocate 8-bytes per pixel buffer */ if ((outfptr->Fptr)->zbitpix == FLOAT_IMG) { datatype = TFLOAT; if ( (outfptr->Fptr)->compress_type == HCOMPRESS_1) { /* need twice as much scratch space (8 bytes per pixel) */ tiledata = (double*) calloc (maxtilelen * 2, sizeof (float)); } else { tiledata = (double*) calloc (maxtilelen, sizeof (float)); } } else if ((outfptr->Fptr)->zbitpix == DOUBLE_IMG) { datatype = TDOUBLE; tiledata = (double*) calloc (maxtilelen, sizeof (double)); } else { datatype = TINT; if ( (outfptr->Fptr)->compress_type == HCOMPRESS_1 && (outfptr->Fptr)->zbitpix == LONG_IMG) { /* need twice as much scratch space (8 bytes per pixel) */ tiledata = (double*) calloc (maxtilelen * 2, sizeof (int)); } else { tiledata = (double*) calloc (maxtilelen, sizeof (int)); } } if (tiledata == NULL) { ffpmsg("Out of memory. (imcomp_compress_image)"); return (*status = MEMORY_ALLOCATION); } /* calculate size of tile in each dimension */ naxis = (outfptr->Fptr)->zndim; for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { if (ii < naxis) { naxes[ii] = (outfptr->Fptr)->znaxis[ii]; tilesize[ii] = (outfptr->Fptr)->tilesize[ii]; } else { naxes[ii] = 1; tilesize[ii] = 1; } } row = 1; /* set up big loop over up to 6 dimensions */ for (i5 = 1; i5 <= naxes[5]; i5 += tilesize[5]) { fpixel[5] = i5; lpixel[5] = minvalue(i5 + tilesize[5] - 1, naxes[5]); tile[5] = lpixel[5] - fpixel[5] + 1; for (i4 = 1; i4 <= naxes[4]; i4 += tilesize[4]) { fpixel[4] = i4; lpixel[4] = minvalue(i4 + tilesize[4] - 1, naxes[4]); tile[4] = lpixel[4] - fpixel[4] + 1; for (i3 = 1; i3 <= naxes[3]; i3 += tilesize[3]) { fpixel[3] = i3; lpixel[3] = minvalue(i3 + tilesize[3] - 1, naxes[3]); tile[3] = lpixel[3] - fpixel[3] + 1; for (i2 = 1; i2 <= naxes[2]; i2 += tilesize[2]) { fpixel[2] = i2; lpixel[2] = minvalue(i2 + tilesize[2] - 1, naxes[2]); tile[2] = lpixel[2] - fpixel[2] + 1; for (i1 = 1; i1 <= naxes[1]; i1 += tilesize[1]) { fpixel[1] = i1; lpixel[1] = minvalue(i1 + tilesize[1] - 1, naxes[1]); tile[1] = lpixel[1] - fpixel[1] + 1; for (i0 = 1; i0 <= naxes[0]; i0 += tilesize[0]) { fpixel[0] = i0; lpixel[0] = minvalue(i0 + tilesize[0] - 1, naxes[0]); tile[0] = lpixel[0] - fpixel[0] + 1; /* number of pixels in this tile */ tilelen = tile[0]; for (ii = 1; ii < naxis; ii++) { tilelen *= tile[ii]; } /* read next tile of data from image */ if (datatype == TFLOAT) { ffgsve(infptr, 1, naxis, naxes, fpixel, lpixel, incre, FLOATNULLVALUE, (float *) tiledata, &anynul, status); } else if (datatype == TDOUBLE) { ffgsvd(infptr, 1, naxis, naxes, fpixel, lpixel, incre, DOUBLENULLVALUE, tiledata, &anynul, status); } else /* read all integer data types as int */ { ffgsvk(infptr, 1, naxis, naxes, fpixel, lpixel, incre, 0, (int *) tiledata, &anynul, status); } /* now compress the tile, and write to row of binary table */ imcomp_compress_tile(outfptr, row, datatype, tiledata, tilelen, tile[0], tile[1], status); /* set flag if we found any null values */ if (anynul) gotnulls = 1; /* check for any error in the previous operations */ if (*status > 0) { ffpmsg("Error writing compressed image to table"); free(tiledata); return (*status); } row++; } } } } } } free (tiledata); /* finished with this buffer */ /* insert ZBLANK keyword if necessary */ if (gotnulls) { ffgcrd(outfptr, "ZCMPTYPE", card, status); ffikyj(outfptr, "ZBLANK", COMPRESS_NULL_VALUE, "null value in the compressed integer array", status); } if (datatype >= TFLOAT ) { /* check if any data were written to the UNCOMPRESSED_DATA column */ /* If not, then delete that column from the table */ for (ii = 1; ii < row; ii++) { ffgdes (outfptr, (outfptr->Fptr)->cn_uncompressed, ii, &nelem, &offset, status); if (nelem) break; } if (!nelem) { tstatus = 0; ffgcno(outfptr, CASEINSEN, "UNCOMPRESSED_DATA", &colnum, &tstatus); if (tstatus == 0) { /* make sure table is properly terminated before deleting col */ /* (in particular, make sure the '1PB(nnn)' keyword is updated */ ffrdef(outfptr, status); ffdcol(outfptr, colnum, status); } } } return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_compress_tile (fitsfile *outfptr, long row, int datatype, void *tiledata, long tilelen, long tilenx, long tileny, int *status) /* This is the main compression routine. This routine does the following to the input tile of pixels: - if it is a float or double image, then it quantizes the pixels - compresses the integer pixel values - writes the compressed byte stream to the FITS file. If the tile cannot be quantized than the raw float or double values are written to the output table. The input tiledata array must only be of type TINT, TFLOAT, or TDOUBLE. Shorter integer types will be type converted to TINT, under the assumption that the input array was allocated with enough scratch space to do this in place in memory. This array may be modified by this routine. If the array is of type TINT or TFLOAT, and the compression type is HCOMPRESS, then it must have been allocated to be twice as large (8 bytes per pixel) to provide scratch space. */ { int *idata = 0; /* quantized integer data */ short *cbuf; /* compressed data */ short *sbuff; unsigned short *usbuff; int clen; /* size of cbuf */ int flag = 1; /* true by default; only = 0 if float data couldn't be quantized */ int iminval = 0, imaxval = 0; /* min and max quantized integers */ double bscale[1] = {1.}, bzero[1] = {0.}; /* scaling parameters */ int nelem = 0; /* number of bytes */ size_t gzip_nelem = 0; long ii, hcomp_len; LONGLONG *lldata; signed char *sbbuff; unsigned char *usbbuff; long *lbuff; unsigned long *ulbuff; int hcompscale; if (*status > 0) return(*status); idata = (int *) tiledata; hcompscale = (outfptr->Fptr)->hcomp_scale; /* convert input tile array in place to 4-byte ints for compression */ /* Note that the calling routine must have allocated the array big enough */ /* to be able to do this. */ if (datatype == TSHORT) { sbuff = (short *) tiledata; for (ii = tilelen; ii >= 0; ii--) idata[ii] = (int) sbuff[ii]; } else if (datatype == TUSHORT) { usbuff = (unsigned short *) tiledata; for (ii = tilelen; ii >= 0; ii--) idata[ii] = (int) usbuff[ii]; } else if (datatype == TBYTE) { usbbuff = (unsigned char *) tiledata; for (ii = tilelen; ii >= 0; ii--) idata[ii] = (int) usbbuff[ii]; } else if (datatype == TSBYTE) { sbbuff = (signed char *) tiledata; for (ii = tilelen; ii >= 0; ii--) idata[ii] = (int) sbbuff[ii]; } else if (datatype == TLONG && sizeof(long) == 8) { /* warning: potential for data overflow here */ lbuff = (long *) tiledata; for (ii = 0; ii < tilelen; ii++) idata[ii] = (int) lbuff[ii]; } else if (datatype == TULONG && sizeof(long) == 8) { /* warning: potential for data overflow here */ ulbuff = (unsigned long *) tiledata; for (ii = 0; ii < tilelen; ii++) idata[ii] = (int) ulbuff[ii]; } else if (datatype == TFLOAT) { /* if the tile-compressed table contains zscale and zzero columns */ /* then scale and quantize the input floating point data. */ /* Otherwise, just truncate the floats to integers. */ if ((outfptr->Fptr)->cn_zscale > 0) { /* quantize the float values into integers */ flag = fits_quantize_float ((float *) tiledata, tilelen, FLOATNULLVALUE, (outfptr->Fptr)->noise_nbits, idata, bscale, bzero, &iminval, &imaxval); /* adjust the hcompress scale by the same scaling factor */ if (hcompscale > 1) hcompscale = (int) (hcompscale / bscale[0]); } else { for (ii = 0; ii < tilelen; ii++) idata[ii] = (int) (((float *)tiledata)[ii]); } } else if (datatype == TDOUBLE) { /* if the tile-compressed table contains zscale and zzero columns */ /* then scale and quantize the input floating point data. */ /* Otherwise, just truncate the floats to integers. */ if ((outfptr->Fptr)->cn_zscale > 0) { /* quantize the double values into integers */ flag = fits_quantize_double ((double *) tiledata, tilelen, DOUBLENULLVALUE, (outfptr->Fptr)->noise_nbits, idata, bscale, bzero, &iminval, &imaxval); /* adjust the hcompress scale by the same scaling factor */ if (hcompscale > 1) hcompscale = (int) (hcompscale / bscale[0]); } else { for (ii = 0; ii < tilelen; ii++) idata[ii] = (int) (((double *)tiledata)[ii]); } } else if (datatype != TINT && datatype != TUINT) { ffpmsg("unsupported datatype (imcomp_compress_tile)"); return(*status = BAD_DATATYPE); } if (flag) /* we can now compress the int array */ { /* allocate buffer for the compressed tile bytes */ clen = (outfptr->Fptr)->maxelem; cbuf = (short *) calloc (clen, sizeof (unsigned char)); if (cbuf == NULL) { ffpmsg("Out of memory. (imcomp_compress_tile)"); return (*status = MEMORY_ALLOCATION); } /* Compress the integer data, then write the compressed bytes */ if ( (outfptr->Fptr)->compress_type == RICE_1) { nelem = fits_rcomp (idata, tilelen, (unsigned char *) cbuf, clen, (outfptr->Fptr)->rice_blocksize); /* Write the compressed byte stream. */ ffpclb(outfptr, (outfptr->Fptr)->cn_compressed, row, 1, nelem, (unsigned char *) cbuf, status); } else if ( (outfptr->Fptr)->compress_type == PLIO_1) { if (iminval < 0 || imaxval > 16777215) { /* plio algorithn only supports positive 24 bit ints */ ffpmsg("data out of range for PLIO compression (0 - 2**24)"); return(*status = DATA_DECOMPRESSION_ERR); } nelem = pl_p2li (idata, 1, cbuf, tilelen); /* Write the compressed byte stream. */ ffpcli(outfptr, (outfptr->Fptr)->cn_compressed, row, 1, nelem, cbuf, status); } else if ( (outfptr->Fptr)->compress_type == GZIP_1) { #if BYTESWAPPED ffswap4(idata, tilelen); /* reverse order of bytes */ #endif compress2mem_from_mem((char *) idata, tilelen * sizeof(int), (char **) &cbuf, (size_t *) &clen, realloc, &gzip_nelem, status); /* Write the compressed byte stream. */ ffpclb(outfptr, (outfptr->Fptr)->cn_compressed, row, 1, gzip_nelem, (unsigned char *) cbuf, status); } else if ( (outfptr->Fptr)->compress_type == HCOMPRESS_1) { hcomp_len = clen; /* allocated size of the buffer */ if ((outfptr->Fptr)->zbitpix == BYTE_IMG || (outfptr->Fptr)->zbitpix == SHORT_IMG) { fits_hcompress(idata, tilenx, tileny, hcompscale, (char *) cbuf, &hcomp_len, status); } else { /* have to convert idata to an I*8 array, in place */ /* idata must have been allocated large enough to do this */ lldata = (LONGLONG *) idata; for (ii = tilelen; ii >= 0; ii--) { lldata[ii] = idata[ii];; } fits_hcompress64(lldata, tilenx, tileny, hcompscale, (char *) cbuf, &hcomp_len, status); } /* Write the compressed byte stream. */ ffpclb(outfptr, (outfptr->Fptr)->cn_compressed, row, 1, hcomp_len, (unsigned char *) cbuf, status); } if (nelem < 0) /* error condition */ { free (cbuf); ffpmsg ("error compressing row of the image (imcomp_compress_tile)"); return (*status = DATA_COMPRESSION_ERR); } if ((outfptr->Fptr)->cn_zscale > 0) { /* write the linear scaling parameters */ ffpcld (outfptr, (outfptr->Fptr)->cn_zscale, row, 1, 1, bscale, status); ffpcld (outfptr, (outfptr->Fptr)->cn_zzero, row, 1, 1, bzero, status); } free(cbuf); /* finished with this buffer */ } else /* floating point data couldn't be quantized */ { /* Write the original floating point data. */ if (datatype == TFLOAT) { ffpcle (outfptr, (outfptr->Fptr)->cn_uncompressed, row, 1, tilelen, (float *)tiledata, status); } else if (datatype == TDOUBLE) { ffpcld (outfptr, (outfptr->Fptr)->cn_uncompressed, row, 1, tilelen, (double *)tiledata, status); } } return (*status); } /*---------------------------------------------------------------------------*/ int fits_write_compressed_img(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be written */ long *infpixel, /* I - 'bottom left corner' of the subsection */ long *inlpixel, /* I - 'top right corner' of the subsection */ int nullcheck, /* I - 0 for no null checking */ /* 1: pixels that are = nullval will be */ /* written with the FITS null pixel value */ /* (floating point arrays only) */ void *array, /* I - array of values to be written */ void *nullval, /* I - undefined pixel value (floating pt only) */ int *status) /* IO - error status */ /* Write a section of a compressed image. */ { int naxis[MAX_COMPRESS_DIM], tiledim[MAX_COMPRESS_DIM]; long tilesize[MAX_COMPRESS_DIM], thistilesize[MAX_COMPRESS_DIM]; long ftile[MAX_COMPRESS_DIM], ltile[MAX_COMPRESS_DIM]; long tfpixel[MAX_COMPRESS_DIM], tlpixel[MAX_COMPRESS_DIM]; long rowdim[MAX_COMPRESS_DIM], offset[MAX_COMPRESS_DIM],ntemp; long fpixel[MAX_COMPRESS_DIM], lpixel[MAX_COMPRESS_DIM]; int ii, i5, i4, i3, i2, i1, i0, ndim, irow, pixlen, tilenul; int anynull, tstatus, buffpixsiz; long totpix; void *buffer; char *bnullarray = 0, card[FLEN_CARD]; float floatnull = 0.; double doublenull = 0.; if (*status > 0) return(*status); if (!fits_is_compressed_image(fptr, status) ) { ffpmsg("CHDU is not a compressed image (fits_write_compressed_img)"); return(*status = DATA_COMPRESSION_ERR); } /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* get temporary space for uncompressing one image tile */ /* Need at least 4-byte per pixel, and in some cases 8-bytes per pixel, */ buffpixsiz = 4; if ( (fptr->Fptr)->compress_type == HCOMPRESS_1 && ((fptr->Fptr)->zbitpix != BYTE_IMG && (fptr->Fptr)->zbitpix != SHORT_IMG) ){ buffpixsiz = 8; } if (datatype == TDOUBLE) buffpixsiz = 8; /* cast to double to force alignment on 8-byte addresses */ buffer = (double *) calloc ((fptr->Fptr)->maxtilelen, buffpixsiz); if (datatype == TSHORT || datatype == TUSHORT) { pixlen = sizeof(short); } else if (datatype == TINT || datatype == TUINT) { pixlen = sizeof(int); } else if (datatype == TBYTE || datatype == TSBYTE) { pixlen = 1; } else if (datatype == TLONG || datatype == TULONG) { pixlen = sizeof(long); } else if (datatype == TFLOAT) { pixlen = sizeof(float); } else if (datatype == TDOUBLE) { pixlen = sizeof(double); } else { ffpmsg("unsupported datatype for compressing image"); return(*status = BAD_DATATYPE); } if (buffer == NULL) { ffpmsg("Out of memory (fits_write_compress_img)"); return (*status = MEMORY_ALLOCATION); } /* initialize all the arrays */ for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { naxis[ii] = 1; tiledim[ii] = 1; tilesize[ii] = 1; ftile[ii] = 1; ltile[ii] = 1; rowdim[ii] = 1; } ndim = (fptr->Fptr)->zndim; ntemp = 1; for (ii = 0; ii < ndim; ii++) { fpixel[ii] = infpixel[ii]; lpixel[ii] = inlpixel[ii]; /* calc number of tiles in each dimension, and tile containing */ /* the first and last pixel we want to read in each dimension */ naxis[ii] = (fptr->Fptr)->znaxis[ii]; if (fpixel[ii] < 1) { free(buffer); return(*status = BAD_PIX_NUM); } tilesize[ii] = (fptr->Fptr)->tilesize[ii]; tiledim[ii] = (naxis[ii] - 1) / tilesize[ii] + 1; ftile[ii] = (fpixel[ii] - 1) / tilesize[ii] + 1; ltile[ii] = minvalue((lpixel[ii] - 1) / tilesize[ii] + 1, tiledim[ii]); rowdim[ii] = ntemp; /* total tiles in each dimension */ ntemp *= tiledim[ii]; } /* support up to 6 dimensions for now */ /* tfpixel and tlpixel are the first and last image pixels */ /* along each dimension of the compression tile */ for (i5 = ftile[5]; i5 <= ltile[5]; i5++) { tfpixel[5] = (i5 - 1) * tilesize[5] + 1; tlpixel[5] = minvalue(tfpixel[5] + tilesize[5] - 1, naxis[5]); thistilesize[5] = tlpixel[5] - tfpixel[5] + 1; offset[5] = (i5 - 1) * rowdim[5]; for (i4 = ftile[4]; i4 <= ltile[4]; i4++) { tfpixel[4] = (i4 - 1) * tilesize[4] + 1; tlpixel[4] = minvalue(tfpixel[4] + tilesize[4] - 1, naxis[4]); thistilesize[4] = thistilesize[5] * (tlpixel[4] - tfpixel[4] + 1); offset[4] = (i4 - 1) * rowdim[4] + offset[5]; for (i3 = ftile[3]; i3 <= ltile[3]; i3++) { tfpixel[3] = (i3 - 1) * tilesize[3] + 1; tlpixel[3] = minvalue(tfpixel[3] + tilesize[3] - 1, naxis[3]); thistilesize[3] = thistilesize[4] * (tlpixel[3] - tfpixel[3] + 1); offset[3] = (i3 - 1) * rowdim[3] + offset[4]; for (i2 = ftile[2]; i2 <= ltile[2]; i2++) { tfpixel[2] = (i2 - 1) * tilesize[2] + 1; tlpixel[2] = minvalue(tfpixel[2] + tilesize[2] - 1, naxis[2]); thistilesize[2] = thistilesize[3] * (tlpixel[2] - tfpixel[2] + 1); offset[2] = (i2 - 1) * rowdim[2] + offset[3]; for (i1 = ftile[1]; i1 <= ltile[1]; i1++) { tfpixel[1] = (i1 - 1) * tilesize[1] + 1; tlpixel[1] = minvalue(tfpixel[1] + tilesize[1] - 1, naxis[1]); thistilesize[1] = thistilesize[2] * (tlpixel[1] - tfpixel[1] + 1); offset[1] = (i1 - 1) * rowdim[1] + offset[2]; for (i0 = ftile[0]; i0 <= ltile[0]; i0++) { tfpixel[0] = (i0 - 1) * tilesize[0] + 1; tlpixel[0] = minvalue(tfpixel[0] + tilesize[0] - 1, naxis[0]); thistilesize[0] = thistilesize[1] * (tlpixel[0] - tfpixel[0] + 1); /* calculate row of table containing this tile */ irow = i0 + offset[1]; /* read and uncompress this row (tile) of the table */ /* also do type conversion and undefined pixel substitution */ /* at this point */ imcomp_decompress_tile(fptr, irow, thistilesize[0], datatype, nullcheck, nullval, buffer, bnullarray, &tilenul, status); if (*status == NO_COMPRESSED_TILE) { /* tile doesn't exist, so initialize to zero */ memset(buffer, 0, pixlen * thistilesize[0]); *status = 0; } /* copy the intersecting pixels to this tile from the input */ imcomp_merge_overlap(buffer, pixlen, ndim, tfpixel, tlpixel, bnullarray, array, fpixel, lpixel, nullcheck, status); /* compress the tile again, and write it back to the FITS file */ imcomp_compress_tile (fptr, irow, datatype, buffer, thistilesize[0], tlpixel[0] - tfpixel[0] + 1, tlpixel[1] - tfpixel[1] + 1, status); } } } } } } free(buffer); /* if the input array has a floating point datatype, and if *nullval is not equal to zero, and if there are any pixels in the array that are equal to the value of *nullval, then we need to make sure that the ZBLANK keyword is present in the compressed image header. If it is not there then we need to insert the keyword. */ if (datatype >= TFLOAT && nullval != 0) { /* OK, this is a floating point data type, with a null value */ if (datatype == TFLOAT) floatnull = *((float *) nullval); else if (datatype == TDOUBLE) doublenull = *((double *) nullval); if (floatnull != 0. || doublenull != 0.) { /* OK, the null value is not = 0 */ /* calculate the size of the imput array */ totpix = 1; for (ii = 0; ii < ndim; ii++) { totpix *= (inlpixel[ii] - infpixel[ii]); } if (totpix <= 0) return(*status); anynull = 0; if (datatype == TFLOAT) { for (ii = 0; ii < totpix; ii++) { if (((float *)array)[ii] == floatnull) { anynull = 1; break; } } } else if (datatype == TDOUBLE) { for (ii = 0; ii < totpix; ii++) { if (((double *)array)[ii] == doublenull) { anynull = 1; break; } } } if (anynull) { /* there are null values in the array */ tstatus = 0; ffgcrd(fptr, "ZBLANK", card, &tstatus); if (tstatus) { /* have to insert the ZBLANK keyword */ ffgcrd(fptr, "ZCMPTYPE", card, status); ffikyj(fptr, "ZBLANK", COMPRESS_NULL_VALUE, "null value in the compressed integer array", status); } } /* there are null values in the array */ } /* non-zero null value */ } /* floating point data type */ return(*status); } /*--------------------------------------------------------------------------*/ int fits_write_compressed_pixels(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be written */ LONGLONG fpixel, /* I - 'first pixel to write */ LONGLONG npixel, /* I - number of pixels to write */ int nullcheck, /* I - 0 for no null checking */ /* 1: pixels that are = nullval will be */ /* written with the FITS null pixel value */ /* (floating point arrays only) */ void *array, /* I - array of values to write */ void *nullval, /* I - value used to represent undefined pixels*/ int *status) /* IO - error status */ /* Write a consecutive set of pixels to a compressed image. This routine interpretes the n-dimensional image as a long one-dimensional array. This is actually a rather inconvenient way to write compressed images in general, and could be rather inefficient if the requested pixels to be written are located in many different image compression tiles. The general strategy used here is to write the requested pixels in blocks that correspond to rectangular image sections. */ { int naxis, ii, bytesperpixel; long naxes[MAX_COMPRESS_DIM], nread; LONGLONG tfirst, tlast, last0, last1, dimsize[MAX_COMPRESS_DIM]; long nplane, firstcoord[MAX_COMPRESS_DIM], lastcoord[MAX_COMPRESS_DIM]; char *arrayptr; if (*status > 0) return(*status); arrayptr = (char *) array; /* get size of array pixels, in bytes */ bytesperpixel = ffpxsz(datatype); for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { naxes[ii] = 1; firstcoord[ii] = 0; lastcoord[ii] = 0; } /* determine the dimensions of the image to be read */ ffgidm(fptr, &naxis, status); ffgisz(fptr, MAX_COMPRESS_DIM, naxes, status); /* calc the cumulative number of pixels in each successive dimension */ dimsize[0] = 1; for (ii = 1; ii < MAX_COMPRESS_DIM; ii++) dimsize[ii] = dimsize[ii - 1] * naxes[ii - 1]; /* determine the coordinate of the first and last pixel in the image */ /* Use zero based indexes here */ tfirst = fpixel - 1; tlast = tfirst + npixel - 1; for (ii = naxis - 1; ii >= 0; ii--) { firstcoord[ii] = (long) (tfirst / dimsize[ii]); lastcoord[ii] = (long) (tlast / dimsize[ii]); tfirst = tfirst - firstcoord[ii] * dimsize[ii]; tlast = tlast - lastcoord[ii] * dimsize[ii]; } /* to simplify things, treat 1-D, 2-D, and 3-D images as separate cases */ if (naxis == 1) { /* Simple: just write the requested range of pixels */ firstcoord[0] = firstcoord[0] + 1; lastcoord[0] = lastcoord[0] + 1; fits_write_compressed_img(fptr, datatype, firstcoord, lastcoord, nullcheck, array, nullval, status); return(*status); } else if (naxis == 2) { nplane = 0; /* write 1st (and only) plane of the image */ fits_write_compressed_img_plane(fptr, datatype, bytesperpixel, nplane, firstcoord, lastcoord, naxes, nullcheck, array, nullval, &nread, status); } else if (naxis == 3) { /* test for special case: writing an integral number of planes */ if (firstcoord[0] == 0 && firstcoord[1] == 0 && lastcoord[0] == naxes[0] - 1 && lastcoord[1] == naxes[1] - 1) { for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { /* convert from zero base to 1 base */ (firstcoord[ii])++; (lastcoord[ii])++; } /* we can write the contiguous block of pixels in one go */ fits_write_compressed_img(fptr, datatype, firstcoord, lastcoord, nullcheck, array, nullval, status); return(*status); } /* save last coordinate in temporary variables */ last0 = lastcoord[0]; last1 = lastcoord[1]; if (firstcoord[2] < lastcoord[2]) { /* we will write up to the last pixel in all but the last plane */ lastcoord[0] = naxes[0] - 1; lastcoord[1] = naxes[1] - 1; } /* write one plane of the cube at a time, for simplicity */ for (nplane = firstcoord[2]; nplane <= lastcoord[2]; nplane++) { if (nplane == lastcoord[2]) { lastcoord[0] = (long) last0; lastcoord[1] = (long) last1; } fits_write_compressed_img_plane(fptr, datatype, bytesperpixel, nplane, firstcoord, lastcoord, naxes, nullcheck, arrayptr, nullval, &nread, status); /* for all subsequent planes, we start with the first pixel */ firstcoord[0] = 0; firstcoord[1] = 0; /* increment pointers to next elements to be written */ arrayptr = arrayptr + nread * bytesperpixel; } } else { ffpmsg("only 1D, 2D, or 3D images are currently supported"); return(*status = DATA_COMPRESSION_ERR); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_write_compressed_img_plane(fitsfile *fptr, /* I - FITS file */ int datatype, /* I - datatype of the array to be written */ int bytesperpixel, /* I - number of bytes per pixel in array */ long nplane, /* I - which plane of the cube to write */ long *firstcoord, /* I coordinate of first pixel to write */ long *lastcoord, /* I coordinate of last pixel to write */ long *naxes, /* I size of each image dimension */ int nullcheck, /* I - 0 for no null checking */ /* 1: pixels that are = nullval will be */ /* written with the FITS null pixel value */ /* (floating point arrays only) */ void *array, /* I - array of values that are written */ void *nullval, /* I - value for undefined pixels */ long *nread, /* O - total number of pixels written */ int *status) /* IO - error status */ /* in general we have to write the first partial row of the image, followed by the middle complete rows, followed by the last partial row of the image. If the first or last rows are complete, then write them at the same time as all the middle rows. */ { /* bottom left coord. and top right coord. */ long blc[MAX_COMPRESS_DIM], trc[MAX_COMPRESS_DIM]; char *arrayptr; *nread = 0; arrayptr = (char *) array; blc[2] = nplane + 1; trc[2] = nplane + 1; if (firstcoord[0] != 0) { /* have to read a partial first row */ blc[0] = firstcoord[0] + 1; blc[1] = firstcoord[1] + 1; trc[1] = blc[1]; if (lastcoord[1] == firstcoord[1]) trc[0] = lastcoord[0] + 1; /* 1st and last pixels in same row */ else trc[0] = naxes[0]; /* read entire rest of the row */ fits_write_compressed_img(fptr, datatype, blc, trc, nullcheck, arrayptr, nullval, status); *nread = *nread + trc[0] - blc[0] + 1; if (lastcoord[1] == firstcoord[1]) { return(*status); /* finished */ } /* set starting coord to beginning of next line */ firstcoord[0] = 0; firstcoord[1] += 1; arrayptr = arrayptr + (trc[0] - blc[0] + 1) * bytesperpixel; } /* write contiguous complete rows of the image, if any */ blc[0] = 1; blc[1] = firstcoord[1] + 1; trc[0] = naxes[0]; if (lastcoord[0] + 1 == naxes[0]) { /* can write the last complete row, too */ trc[1] = lastcoord[1] + 1; } else { /* last row is incomplete; have to read it separately */ trc[1] = lastcoord[1]; } if (trc[1] >= blc[1]) /* must have at least one whole line to read */ { fits_write_compressed_img(fptr, datatype, blc, trc, nullcheck, arrayptr, nullval, status); *nread = *nread + (trc[1] - blc[1] + 1) * naxes[0]; if (lastcoord[1] + 1 == trc[1]) return(*status); /* finished */ /* increment pointers for the last partial row */ arrayptr = arrayptr + (trc[1] - blc[1] + 1) * naxes[0] * bytesperpixel; } if (trc[1] == lastcoord[1] + 1) return(*status); /* all done */ /* set starting and ending coord to last line */ trc[0] = lastcoord[0] + 1; trc[1] = lastcoord[1] + 1; blc[1] = trc[1]; fits_write_compressed_img(fptr, datatype, blc, trc, nullcheck, arrayptr, nullval, status); *nread = *nread + trc[0] - blc[0] + 1; return(*status); } /* ######################################################################## */ /* ### Image Decompression Routines ### */ /* ######################################################################## */ /*--------------------------------------------------------------------------*/ int fits_img_decompress (fitsfile *infptr, /* image (bintable) to uncompress */ fitsfile *outfptr, /* empty HDU for output uncompressed image */ int *status) /* IO - error status */ /* This routine decompresses the whole image and writes it to the output file. */ { double *data; int ii, datatype = 0, byte_per_pix = 0, naxis, bitpix, numkeys; int nullcheck, anynul, tstatus, nullprime = 0, hdupos, norec = 0; LONGLONG fpixel[MAX_COMPRESS_DIM], lpixel[MAX_COMPRESS_DIM]; long inc[MAX_COMPRESS_DIM], naxes[MAX_COMPRESS_DIM]; long imgsize, memsize; float *nulladdr, fnulval; double dnulval; char card[FLEN_CARD]; if (*status > 0) return(*status); if (!fits_is_compressed_image(infptr, status) ) { ffpmsg("CHDU is not a compressed image (fits_img_decompress)"); return(*status = DATA_DECOMPRESSION_ERR); } /* get information about the state of the output file; does it already */ /* contain any keywords and HDUs? */ fits_get_hdu_num(outfptr, &hdupos); /* Get the current output HDU position */ fits_get_hdrspace(outfptr, &numkeys, 0, status); /* Was the input compressed HDU originally the primary array image? */ tstatus = 0; if (!fits_read_card(infptr, "ZSIMPLE", card, &tstatus)) { /* yes, input HDU was a primary array (not an IMAGE extension) */ /* Now determine if we can uncompress it into the primary array of */ /* the output file. This is only possible if the output file */ /* currently only contains a null primary array, with no addition */ /* header keywords and with no following extension in the FITS file. */ if (hdupos == 1) { /* are we positioned at the primary array? */ if (numkeys <= 10) { /* is the header practically empty? */ if (numkeys == 0) { /* primary HDU is completely empty */ nullprime = 1; } else { fits_get_img_param(outfptr, 9, &bitpix, &naxis, naxes, status); if (naxis == 0) /* is this a null image? */ nullprime = 1; } } } } if (nullprime) { /* We will delete the existing keywords in the null primary array and uncompress the input image into the primary array of the output */ for (ii = numkeys; ii > 0; ii--) fits_delete_record(outfptr, ii, status); } else { /* if the ZTENSION keyword doesn't exist, then we have to write the required keywords manually */ tstatus = 0; if (fits_read_card(infptr, "ZTENSION", card, &tstatus)) { /* create an empty output image with the correct dimensions */ if (ffcrim(outfptr, (infptr->Fptr)->zbitpix, (infptr->Fptr)->zndim, (infptr->Fptr)->znaxis, status) > 0) { ffpmsg("error creating output decompressed image HDU"); return (*status); } norec = 1; /* the required keywords have already been written */ } else { if (numkeys == 0) { /* the output file is currently completely empty */ /* In this case, the input is a compressed IMAGE extension. */ /* Since the uncompressed output file is currently completely empty, */ /* we need to write a null primary array before uncompressing the */ /* image extension */ ffcrim(outfptr, 8, 0, naxes, status); /* naxes is not used */ /* now create the empty extension to uncompress into */ if (fits_create_hdu(outfptr, status) > 0) { ffpmsg("error creating output decompressed image HDU"); return (*status); } } else { /* just create a new empty extension, then copy all the required */ /* keywords into it. */ fits_create_hdu(outfptr, status); } } } if (*status > 0) { ffpmsg("error creating output decompressed image HDU"); return (*status); } /* Copy the table header to the image header. */ if (imcomp_copy_comp2img(infptr, outfptr, norec, status) > 0) { ffpmsg("error copying header keywords from compressed image"); return (*status); } /* force a rescan of the output header keywords, then reset the scaling */ /* in case the BSCALE and BZERO keywords are present, so that the */ /* decompressed values won't be scaled when written to the output image */ ffrdef(outfptr, status); ffpscl(outfptr, 1.0, 0.0, status); ffpscl(infptr, 1.0, 0.0, status); /* initialize; no null checking is needed for integer images */ nullcheck = 0; nulladdr = &fnulval; /* determine datatype for image */ if ((infptr->Fptr)->zbitpix == BYTE_IMG) { datatype = TBYTE; byte_per_pix = 1; } else if ((infptr->Fptr)->zbitpix == SHORT_IMG) { datatype = TSHORT; byte_per_pix = sizeof(short); } else if ((infptr->Fptr)->zbitpix == LONG_IMG) { datatype = TINT; byte_per_pix = sizeof(int); } else if ((infptr->Fptr)->zbitpix == FLOAT_IMG) { /* In the case of float images we must check for NaNs */ nullcheck = 1; fnulval = FLOATNULLVALUE; nulladdr = &fnulval; datatype = TFLOAT; byte_per_pix = sizeof(float); } else if ((infptr->Fptr)->zbitpix == DOUBLE_IMG) { /* In the case of double images we must check for NaNs */ nullcheck = 1; dnulval = DOUBLENULLVALUE; nulladdr = (float *) &dnulval; datatype = TDOUBLE; byte_per_pix = sizeof(double); } /* calculate size of the image (in pixels) */ imgsize = 1; for (ii = 0; ii < (infptr->Fptr)->zndim; ii++) { imgsize *= (infptr->Fptr)->znaxis[ii]; fpixel[ii] = 1; /* Set first and last pixel to */ lpixel[ii] = (infptr->Fptr)->znaxis[ii]; /* include the entire image. */ inc[ii] = 1; } /* Calc equivalent number of double pixels same size as whole the image. */ /* We use double datatype to force the memory to be aligned properly */ memsize = ((imgsize * byte_per_pix) - 1) / sizeof(double) + 1; /* allocate memory for the image */ data = (double*) calloc (memsize, sizeof(double)); if (!data) { ffpmsg("Couldn't allocate memory for the uncompressed image"); return(*status = MEMORY_ALLOCATION); } /* uncompress the entire image into memory */ /* This routine should be enhanced sometime to only need enough */ /* memory to uncompress one tile at a time. */ fits_read_compressed_img(infptr, datatype, fpixel, lpixel, inc, nullcheck, nulladdr, data, NULL, &anynul, status); /* write the image to the output file */ if (anynul) fits_write_imgnull(outfptr, datatype, 1, imgsize, data, nulladdr, status); else fits_write_img(outfptr, datatype, 1, imgsize, data, status); free(data); return (*status); } /*--------------------------------------------------------------------------*/ int fits_decompress_img (fitsfile *infptr, /* image (bintable) to uncompress */ fitsfile *outfptr, /* empty HDU for output uncompressed image */ int *status) /* IO - error status */ /* This routine decompresses the whole image and writes it to the output file. */ { double *data; int ii, datatype = 0, byte_per_pix = 0; int nullcheck, anynul; LONGLONG fpixel[MAX_COMPRESS_DIM], lpixel[MAX_COMPRESS_DIM]; long inc[MAX_COMPRESS_DIM]; long imgsize, memsize; float *nulladdr, fnulval; double dnulval; if (*status > 0) return(*status); if (!fits_is_compressed_image(infptr, status) ) { ffpmsg("CHDU is not a compressed image (fits_decompress_img)"); return(*status = DATA_DECOMPRESSION_ERR); } /* create an empty output image with the correct dimensions */ if (ffcrim(outfptr, (infptr->Fptr)->zbitpix, (infptr->Fptr)->zndim, (infptr->Fptr)->znaxis, status) > 0) { ffpmsg("error creating output decompressed image HDU"); return (*status); } /* Copy the table header to the image header. */ if (imcomp_copy_imheader(infptr, outfptr, status) > 0) { ffpmsg("error copying header of compressed image"); return (*status); } /* force a rescan of the output header keywords, then reset the scaling */ /* in case the BSCALE and BZERO keywords are present, so that the */ /* decompressed values won't be scaled when written to the output image */ ffrdef(outfptr, status); ffpscl(outfptr, 1.0, 0.0, status); ffpscl(infptr, 1.0, 0.0, status); /* initialize; no null checking is needed for integer images */ nullcheck = 0; nulladdr = &fnulval; /* determine datatype for image */ if ((infptr->Fptr)->zbitpix == BYTE_IMG) { datatype = TBYTE; byte_per_pix = 1; } else if ((infptr->Fptr)->zbitpix == SHORT_IMG) { datatype = TSHORT; byte_per_pix = sizeof(short); } else if ((infptr->Fptr)->zbitpix == LONG_IMG) { datatype = TINT; byte_per_pix = sizeof(int); } else if ((infptr->Fptr)->zbitpix == FLOAT_IMG) { /* In the case of float images we must check for NaNs */ nullcheck = 1; fnulval = FLOATNULLVALUE; nulladdr = &fnulval; datatype = TFLOAT; byte_per_pix = sizeof(float); } else if ((infptr->Fptr)->zbitpix == DOUBLE_IMG) { /* In the case of double images we must check for NaNs */ nullcheck = 1; dnulval = DOUBLENULLVALUE; nulladdr = (float *) &dnulval; datatype = TDOUBLE; byte_per_pix = sizeof(double); } /* calculate size of the image (in pixels) */ imgsize = 1; for (ii = 0; ii < (infptr->Fptr)->zndim; ii++) { imgsize *= (infptr->Fptr)->znaxis[ii]; fpixel[ii] = 1; /* Set first and last pixel to */ lpixel[ii] = (infptr->Fptr)->znaxis[ii]; /* include the entire image. */ inc[ii] = 1; } /* Calc equivalent number of double pixels same size as whole the image. */ /* We use double datatype to force the memory to be aligned properly */ memsize = ((imgsize * byte_per_pix) - 1) / sizeof(double) + 1; /* allocate memory for the image */ data = (double*) calloc (memsize, sizeof(double)); if (!data) { ffpmsg("Couldn't allocate memory for the uncompressed image"); return(*status = MEMORY_ALLOCATION); } /* uncompress the entire image into memory */ /* This routine should be enhanced sometime to only need enough */ /* memory to uncompress one tile at a time. */ fits_read_compressed_img(infptr, datatype, fpixel, lpixel, inc, nullcheck, nulladdr, data, NULL, &anynul, status); /* write the image to the output file */ if (anynul) fits_write_imgnull(outfptr, datatype, 1, imgsize, data, nulladdr, status); else fits_write_img(outfptr, datatype, 1, imgsize, data, status); free(data); return (*status); } /*---------------------------------------------------------------------------*/ int fits_read_compressed_img(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be returned */ LONGLONG *infpixel, /* I - 'bottom left corner' of the subsection */ LONGLONG *inlpixel, /* I - 'top right corner' of the subsection */ long *ininc, /* I - increment to be applied in each dimension */ int nullcheck, /* I - 0 for no null checking */ /* 1: set undefined pixels = nullval */ /* 2: set nullarray=1 for undefined pixels */ void *nullval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of flags = 1 if nullcheck = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a section of a compressed image; Note: lpixel may be larger than the size of the uncompressed image. Only the pixels within the image will be returned. */ { int naxis[MAX_COMPRESS_DIM], tiledim[MAX_COMPRESS_DIM]; long tilesize[MAX_COMPRESS_DIM], thistilesize[MAX_COMPRESS_DIM]; long ftile[MAX_COMPRESS_DIM], ltile[MAX_COMPRESS_DIM]; long tfpixel[MAX_COMPRESS_DIM], tlpixel[MAX_COMPRESS_DIM]; long rowdim[MAX_COMPRESS_DIM], offset[MAX_COMPRESS_DIM],ntemp; long fpixel[MAX_COMPRESS_DIM], lpixel[MAX_COMPRESS_DIM]; long inc[MAX_COMPRESS_DIM]; int ii, i5, i4, i3, i2, i1, i0, ndim, irow, pixlen, tilenul; void *buffer; char *bnullarray = 0; if (*status > 0) return(*status); if (!fits_is_compressed_image(fptr, status) ) { ffpmsg("CHDU is not a compressed image (fits_read_compressed_img)"); return(*status = DATA_DECOMPRESSION_ERR); } /* get temporary space for uncompressing one image tile */ if (datatype == TSHORT) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (short)); pixlen = sizeof(short); } else if (datatype == TINT) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (int)); pixlen = sizeof(int); } else if (datatype == TLONG) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (long)); pixlen = sizeof(long); } else if (datatype == TFLOAT) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (float)); pixlen = sizeof(float); } else if (datatype == TDOUBLE) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (double)); pixlen = sizeof(double); } else if (datatype == TUSHORT) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (unsigned short)); pixlen = sizeof(short); } else if (datatype == TUINT) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (unsigned int)); pixlen = sizeof(int); } else if (datatype == TULONG) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (unsigned long)); pixlen = sizeof(long); } else if (datatype == TBYTE || datatype == TSBYTE) { buffer = calloc ((fptr->Fptr)->maxtilelen, sizeof (char)); pixlen = 1; } else { ffpmsg("unsupported datatype for uncompressing image"); return(*status = BAD_DATATYPE); } if (buffer == NULL) { ffpmsg("Out of memory (fits_read_compress_img)"); return (*status = MEMORY_ALLOCATION); } /* allocate memory for a null flag array, if needed */ if (nullcheck == 2) { bnullarray = calloc ((fptr->Fptr)->maxtilelen, sizeof (char)); if (bnullarray == NULL) { ffpmsg("Out of memory (fits_read_compress_img)"); free(buffer); return (*status = MEMORY_ALLOCATION); } } /* initialize all the arrays */ for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { naxis[ii] = 1; tiledim[ii] = 1; tilesize[ii] = 1; ftile[ii] = 1; ltile[ii] = 1; rowdim[ii] = 1; } ndim = (fptr->Fptr)->zndim; ntemp = 1; for (ii = 0; ii < ndim; ii++) { /* support for mirror-reversed image sections */ if (infpixel[ii] <= inlpixel[ii]) { fpixel[ii] = (long) infpixel[ii]; lpixel[ii] = (long) inlpixel[ii]; inc[ii] = ininc[ii]; } else { fpixel[ii] = (long) inlpixel[ii]; lpixel[ii] = (long) infpixel[ii]; inc[ii] = -ininc[ii]; } /* calc number of tiles in each dimension, and tile containing */ /* the first and last pixel we want to read in each dimension */ naxis[ii] = (fptr->Fptr)->znaxis[ii]; if (fpixel[ii] < 1) { if (nullcheck == 2) { free(bnullarray); } free(buffer); return(*status = BAD_PIX_NUM); } tilesize[ii] = (fptr->Fptr)->tilesize[ii]; tiledim[ii] = (naxis[ii] - 1) / tilesize[ii] + 1; ftile[ii] = (fpixel[ii] - 1) / tilesize[ii] + 1; ltile[ii] = minvalue((lpixel[ii] - 1) / tilesize[ii] + 1, tiledim[ii]); rowdim[ii] = ntemp; /* total tiles in each dimension */ ntemp *= tiledim[ii]; } if (anynul) *anynul = 0; /* initialize */ /* support up to 6 dimensions for now */ /* tfpixel and tlpixel are the first and last image pixels */ /* along each dimension of the compression tile */ for (i5 = ftile[5]; i5 <= ltile[5]; i5++) { tfpixel[5] = (i5 - 1) * tilesize[5] + 1; tlpixel[5] = minvalue(tfpixel[5] + tilesize[5] - 1, naxis[5]); thistilesize[5] = tlpixel[5] - tfpixel[5] + 1; offset[5] = (i5 - 1) * rowdim[5]; for (i4 = ftile[4]; i4 <= ltile[4]; i4++) { tfpixel[4] = (i4 - 1) * tilesize[4] + 1; tlpixel[4] = minvalue(tfpixel[4] + tilesize[4] - 1, naxis[4]); thistilesize[4] = thistilesize[5] * (tlpixel[4] - tfpixel[4] + 1); offset[4] = (i4 - 1) * rowdim[4] + offset[5]; for (i3 = ftile[3]; i3 <= ltile[3]; i3++) { tfpixel[3] = (i3 - 1) * tilesize[3] + 1; tlpixel[3] = minvalue(tfpixel[3] + tilesize[3] - 1, naxis[3]); thistilesize[3] = thistilesize[4] * (tlpixel[3] - tfpixel[3] + 1); offset[3] = (i3 - 1) * rowdim[3] + offset[4]; for (i2 = ftile[2]; i2 <= ltile[2]; i2++) { tfpixel[2] = (i2 - 1) * tilesize[2] + 1; tlpixel[2] = minvalue(tfpixel[2] + tilesize[2] - 1, naxis[2]); thistilesize[2] = thistilesize[3] * (tlpixel[2] - tfpixel[2] + 1); offset[2] = (i2 - 1) * rowdim[2] + offset[3]; for (i1 = ftile[1]; i1 <= ltile[1]; i1++) { tfpixel[1] = (i1 - 1) * tilesize[1] + 1; tlpixel[1] = minvalue(tfpixel[1] + tilesize[1] - 1, naxis[1]); thistilesize[1] = thistilesize[2] * (tlpixel[1] - tfpixel[1] + 1); offset[1] = (i1 - 1) * rowdim[1] + offset[2]; for (i0 = ftile[0]; i0 <= ltile[0]; i0++) { tfpixel[0] = (i0 - 1) * tilesize[0] + 1; tlpixel[0] = minvalue(tfpixel[0] + tilesize[0] - 1, naxis[0]); thistilesize[0] = thistilesize[1] * (tlpixel[0] - tfpixel[0] + 1); /* calculate row of table containing this tile */ irow = i0 + offset[1]; /* printf("row %d, %d %d, %d %d, %d %d; %d\n", irow, tfpixel[0],tlpixel[0],tfpixel[1],tlpixel[1],tfpixel[2],tlpixel[2], thistilesize[0]); */ /* read and uncompress this row (tile) of the table */ /* also do type conversion and undefined pixel substitution */ /* at this point */ imcomp_decompress_tile(fptr, irow, thistilesize[0], datatype, nullcheck, nullval, buffer, bnullarray, &tilenul, status); if (tilenul && anynul) *anynul = 1; /* there are null pixels */ /* printf(" pixlen=%d, ndim=%d, %d %d %d, %d %d %d, %d %d %d\n", pixlen, ndim, fpixel[0],lpixel[0],inc[0],fpixel[1],lpixel[1],inc[1], fpixel[2],lpixel[2],inc[2]); */ /* copy the intersecting pixels from this tile to the output */ imcomp_copy_overlap(buffer, pixlen, ndim, tfpixel, tlpixel, bnullarray, array, fpixel, lpixel, inc, nullcheck, nullarray, status); } } } } } } if (nullcheck == 2) { free(bnullarray); } free(buffer); return(*status); } /*--------------------------------------------------------------------------*/ int fits_read_compressed_pixels(fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the array to be returned */ LONGLONG fpixel, /* I - 'first pixel to read */ LONGLONG npixel, /* I - number of pixels to read */ int nullcheck, /* I - 0 for no null checking */ /* 1: set undefined pixels = nullval */ /* 2: set nullarray=1 for undefined pixels */ void *nullval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of flags = 1 if nullcheck = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a consecutive set of pixels from a compressed image. This routine interpretes the n-dimensional image as a long one-dimensional array. This is actually a rather inconvenient way to read compressed images in general, and could be rather inefficient if the requested pixels to be read are located in many different image compression tiles. The general strategy used here is to read the requested pixels in blocks that correspond to rectangular image sections. */ { int naxis, ii, bytesperpixel, planenul; long naxes[MAX_COMPRESS_DIM], nread; long nplane, inc[MAX_COMPRESS_DIM]; LONGLONG tfirst, tlast, last0, last1, dimsize[MAX_COMPRESS_DIM]; LONGLONG firstcoord[MAX_COMPRESS_DIM], lastcoord[MAX_COMPRESS_DIM]; char *arrayptr, *nullarrayptr; if (*status > 0) return(*status); arrayptr = (char *) array; nullarrayptr = nullarray; /* get size of array pixels, in bytes */ bytesperpixel = ffpxsz(datatype); for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { naxes[ii] = 1; firstcoord[ii] = 0; lastcoord[ii] = 0; inc[ii] = 1; } /* determine the dimensions of the image to be read */ ffgidm(fptr, &naxis, status); ffgisz(fptr, MAX_COMPRESS_DIM, naxes, status); /* calc the cumulative number of pixels in each successive dimension */ dimsize[0] = 1; for (ii = 1; ii < MAX_COMPRESS_DIM; ii++) dimsize[ii] = dimsize[ii - 1] * naxes[ii - 1]; /* determine the coordinate of the first and last pixel in the image */ /* Use zero based indexes here */ tfirst = fpixel - 1; tlast = tfirst + npixel - 1; for (ii = naxis - 1; ii >= 0; ii--) { firstcoord[ii] = tfirst / dimsize[ii]; lastcoord[ii] = tlast / dimsize[ii]; tfirst = tfirst - firstcoord[ii] * dimsize[ii]; tlast = tlast - lastcoord[ii] * dimsize[ii]; } /* to simplify things, treat 1-D, 2-D, and 3-D images as separate cases */ if (naxis == 1) { /* Simple: just read the requested range of pixels */ firstcoord[0] = firstcoord[0] + 1; lastcoord[0] = lastcoord[0] + 1; fits_read_compressed_img(fptr, datatype, firstcoord, lastcoord, inc, nullcheck, nullval, array, nullarray, anynul, status); return(*status); } else if (naxis == 2) { nplane = 0; /* read 1st (and only) plane of the image */ fits_read_compressed_img_plane(fptr, datatype, bytesperpixel, nplane, firstcoord, lastcoord, inc, naxes, nullcheck, nullval, array, nullarray, anynul, &nread, status); } else if (naxis == 3) { /* test for special case: reading an integral number of planes */ if (firstcoord[0] == 0 && firstcoord[1] == 0 && lastcoord[0] == naxes[0] - 1 && lastcoord[1] == naxes[1] - 1) { for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { /* convert from zero base to 1 base */ (firstcoord[ii])++; (lastcoord[ii])++; } /* we can read the contiguous block of pixels in one go */ fits_read_compressed_img(fptr, datatype, firstcoord, lastcoord, inc, nullcheck, nullval, array, nullarray, anynul, status); return(*status); } if (anynul) *anynul = 0; /* initialize */ /* save last coordinate in temporary variables */ last0 = lastcoord[0]; last1 = lastcoord[1]; if (firstcoord[2] < lastcoord[2]) { /* we will read up to the last pixel in all but the last plane */ lastcoord[0] = naxes[0] - 1; lastcoord[1] = naxes[1] - 1; } /* read one plane of the cube at a time, for simplicity */ for (nplane = (long) firstcoord[2]; nplane <= lastcoord[2]; nplane++) { if (nplane == lastcoord[2]) { lastcoord[0] = last0; lastcoord[1] = last1; } fits_read_compressed_img_plane(fptr, datatype, bytesperpixel, nplane, firstcoord, lastcoord, inc, naxes, nullcheck, nullval, arrayptr, nullarrayptr, &planenul, &nread, status); if (planenul && anynul) *anynul = 1; /* there are null pixels */ /* for all subsequent planes, we start with the first pixel */ firstcoord[0] = 0; firstcoord[1] = 0; /* increment pointers to next elements to be read */ arrayptr = arrayptr + nread * bytesperpixel; if (nullarrayptr && (nullcheck == 2) ) nullarrayptr = nullarrayptr + nread; } } else { ffpmsg("only 1D, 2D, or 3D images are currently supported"); return(*status = DATA_DECOMPRESSION_ERR); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_read_compressed_img_plane(fitsfile *fptr, /* I - FITS file */ int datatype, /* I - datatype of the array to be returned */ int bytesperpixel, /* I - number of bytes per pixel in array */ long nplane, /* I - which plane of the cube to read */ LONGLONG *firstcoord, /* coordinate of first pixel to read */ LONGLONG *lastcoord, /* coordinate of last pixel to read */ long *inc, /* increment of pixels to read */ long *naxes, /* size of each image dimension */ int nullcheck, /* I - 0 for no null checking */ /* 1: set undefined pixels = nullval */ /* 2: set nullarray=1 for undefined pixels */ void *nullval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ char *nullarray, /* O - array of flags = 1 if nullcheck = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ long *nread, /* O - total number of pixels read and returned*/ int *status) /* IO - error status */ /* in general we have to read the first partial row of the image, followed by the middle complete rows, followed by the last partial row of the image. If the first or last rows are complete, then read them at the same time as all the middle rows. */ { /* bottom left coord. and top right coord. */ LONGLONG blc[MAX_COMPRESS_DIM], trc[MAX_COMPRESS_DIM]; char *arrayptr, *nullarrayptr; int tnull; if (anynul) *anynul = 0; *nread = 0; arrayptr = (char *) array; nullarrayptr = nullarray; blc[2] = nplane + 1; trc[2] = nplane + 1; if (firstcoord[0] != 0) { /* have to read a partial first row */ blc[0] = firstcoord[0] + 1; blc[1] = firstcoord[1] + 1; trc[1] = blc[1]; if (lastcoord[1] == firstcoord[1]) trc[0] = lastcoord[0] + 1; /* 1st and last pixels in same row */ else trc[0] = naxes[0]; /* read entire rest of the row */ fits_read_compressed_img(fptr, datatype, blc, trc, inc, nullcheck, nullval, arrayptr, nullarrayptr, &tnull, status); *nread = *nread + (long) (trc[0] - blc[0] + 1); if (tnull && anynul) *anynul = 1; /* there are null pixels */ if (lastcoord[1] == firstcoord[1]) { return(*status); /* finished */ } /* set starting coord to beginning of next line */ firstcoord[0] = 0; firstcoord[1] += 1; arrayptr = arrayptr + (trc[0] - blc[0] + 1) * bytesperpixel; if (nullarrayptr && (nullcheck == 2) ) nullarrayptr = nullarrayptr + (trc[0] - blc[0] + 1); } /* read contiguous complete rows of the image, if any */ blc[0] = 1; blc[1] = firstcoord[1] + 1; trc[0] = naxes[0]; if (lastcoord[0] + 1 == naxes[0]) { /* can read the last complete row, too */ trc[1] = lastcoord[1] + 1; } else { /* last row is incomplete; have to read it separately */ trc[1] = lastcoord[1]; } if (trc[1] >= blc[1]) /* must have at least one whole line to read */ { fits_read_compressed_img(fptr, datatype, blc, trc, inc, nullcheck, nullval, arrayptr, nullarrayptr, &tnull, status); *nread = *nread + (long) ((trc[1] - blc[1] + 1) * naxes[0]); if (tnull && anynul) *anynul = 1; if (lastcoord[1] + 1 == trc[1]) return(*status); /* finished */ /* increment pointers for the last partial row */ arrayptr = arrayptr + (trc[1] - blc[1] + 1) * naxes[0] * bytesperpixel; if (nullarrayptr && (nullcheck == 2) ) nullarrayptr = nullarrayptr + (trc[1] - blc[1] + 1) * naxes[0]; } if (trc[1] == lastcoord[1] + 1) return(*status); /* all done */ /* set starting and ending coord to last line */ trc[0] = lastcoord[0] + 1; trc[1] = lastcoord[1] + 1; blc[1] = trc[1]; fits_read_compressed_img(fptr, datatype, blc, trc, inc, nullcheck, nullval, arrayptr, nullarrayptr, &tnull, status); if (tnull && anynul) *anynul = 1; *nread = *nread + (long) (trc[0] - blc[0] + 1); return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_get_compressed_image_par(fitsfile *infptr, int *status) /* This routine reads keywords from a BINTABLE extension containing a compressed image. */ { char keyword[FLEN_KEYWORD]; char value[FLEN_VALUE]; int ii, tstatus; long expect_nrows, maxtilelen; if (*status > 0) return(*status); /* Copy relevant header keyword values to structure */ if (ffgky (infptr, TSTRING, "ZCMPTYPE", value, NULL, status) > 0) { ffpmsg("required ZCMPTYPE compression keyword not found in"); ffpmsg(" imcomp_get_compressed_image_par"); return(*status); } (infptr->Fptr)->zcmptype[0] = '\0'; strncat((infptr->Fptr)->zcmptype, value, 11); if (!FSTRCMP(value, "RICE_1") ) (infptr->Fptr)->compress_type = RICE_1; else if (!FSTRCMP(value, "HCOMPRESS_1") ) (infptr->Fptr)->compress_type = HCOMPRESS_1; else if (!FSTRCMP(value, "GZIP_1") ) (infptr->Fptr)->compress_type = GZIP_1; else if (!FSTRCMP(value, "PLIO_1") ) (infptr->Fptr)->compress_type = PLIO_1; else { ffpmsg("Unknown image compression type:"); ffpmsg(value); return (*status = DATA_DECOMPRESSION_ERR); } if (ffgky (infptr, TINT, "ZBITPIX", &(infptr->Fptr)->zbitpix, NULL, status) > 0) { ffpmsg("required ZBITPIX compression keyword not found"); return(*status); } if (ffgky (infptr,TINT, "ZNAXIS", &(infptr->Fptr)->zndim, NULL, status) > 0) { ffpmsg("required ZNAXIS compression keyword not found"); return(*status); } if ((infptr->Fptr)->zndim < 1) { ffpmsg("Compressed image has no data (ZNAXIS < 1)"); return (*status = BAD_NAXIS); } if ((infptr->Fptr)->zndim > MAX_COMPRESS_DIM) { ffpmsg("Compressed image has too many dimensions"); return(*status = BAD_NAXIS); } expect_nrows = 1; maxtilelen = 1; for (ii = 0; ii < (infptr->Fptr)->zndim; ii++) { /* get image size */ sprintf (keyword, "ZNAXIS%d", ii+1); ffgky (infptr, TLONG,keyword, &(infptr->Fptr)->znaxis[ii],NULL,status); if (*status > 0) { ffpmsg("required ZNAXISn compression keyword not found"); return(*status); } /* get compression tile size */ sprintf (keyword, "ZTILE%d", ii+1); /* set default tile size in case keywords are not present */ if (ii == 0) (infptr->Fptr)->tilesize[0] = (infptr->Fptr)->znaxis[0]; else (infptr->Fptr)->tilesize[ii] = 1; tstatus = 0; ffgky (infptr, TLONG, keyword, &(infptr->Fptr)->tilesize[ii], NULL, &tstatus); expect_nrows *= (((infptr->Fptr)->znaxis[ii] - 1) / (infptr->Fptr)->tilesize[ii]+ 1); maxtilelen *= (infptr->Fptr)->tilesize[ii]; } /* check number of rows */ if (expect_nrows != (infptr->Fptr)->numrows) { ffpmsg( "number of table rows != the number of tiles in compressed image"); return (*status = DATA_DECOMPRESSION_ERR); } /* read any algorithm specific parameters */ if ((infptr->Fptr)->compress_type == RICE_1 ) { if (ffgky(infptr, TINT,"ZVAL1", &(infptr->Fptr)->rice_blocksize, NULL, status) > 0) { ffpmsg("required ZVAL1 compression keyword not found"); return(*status); } if ((infptr->Fptr)->zbitpix < 0) { /* try to read the floating point quantization parameter */ tstatus = 0; ffgky(infptr, TINT,"ZVAL2", &(infptr->Fptr)->noise_nbits, NULL, &tstatus); } } else if ((infptr->Fptr)->compress_type == HCOMPRESS_1 ) { if (ffgky(infptr, TINT,"ZVAL1", &(infptr->Fptr)->hcomp_scale, NULL, status) > 0) { ffpmsg("required ZVAL1 compression keyword not found"); return(*status); } tstatus = 0; ffgky(infptr, TINT,"ZVAL2", &(infptr->Fptr)->hcomp_smooth, NULL, &tstatus); if ((infptr->Fptr)->zbitpix < 0) { /* try to read the floating point quantization parameter */ tstatus = 0; ffgky(infptr, TINT,"ZVAL3", &(infptr->Fptr)->noise_nbits, NULL, &tstatus); } } else { if ((infptr->Fptr)->zbitpix < 0) { /* try to read the floating point quantization parameter */ tstatus = 0; ffgky(infptr, TINT,"ZVAL1", &(infptr->Fptr)->noise_nbits, NULL, &tstatus); } } /* store number of pixels in each compression tile, */ /* and max size of the compressed tile buffer */ (infptr->Fptr)->maxtilelen = maxtilelen; (infptr->Fptr)->maxelem = imcomp_calc_max_elem ((infptr->Fptr)->compress_type, maxtilelen, (infptr->Fptr)->zbitpix, (infptr->Fptr)->rice_blocksize); /* Get Column numbers. */ if (ffgcno(infptr, CASEINSEN, "COMPRESSED_DATA", &(infptr->Fptr)->cn_compressed, status) > 0) { ffpmsg("couldn't find COMPRESSED_DATA column (fits_get_compressed_img_par)"); return(*status = DATA_DECOMPRESSION_ERR); } ffpmrk(); /* put mark on message stack; erase any messages after this */ tstatus = 0; ffgcno(infptr,CASEINSEN, "UNCOMPRESSED_DATA", &(infptr->Fptr)->cn_uncompressed, &tstatus); tstatus = 0; if (ffgcno(infptr, CASEINSEN, "ZSCALE", &(infptr->Fptr)->cn_zscale, &tstatus) > 0) { /* CMPSCALE column doesn't exist; see if there is a keyword */ tstatus = 0; if (ffgky(infptr, TDOUBLE, "ZSCALE", &(infptr->Fptr)->zscale, NULL, &tstatus) <= 0) (infptr->Fptr)->cn_zscale = -1; /* flag for a constant ZSCALE */ } tstatus = 0; if (ffgcno(infptr, CASEINSEN, "ZZERO", &(infptr->Fptr)->cn_zzero, &tstatus) > 0) { /* CMPZERO column doesn't exist; see if there is a keyword */ tstatus = 0; if (ffgky(infptr, TDOUBLE, "ZZERO", &(infptr->Fptr)->zzero, NULL, &tstatus) <= 0) (infptr->Fptr)->cn_zzero = -1; /* flag for a constant ZZERO */ } tstatus = 0; if (ffgcno(infptr, CASEINSEN, "ZBLANK", &(infptr->Fptr)->cn_zblank, &tstatus) > 0) { /* CMPZERO column doesn't exist; see if there is a keyword */ tstatus = 0; if (ffgky(infptr, TINT, "ZBLANK", &(infptr->Fptr)->zblank, NULL, &tstatus) <= 0) (infptr->Fptr)->cn_zblank = -1; /* flag for a constant ZBLANK */ } /* read the conventional BSCALE and BZERO scaling keywords, if present */ tstatus = 0; if (ffgky (infptr, TDOUBLE, "BSCALE", &(infptr->Fptr)->cn_bscale, NULL, &tstatus) > 0) { (infptr->Fptr)->cn_bscale = 1.0; } tstatus = 0; if (ffgky (infptr, TDOUBLE, "BZERO", &(infptr->Fptr)->cn_bzero, NULL, &tstatus) > 0) { (infptr->Fptr)->cn_bzero = 0.0; } ffcmrk(); /* clear any spurious error messages, back to the mark */ return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_copy_imheader(fitsfile *infptr, fitsfile *outfptr, int *status) /* This routine reads the header keywords from the input image and copies them to the output image; the manditory structural keywords and the checksum keywords are not copied. If the DATE keyword is copied, then it is updated with the current date and time. */ { int nkeys, ii, keyclass; char card[FLEN_CARD]; /* a header record */ if (*status > 0) return(*status); ffghsp(infptr, &nkeys, NULL, status); /* get number of keywords in image */ for (ii = 5; ii <= nkeys; ii++) /* skip the first 4 keywords */ { ffgrec(infptr, ii, card, status); keyclass = ffgkcl(card); /* Get the type/class of keyword */ /* don't copy structural keywords or checksum keywords */ if ((keyclass <= TYP_CMPRS_KEY) || (keyclass == TYP_CKSUM_KEY)) continue; if (FSTRNCMP(card, "DATE ", 5) == 0) /* write current date */ { ffpdat(outfptr, status); } else if (FSTRNCMP(card, "EXTNAME ", 8) == 0) { /* don't copy default EXTNAME keyword from a compressed image */ if (FSTRNCMP(card, "EXTNAME = 'COMPRESSED_IMAGE'", 28)) { /* if EXTNAME keyword already exists, overwrite it */ /* otherwise append a new EXTNAME keyword */ ffucrd(outfptr, "EXTNAME", card, status); } } else { /* just copy the keyword to the output header */ ffprec (outfptr, card, status); } if (*status > 0) return (*status); } return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_copy_img2comp(fitsfile *infptr, fitsfile *outfptr, int *status) /* This routine copies the header keywords from the uncompressed input image and to the compressed image (in a binary table) */ { char card[FLEN_CARD]; /* a header record */ /* tile compressed image keyword translation table */ /* INPUT OUTPUT */ /* 01234567 01234567 */ char *patterns[][2] = {{"SIMPLE", "ZSIMPLE" }, {"XTENSION", "ZTENSION" }, {"BITPIX", "ZBITPIX" }, {"NAXIS", "ZNAXIS" }, {"NAXISm", "ZNAXISm" }, {"EXTEND", "ZEXTEND" }, {"BLOCKED", "ZBLOCKED"}, {"PCOUNT", "ZPCOUNT" }, {"GCOUNT", "ZGCOUNT" }, {"CHECKSUM","ZHECKSUM"}, /* save original checksums */ {"DATASUM", "ZDATASUM"}, {"*", "+" }}; /* copy all other keywords */ int npat; if (*status > 0) return(*status); /* write a default EXTNAME keyword if it doesn't exist in input file*/ fits_read_card(infptr, "EXTNAME", card, status); if (*status) { *status = 0; strcpy(card, "EXTNAME = 'COMPRESSED_IMAGE'"); fits_write_record(outfptr, card, status); } /* copy all the keywords from the input file to the output */ npat = sizeof(patterns)/sizeof(patterns[0][0])/2; fits_translate_keywords(infptr, outfptr, 1, patterns, npat, 0, 0, 0, status); if (*status > 0) return (*status); return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_copy_comp2img(fitsfile *infptr, fitsfile *outfptr, int norec, int *status) /* This routine copies the header keywords from the compressed input image and to the uncompressed image (in a binary table) */ { char card[FLEN_CARD]; /* a header record */ char *patterns[40][2]; char negative[] = "-"; int ii, npat, nreq, nsp; /* tile compressed image keyword translation table */ /* INPUT OUTPUT */ /* 01234567 01234567 */ /* only translate these if required keywords not already written */ char *reqkeys[][2] = { {"ZSIMPLE", "SIMPLE" }, {"ZTENSION", "XTENSION"}, {"ZBITPIX", "BITPIX" }, {"ZNAXIS", "NAXIS" }, {"ZNAXISm", "NAXISm" }, {"ZEXTEND", "EXTEND" }, {"ZBLOCKED", "BLOCKED"}, {"ZPCOUNT", "PCOUNT" }, {"ZGCOUNT", "GCOUNT" }, {"ZHECKSUM", "CHECKSUM"}, /* restore original checksums */ {"ZDATASUM", "DATASUM"}}; /* other special keywords */ char *spkeys[][2] = { {"XTENSION", "-" }, {"BITPIX", "-" }, {"NAXIS", "-" }, {"NAXISm", "-" }, {"PCOUNT", "-" }, {"GCOUNT", "-" }, {"TFIELDS", "-" }, {"TTYPEm", "-" }, {"TFORMm", "-" }, {"ZIMAGE", "-" }, {"ZTILEm", "-" }, {"ZCMPTYPE", "-" }, {"ZNAMEm", "-" }, {"ZVALm", "-" }, {"CHECKSUM","-" }, /* delete checksums */ {"DATASUM", "-" }, {"EXTNAME", "+" }, /* we may change this, below */ {"*", "+" }}; if (*status > 0) return(*status); nreq = sizeof(reqkeys)/sizeof(reqkeys[0][0])/2; nsp = sizeof(spkeys)/sizeof(spkeys[0][0])/2; /* construct translation patterns */ for (ii = 0; ii < nreq; ii++) { patterns[ii][0] = reqkeys[ii][0]; if (norec) patterns[ii][1] = negative; else patterns[ii][1] = reqkeys[ii][1]; } for (ii = 0; ii < nsp; ii++) { patterns[ii+nreq][0] = spkeys[ii][0]; patterns[ii+nreq][1] = spkeys[ii][1]; } npat = nreq + nsp; /* see if the EXTNAME keyword should be copied or not */ fits_read_card(infptr, "EXTNAME", card, status); if (!strncmp(card, "EXTNAME = 'COMPRESSED_IMAGE'", 28)) patterns[npat-2][1] = negative; /* translate and copy the keywords from the input file to the output */ fits_translate_keywords(infptr, outfptr, 1, patterns, npat, 0, 0, 0, status); if (*status > 0) return (*status); return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_decompress_tile (fitsfile *infptr, int nrow, /* I - row of table to read and uncompress */ int tilelen, /* I - number of pixels in the tile */ int datatype, /* I - datatype to be returned in 'buffer' */ int nullcheck, /* I - 0 for no null checking */ void *nulval, /* I - value to be used for undefined pixels */ void *buffer, /* O - buffer for returned decompressed values */ char *bnullarray, /* O - buffer for returned null flags */ int *anynul, /* O - any null values returned? */ int *status) /* This routine decompresses one tile of the image */ { int *idata = 0; /* uncompressed integer data */ LONGLONG *lldata; size_t idatalen, tilebytesize; int ii, tnull; /* value in the data which represents nulls */ unsigned char *cbuf = 0; /* compressed data */ unsigned char charnull = 0; short *sbuf = 0; short snull = 0; int blocksize; double bscale, bzero, dummy = 0; /* scaling parameters */ long nelem = 0, offset = 0; /* number of bytes */ int smooth, nx, ny, scale; /* hcompress parameters */ if (*status > 0) return(*status); /* get length of the compressed byte stream */ ffgdes (infptr, (infptr->Fptr)->cn_compressed, nrow, &nelem, &offset, status); /* EOF error here indicates that this tile has not yet been written */ if (*status == END_OF_FILE) return(*status = NO_COMPRESSED_TILE); /* **************************************************************** */ if (nelem == 0) /* tile was not compressed; read uncompressed data */ { if ((infptr->Fptr)->cn_uncompressed < 1 ) { return (*status = NO_COMPRESSED_TILE); } /* no compressed data, so simply read the uncompressed data */ /* directly from the UNCOMPRESSED_DATA column, then return */ ffgdes (infptr, (infptr->Fptr)->cn_uncompressed, nrow, &nelem, &offset, status); if (nelem == 0 && offset == 0) return (*status = NO_COMPRESSED_TILE); if (nullcheck <= 1) fits_read_col(infptr, datatype, (infptr->Fptr)->cn_uncompressed, nrow, 1, nelem, nulval, buffer, anynul, status); else fits_read_colnull(infptr, datatype, (infptr->Fptr)->cn_uncompressed, nrow, 1, nelem, buffer, bnullarray, anynul, status); return(*status); } /* **************************************************************** */ if (nullcheck == 2) { for (ii = 0; ii < tilelen; ii++) /* initialize the null array */ bnullarray[ii] = 0; } if (anynul) *anynul = 0; /* get linear scaling and offset values, if they exist */ if ((infptr->Fptr)->cn_zscale == 0) { /* set default scaling, if scaling is not defined */ bscale = 1.; bzero = 0.; } else if ((infptr->Fptr)->cn_zscale == -1) { bscale = (infptr->Fptr)->zscale; bzero = (infptr->Fptr)->zzero; } else { /* read the linear scale and offset values for this row */ ffgcvd (infptr, (infptr->Fptr)->cn_zscale, nrow, 1, 1, 0., &bscale, NULL, status); ffgcvd (infptr, (infptr->Fptr)->cn_zzero, nrow, 1, 1, 0., &bzero, NULL, status); if (*status > 0) { ffpmsg("error reading scaling factor and offset for compressed tile"); free(idata); free (cbuf); return (*status); } } if (bscale == 1.0 && bzero == 0.0 ) { /* if no other scaling has been specified, try using the values given by the BSCALE and BZERO keywords, if any */ bscale = (infptr->Fptr)->cn_bscale; bzero = (infptr->Fptr)->cn_bzero; } /* ************************************************************* */ /* get the value used to represent nulls in the int array */ if ((infptr->Fptr)->cn_zblank == 0) { nullcheck = 0; /* no null value; don't check for nulls */ } else if ((infptr->Fptr)->cn_zblank == -1) { tnull = (infptr->Fptr)->zblank; /* use the the ZBLANK keyword */ } else { /* read the null value for this row */ ffgcvk (infptr, (infptr->Fptr)->cn_zblank, nrow, 1, 1, 0, &tnull, NULL, status); if (*status > 0) { ffpmsg("error reading null value for compressed tile"); free(idata); free (cbuf); return (*status); } } /* ************************************************************* */ /* allocate memory for uncompressed integers */ if ((infptr->Fptr)->compress_type == HCOMPRESS_1 && ((infptr->Fptr)->zbitpix != BYTE_IMG && (infptr->Fptr)->zbitpix != SHORT_IMG) ) { /* must allocate 8 bytes per pixel of scratch space */ lldata = (LONGLONG*) calloc (tilelen, sizeof (LONGLONG)); idata = (int *) lldata; } else { idata = (int*) calloc (tilelen, sizeof (int)); } if (idata == NULL) { ffpmsg("Out of memory for idata. (imcomp_decompress_tile)"); return (*status = MEMORY_ALLOCATION); } /* ************************************************************* */ if ((infptr->Fptr)->compress_type == RICE_1) { cbuf = (unsigned char *) calloc (nelem, sizeof (unsigned char)); if (cbuf == NULL) { ffpmsg("Out of memory for cbuf. (imcomp_decompress_tile)"); free(idata); return (*status = MEMORY_ALLOCATION); } /* read array of compressed bytes */ if (fits_read_col(infptr, TBYTE, (infptr->Fptr)->cn_compressed, nrow, 1, nelem, &charnull, cbuf, NULL, status) > 0) { ffpmsg("error reading compressed byte stream from binary table"); free (cbuf); free(idata); return (*status); } /* uncompress the data */ blocksize = (infptr->Fptr)->rice_blocksize; if ((*status = fits_rdecomp (cbuf, nelem, (unsigned int *)idata, tilelen, blocksize))) { free (cbuf); free(idata); return (*status); } free(cbuf); } /* ************************************************************* */ else if ((infptr->Fptr)->compress_type == HCOMPRESS_1) { cbuf = (unsigned char *) calloc (nelem, sizeof (unsigned char)); if (cbuf == NULL) { ffpmsg("Out of memory for cbuf. (imcomp_decompress_tile)"); free(idata); return (*status = MEMORY_ALLOCATION); } /* read array of compressed bytes */ if (fits_read_col(infptr, TBYTE, (infptr->Fptr)->cn_compressed, nrow, 1, nelem, &charnull, cbuf, NULL, status) > 0) { ffpmsg("error reading compressed byte stream from binary table"); free (cbuf); free(idata); return (*status); } /* uncompress the data */ smooth = (infptr->Fptr)->hcomp_smooth; if ( ((infptr->Fptr)->zbitpix == BYTE_IMG || (infptr->Fptr)->zbitpix == SHORT_IMG) ) { if ((*status = fits_hdecompress(cbuf, smooth, idata, &nx, &ny, &scale, status))) { free (cbuf); free(idata); return (*status); } } else { /* idata must have been allocated twice as large for this to work */ if ((*status = fits_hdecompress64(cbuf, smooth, lldata, &nx, &ny, &scale, status))) { free (cbuf); free(idata); return (*status); } } free(cbuf); } /* ************************************************************* */ else if ((infptr->Fptr)->compress_type == PLIO_1) { sbuf = (short *) calloc (nelem, sizeof (short)); if (sbuf == NULL) { ffpmsg("Out of memory for sbuf. (imcomp_decompress_tile)"); free(idata); return (*status = MEMORY_ALLOCATION); } /* read array of compressed bytes */ if (fits_read_col(infptr, TSHORT, (infptr->Fptr)->cn_compressed, nrow, 1, nelem, &snull, sbuf, NULL, status) > 0) { ffpmsg("error reading compressed byte stream from binary table"); free(idata); free (sbuf); return (*status); } pl_l2pi (sbuf, 1, idata, tilelen); /* uncompress the data */ free(sbuf); } /* ************************************************************* */ else if ((infptr->Fptr)->compress_type == GZIP_1) { cbuf = (unsigned char *) calloc (nelem, sizeof (unsigned char)); if (cbuf == NULL) { ffpmsg("Out of memory for cbuf. (imcomp_decompress_tile)"); free(idata); return (*status = MEMORY_ALLOCATION); } /* read array of compressed bytes */ if (fits_read_col(infptr, TBYTE, (infptr->Fptr)->cn_compressed, nrow, 1, nelem, &charnull, cbuf, NULL, status) > 0) { ffpmsg("error reading compressed byte stream from binary table"); free(idata); free (cbuf); return (*status); } /* uncompress the data */ idatalen = tilelen * sizeof(int); if (uncompress2mem_from_mem ((char *)cbuf, nelem, (char **) &idata, &idatalen, realloc, &tilebytesize, status)) { ffpmsg("uncompress2mem_from_mem returned with an error"); free(idata); free (cbuf); return (*status); } #if BYTESWAPPED ffswap4(idata, tilelen); /* reverse order of bytes */ #endif if (idatalen != tilebytesize) { ffpmsg("error: uncompressed tile has wrong size"); free(idata); free (cbuf); return (*status = DATA_DECOMPRESSION_ERR); } free(cbuf); } /* ************************************************************* */ else { ffpmsg("unknown compression algorithm"); free(idata); return (*status = DATA_DECOMPRESSION_ERR); } /* ************************************************************* */ /* copy the uncompressed tile data to the output buffer, doing */ /* null checking, datatype conversion and linear scaling, if necessary */ if (nulval == 0) nulval = &dummy; /* set address to dummy value */ if (datatype == TSHORT) { fffi4i2(idata, tilelen, bscale, bzero, nullcheck, tnull, *(short *) nulval, bnullarray, anynul, (short *) buffer, status); } else if (datatype == TINT) { fffi4int(idata, (long) tilelen, bscale, bzero, nullcheck, tnull, *(int *) nulval, bnullarray, anynul, (int *) buffer, status); } else if (datatype == TLONG) { fffi4i4(idata, tilelen, bscale, bzero, nullcheck, tnull, *(long *) nulval, bnullarray, anynul, (long *) buffer, status); } else if (datatype == TFLOAT) { fffi4r4(idata, tilelen, bscale, bzero, nullcheck, tnull, *(float *) nulval, bnullarray, anynul, (float *) buffer, status); } else if (datatype == TDOUBLE) { fffi4r8(idata, tilelen, bscale, bzero, nullcheck, tnull, *(double *) nulval, bnullarray, anynul, (double *) buffer, status); } else if (datatype == TBYTE) { fffi4i1(idata, tilelen, bscale, bzero, nullcheck, tnull, *(unsigned char *) nulval, bnullarray, anynul, (unsigned char *) buffer, status); } else if (datatype == TSBYTE) { fffi4s1(idata, tilelen, bscale, bzero, nullcheck, tnull, *(signed char *) nulval, bnullarray, anynul, (signed char *) buffer, status); } else if (datatype == TUSHORT) { fffi4u2(idata, tilelen, bscale, bzero, nullcheck, tnull, *(unsigned short *) nulval, bnullarray, anynul, (unsigned short *) buffer, status); } else if (datatype == TUINT) { fffi4uint(idata, tilelen, bscale, bzero, nullcheck, tnull, *(unsigned int *) nulval, bnullarray, anynul, (unsigned int *) buffer, status); } else if (datatype == TULONG) { fffi4u4(idata, tilelen, bscale, bzero, nullcheck, tnull, *(unsigned long *) nulval, bnullarray, anynul, (unsigned long *) buffer, status); } else *status = BAD_DATATYPE; free(idata); return (*status); } /*--------------------------------------------------------------------------*/ int imcomp_copy_overlap ( char *tile, /* I - multi dimensional array of tile pixels */ int pixlen, /* I - number of bytes in each tile or image pixel */ int ndim, /* I - number of dimension in the tile and image */ long *tfpixel, /* I - first pixel number in each dim. of the tile */ long *tlpixel, /* I - last pixel number in each dim. of the tile */ char *bnullarray, /* I - array of null flags; used if nullcheck = 2 */ char *image, /* O - multi dimensional output image */ long *fpixel, /* I - first pixel number in each dim. of the image */ long *lpixel, /* I - last pixel number in each dim. of the image */ long *ininc, /* I - increment to be applied in each image dimen. */ int nullcheck, /* I - 0, 1: do nothing; 2: set nullarray for nulls */ char *nullarray, int *status) /* copy the intersecting pixels from a decompressed tile to the output image. Both the tile and the image must have the same number of dimensions. */ { long imgdim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* output image, allowing for inc factor */ long tiledim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* tile, array; inc factor is not relevant */ long imgfpix[MAX_COMPRESS_DIM]; /* 1st img pix overlapping tile: 0 base, */ /* allowing for inc factor */ long imglpix[MAX_COMPRESS_DIM]; /* last img pix overlapping tile 0 base, */ /* allowing for inc factor */ long tilefpix[MAX_COMPRESS_DIM]; /* 1st tile pix overlapping img 0 base, */ /* allowing for inc factor */ long inc[MAX_COMPRESS_DIM]; /* local copy of input ininc */ long i1, i2, i3, i4; /* offset along each axis of the image */ long it1, it2, it3, it4; long im1, im2, im3, im4; /* offset to image pixel, allowing for inc */ long ipos, tf, tl; long t2, t3, t4; /* offset along each axis of the tile */ long tilepix, imgpix, tilepixbyte, imgpixbyte; int ii, overlap_bytes, overlap_flags; if (*status > 0) return(*status); for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { /* set default values for higher dimensions */ inc[ii] = 1; imgdim[ii] = 1; tiledim[ii] = 1; imgfpix[ii] = 0; imglpix[ii] = 0; tilefpix[ii] = 0; } /* ------------------------------------------------------------ */ /* calc amount of overlap in each dimension; if there is zero */ /* overlap in any dimension then just return */ /* ------------------------------------------------------------ */ for (ii = 0; ii < ndim; ii++) { if (tlpixel[ii] < fpixel[ii] || tfpixel[ii] > lpixel[ii]) return(*status); /* there are no overlapping pixels */ inc[ii] = ininc[ii]; /* calc dimensions of the output image section */ imgdim[ii] = (lpixel[ii] - fpixel[ii]) / labs(inc[ii]) + 1; if (imgdim[ii] < 1) return(*status = NEG_AXIS); /* calc dimensions of the tile */ tiledim[ii] = tlpixel[ii] - tfpixel[ii] + 1; if (tiledim[ii] < 1) return(*status = NEG_AXIS); if (ii > 0) tiledim[ii] *= tiledim[ii - 1]; /* product of dimensions */ /* first and last pixels in image that overlap with the tile, 0 base */ tf = tfpixel[ii] - 1; tl = tlpixel[ii] - 1; /* skip this plane if it falls in the cracks of the subsampled image */ while ((tf-(fpixel[ii] - 1)) % labs(inc[ii])) { tf++; if (tf > tl) return(*status); /* no overlapping pixels */ } while ((tl-(fpixel[ii] - 1)) % labs(inc[ii])) { tl--; if (tf > tl) return(*status); /* no overlapping pixels */ } imgfpix[ii] = maxvalue((tf - fpixel[ii] +1) / labs(inc[ii]) , 0); imglpix[ii] = minvalue((tl - fpixel[ii] +1) / labs(inc[ii]) , imgdim[ii] - 1); /* first pixel in the tile that overlaps with the image (0 base) */ tilefpix[ii] = maxvalue(fpixel[ii] - tfpixel[ii], 0); while ((tfpixel[ii] + tilefpix[ii] - fpixel[ii]) % labs(inc[ii])) { (tilefpix[ii])++; if (tilefpix[ii] >= tiledim[ii]) return(*status); /* no overlapping pixels */ } /* printf("ii tfpixel, tlpixel %d %d %d \n",ii, tfpixel[ii], tlpixel[ii]); printf("ii, tf, tl, imgfpix,imglpix, tilefpix %d %d %d %d %d %d\n",ii, tf,tl,imgfpix[ii], imglpix[ii],tilefpix[ii]); */ if (ii > 0) imgdim[ii] *= imgdim[ii - 1]; /* product of dimensions */ } /* ---------------------------------------------------------------- */ /* calc number of pixels in each row (first dimension) that overlap */ /* multiply by pixlen to get number of bytes to copy in each loop */ /* ---------------------------------------------------------------- */ if (inc[0] != 1) overlap_flags = 1; /* can only copy 1 pixel at a time */ else overlap_flags = imglpix[0] - imgfpix[0] + 1; /* can copy whole row */ overlap_bytes = overlap_flags * pixlen; /* support up to 5 dimensions for now */ for (i4 = 0, it4=0; i4 <= imglpix[4] - imgfpix[4]; i4++, it4++) { /* increment plane if it falls in the cracks of the subsampled image */ while (ndim > 4 && (tfpixel[4] + tilefpix[4] - fpixel[4] + it4) % labs(inc[4]) != 0) it4++; /* offset to start of hypercube */ if (inc[4] > 0) im4 = (i4 + imgfpix[4]) * imgdim[3]; else im4 = imgdim[4] - (i4 + 1 + imgfpix[4]) * imgdim[3]; t4 = (tilefpix[4] + it4) * tiledim[3]; for (i3 = 0, it3=0; i3 <= imglpix[3] - imgfpix[3]; i3++, it3++) { /* increment plane if it falls in the cracks of the subsampled image */ while (ndim > 3 && (tfpixel[3] + tilefpix[3] - fpixel[3] + it3) % labs(inc[3]) != 0) it3++; /* offset to start of cube */ if (inc[3] > 0) im3 = (i3 + imgfpix[3]) * imgdim[2] + im4; else im3 = imgdim[3] - (i3 + 1 + imgfpix[3]) * imgdim[2] + im4; t3 = (tilefpix[3] + it3) * tiledim[2] + t4; /* loop through planes of the image */ for (i2 = 0, it2=0; i2 <= imglpix[2] - imgfpix[2]; i2++, it2++) { /* incre plane if it falls in the cracks of the subsampled image */ while (ndim > 2 && (tfpixel[2] + tilefpix[2] - fpixel[2] + it2) % labs(inc[2]) != 0) it2++; /* offset to start of plane */ if (inc[2] > 0) im2 = (i2 + imgfpix[2]) * imgdim[1] + im3; else im2 = imgdim[2] - (i2 + 1 + imgfpix[2]) * imgdim[1] + im3; t2 = (tilefpix[2] + it2) * tiledim[1] + t3; /* loop through rows of the image */ for (i1 = 0, it1=0; i1 <= imglpix[1] - imgfpix[1]; i1++, it1++) { /* incre row if it falls in the cracks of the subsampled image */ while (ndim > 1 && (tfpixel[1] + tilefpix[1] - fpixel[1] + it1) % labs(inc[1]) != 0) it1++; /* calc position of first pixel in tile to be copied */ tilepix = tilefpix[0] + (tilefpix[1] + it1) * tiledim[0] + t2; /* offset to start of row */ if (inc[1] > 0) im1 = (i1 + imgfpix[1]) * imgdim[0] + im2; else im1 = imgdim[1] - (i1 + 1 + imgfpix[1]) * imgdim[0] + im2; /* printf("inc = %d %d %d %d\n",inc[0],inc[1],inc[2],inc[3]); printf("im1,im2,im3,im4 = %d %d %d %d\n",im1,im2,im3,im4); */ /* offset to byte within the row */ if (inc[0] > 0) imgpix = imgfpix[0] + im1; else imgpix = imgdim[0] - 1 - imgfpix[0] + im1; /* printf("tilefpix0,1, imgfpix1, it1, inc1, t2= %d %d %d %d %d %d\n", tilefpix[0],tilefpix[1],imgfpix[1],it1,inc[1], t2); printf("i1, it1, tilepix, imgpix %d %d %d %d \n", i1, it1, tilepix, imgpix); */ /* loop over pixels along one row of the image */ for (ipos = imgfpix[0]; ipos <= imglpix[0]; ipos += overlap_flags) { if (nullcheck == 2) { /* copy overlapping null flags from tile to image */ memcpy(nullarray + imgpix, bnullarray + tilepix, overlap_flags); } /* convert from image pixel to byte offset */ tilepixbyte = tilepix * pixlen; imgpixbyte = imgpix * pixlen; /* printf(" tilepix, tilepixbyte, imgpix, imgpixbyte= %d %d %d %d\n", tilepix, tilepixbyte, imgpix, imgpixbyte); */ /* copy overlapping row of pixels from tile to image */ memcpy(image + imgpixbyte, tile + tilepixbyte, overlap_bytes); tilepix += (overlap_flags * labs(inc[0])); if (inc[0] > 0) imgpix += overlap_flags; else imgpix -= overlap_flags; } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int imcomp_merge_overlap ( char *tile, /* O - multi dimensional array of tile pixels */ int pixlen, /* I - number of bytes in each tile or image pixel */ int ndim, /* I - number of dimension in the tile and image */ long *tfpixel, /* I - first pixel number in each dim. of the tile */ long *tlpixel, /* I - last pixel number in each dim. of the tile */ char *bnullarray, /* I - array of null flags; used if nullcheck = 2 */ char *image, /* I - multi dimensional output image */ long *fpixel, /* I - first pixel number in each dim. of the image */ long *lpixel, /* I - last pixel number in each dim. of the image */ int nullcheck, /* I - 0, 1: do nothing; 2: set nullarray for nulls */ int *status) /* Similar to imcomp_copy_overlap, except it copies the overlapping pixels from the 'image' to the 'tile'. */ { long imgdim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* output image, allowing for inc factor */ long tiledim[MAX_COMPRESS_DIM]; /* product of preceding dimensions in the */ /* tile, array; inc factor is not relevant */ long imgfpix[MAX_COMPRESS_DIM]; /* 1st img pix overlapping tile: 0 base, */ /* allowing for inc factor */ long imglpix[MAX_COMPRESS_DIM]; /* last img pix overlapping tile 0 base, */ /* allowing for inc factor */ long tilefpix[MAX_COMPRESS_DIM]; /* 1st tile pix overlapping img 0 base, */ /* allowing for inc factor */ long inc[MAX_COMPRESS_DIM]; /* local copy of input ininc */ long i1, i2, i3, i4; /* offset along each axis of the image */ long it1, it2, it3, it4; long im1, im2, im3, im4; /* offset to image pixel, allowing for inc */ long ipos, tf, tl; long t2, t3, t4; /* offset along each axis of the tile */ long tilepix, imgpix, tilepixbyte, imgpixbyte; int ii, overlap_bytes, overlap_flags; if (*status > 0) return(*status); for (ii = 0; ii < MAX_COMPRESS_DIM; ii++) { /* set default values for higher dimensions */ inc[ii] = 1; imgdim[ii] = 1; tiledim[ii] = 1; imgfpix[ii] = 0; imglpix[ii] = 0; tilefpix[ii] = 0; } /* ------------------------------------------------------------ */ /* calc amount of overlap in each dimension; if there is zero */ /* overlap in any dimension then just return */ /* ------------------------------------------------------------ */ for (ii = 0; ii < ndim; ii++) { if (tlpixel[ii] < fpixel[ii] || tfpixel[ii] > lpixel[ii]) return(*status); /* there are no overlapping pixels */ /* calc dimensions of the output image section */ imgdim[ii] = (lpixel[ii] - fpixel[ii]) / labs(inc[ii]) + 1; if (imgdim[ii] < 1) return(*status = NEG_AXIS); /* calc dimensions of the tile */ tiledim[ii] = tlpixel[ii] - tfpixel[ii] + 1; if (tiledim[ii] < 1) return(*status = NEG_AXIS); if (ii > 0) tiledim[ii] *= tiledim[ii - 1]; /* product of dimensions */ /* first and last pixels in image that overlap with the tile, 0 base */ tf = tfpixel[ii] - 1; tl = tlpixel[ii] - 1; /* skip this plane if it falls in the cracks of the subsampled image */ while ((tf-(fpixel[ii] - 1)) % labs(inc[ii])) { tf++; if (tf > tl) return(*status); /* no overlapping pixels */ } while ((tl-(fpixel[ii] - 1)) % labs(inc[ii])) { tl--; if (tf > tl) return(*status); /* no overlapping pixels */ } imgfpix[ii] = maxvalue((tf - fpixel[ii] +1) / labs(inc[ii]) , 0); imglpix[ii] = minvalue((tl - fpixel[ii] +1) / labs(inc[ii]) , imgdim[ii] - 1); /* first pixel in the tile that overlaps with the image (0 base) */ tilefpix[ii] = maxvalue(fpixel[ii] - tfpixel[ii], 0); while ((tfpixel[ii] + tilefpix[ii] - fpixel[ii]) % labs(inc[ii])) { (tilefpix[ii])++; if (tilefpix[ii] >= tiledim[ii]) return(*status); /* no overlapping pixels */ } /* printf("ii tfpixel, tlpixel %d %d %d \n",ii, tfpixel[ii], tlpixel[ii]); printf("ii, tf, tl, imgfpix,imglpix, tilefpix %d %d %d %d %d %d\n",ii, tf,tl,imgfpix[ii], imglpix[ii],tilefpix[ii]); */ if (ii > 0) imgdim[ii] *= imgdim[ii - 1]; /* product of dimensions */ } /* ---------------------------------------------------------------- */ /* calc number of pixels in each row (first dimension) that overlap */ /* multiply by pixlen to get number of bytes to copy in each loop */ /* ---------------------------------------------------------------- */ if (inc[0] != 1) overlap_flags = 1; /* can only copy 1 pixel at a time */ else overlap_flags = imglpix[0] - imgfpix[0] + 1; /* can copy whole row */ overlap_bytes = overlap_flags * pixlen; /* support up to 5 dimensions for now */ for (i4 = 0, it4=0; i4 <= imglpix[4] - imgfpix[4]; i4++, it4++) { /* increment plane if it falls in the cracks of the subsampled image */ while (ndim > 4 && (tfpixel[4] + tilefpix[4] - fpixel[4] + it4) % labs(inc[4]) != 0) it4++; /* offset to start of hypercube */ if (inc[4] > 0) im4 = (i4 + imgfpix[4]) * imgdim[3]; else im4 = imgdim[4] - (i4 + 1 + imgfpix[4]) * imgdim[3]; t4 = (tilefpix[4] + it4) * tiledim[3]; for (i3 = 0, it3=0; i3 <= imglpix[3] - imgfpix[3]; i3++, it3++) { /* increment plane if it falls in the cracks of the subsampled image */ while (ndim > 3 && (tfpixel[3] + tilefpix[3] - fpixel[3] + it3) % labs(inc[3]) != 0) it3++; /* offset to start of cube */ if (inc[3] > 0) im3 = (i3 + imgfpix[3]) * imgdim[2] + im4; else im3 = imgdim[3] - (i3 + 1 + imgfpix[3]) * imgdim[2] + im4; t3 = (tilefpix[3] + it3) * tiledim[2] + t4; /* loop through planes of the image */ for (i2 = 0, it2=0; i2 <= imglpix[2] - imgfpix[2]; i2++, it2++) { /* incre plane if it falls in the cracks of the subsampled image */ while (ndim > 2 && (tfpixel[2] + tilefpix[2] - fpixel[2] + it2) % labs(inc[2]) != 0) it2++; /* offset to start of plane */ if (inc[2] > 0) im2 = (i2 + imgfpix[2]) * imgdim[1] + im3; else im2 = imgdim[2] - (i2 + 1 + imgfpix[2]) * imgdim[1] + im3; t2 = (tilefpix[2] + it2) * tiledim[1] + t3; /* loop through rows of the image */ for (i1 = 0, it1=0; i1 <= imglpix[1] - imgfpix[1]; i1++, it1++) { /* incre row if it falls in the cracks of the subsampled image */ while (ndim > 1 && (tfpixel[1] + tilefpix[1] - fpixel[1] + it1) % labs(inc[1]) != 0) it1++; /* calc position of first pixel in tile to be copied */ tilepix = tilefpix[0] + (tilefpix[1] + it1) * tiledim[0] + t2; /* offset to start of row */ if (inc[1] > 0) im1 = (i1 + imgfpix[1]) * imgdim[0] + im2; else im1 = imgdim[1] - (i1 + 1 + imgfpix[1]) * imgdim[0] + im2; /* printf("inc = %d %d %d %d\n",inc[0],inc[1],inc[2],inc[3]); printf("im1,im2,im3,im4 = %d %d %d %d\n",im1,im2,im3,im4); */ /* offset to byte within the row */ if (inc[0] > 0) imgpix = imgfpix[0] + im1; else imgpix = imgdim[0] - 1 - imgfpix[0] + im1; /* printf("tilefpix0,1, imgfpix1, it1, inc1, t2= %d %d %d %d %d %d\n", tilefpix[0],tilefpix[1],imgfpix[1],it1,inc[1], t2); printf("i1, it1, tilepix, imgpix %d %d %d %d \n", i1, it1, tilepix, imgpix); */ /* loop over pixels along one row of the image */ for (ipos = imgfpix[0]; ipos <= imglpix[0]; ipos += overlap_flags) { /* convert from image pixel to byte offset */ tilepixbyte = tilepix * pixlen; imgpixbyte = imgpix * pixlen; /* printf(" tilepix, tilepixbyte, imgpix, imgpixbyte= %d %d %d %d\n", tilepix, tilepixbyte, imgpix, imgpixbyte); */ /* copy overlapping row of pixels from image to tile */ memcpy(tile + tilepixbyte, image + imgpixbyte, overlap_bytes); tilepix += (overlap_flags * labs(inc[0])); if (inc[0] > 0) imgpix += overlap_flags; else imgpix -= overlap_flags; } } } } } return(*status); } indi-0.5/src/cfitsio/getcolsb.c0000644000175000017500000022323410610474375014323 0ustar jrjr/* This file, getcolsb.c, contains routines that read data elements from */ /* a FITS image or table, with signed char (signed byte) data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ signed char nulval, /* I - value for undefined pixels */ signed char *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; signed char nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TSBYTE, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclsb(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ signed char *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TSBYTE, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclsb(fptr, 2, row, firstelem, nelem, 1, 2, 0, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ signed char nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ signed char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dsb(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dsb(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ signed char nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ signed char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; LONGLONG nfits, narray; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; signed char nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TSBYTE, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclsb(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclsb(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ signed char nulval, /* I - value to set undefined pixels */ signed char *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii, i0, i1, i2, i3, i4, i5, i6, i7, i8, row, rstr, rstp, rinc; long str[9], stp[9], incr[9], dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; signed char nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvsb is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TSBYTE, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvsb: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgclsb(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ signed char *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; signed char nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvsb is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TSBYTE, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvsb: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclsb(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpsb( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ signed char *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclsb(fptr, 1, row, firstelem, nelem, 1, 1, 0, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ signed char nulval, /* I - value for null pixels */ signed char *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ signed char *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { signed char dummy = 0; ffgclsb(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclsb(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ signed char nulval, /* I - value for null pixels if nultyp = 1 */ signed char *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; union u_tag { char charval; signed char scharval; } u; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status); /* special case: read column of T/F logicals */ if (tcode == TLOGICAL && elemincre == 1) { u.scharval = nulval; ffgcll(fptr, colnum, firstrow, firstelem, nelem, nultyp, u.charval, (char *) array, nularray, anynul, status); return(*status); } if (strchr(tform,'A') != NULL) { if (*status == BAD_ELEM_NUM) { /* ignore this error message */ *status = 0; ffcmsg(); /* clear error stack */ } /* interpret a 'A' ASCII column as a 'B' byte column ('8A' == '8B') */ /* This is an undocumented 'feature' in CFITSIO */ /* we have to reset some of the values returned by ffgcpr */ tcode = TBYTE; incre = 1; /* each element is 1 byte wide */ repeat = twidth; /* total no. of chars in the col */ twidth = 1; /* width of each element */ scale = 1.0; /* no scaling */ zero = 0.0; tnull = NULL_UNDEFINED; /* don't test for nulls */ maxelem = DBUFFSIZE; } if (*status > 0) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING && hdutype == ASCII_TBL) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default, check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + (rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) &array[next], status); fffi1s1((unsigned char *)&array[next], ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2s1((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4s1((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8s1( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4s1((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8s1((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); /* interpret the string as an ASCII formated number */ fffstrs1((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read bytes from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgclsb).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgclsb).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1s1(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == -128.) { /* Instead of subtracting 128, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(signed char *) &input[ii] ) ^ 0x80; } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == -128.) { /* Instead of subtracting 128, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = ( *(signed char *) &input[ii] ) ^ 0x80; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2s1(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4s1(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8s1(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < -128) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > 127) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4s1(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { /* use redundant boolean logic in following statement */ /* to suppress irritating Borland compiler warning message */ if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (zero > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8s1(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (input[ii] > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (zero > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstrs1(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ signed char nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ signed char *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DSCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = -128; } else if (dvalue > DSCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = 127; } else output[ii] = (signed char) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } indi-0.5/src/cfitsio/longnam.h0000644000175000017500000004734510610474402014157 0ustar jrjr#ifndef _LONGNAME_H #define _LONGNAME_H #define fits_parse_input_url ffiurl #define fits_parse_input_filename ffifile #define fits_parse_rootname ffrtnm #define fits_file_exists ffexist #define fits_parse_output_url ffourl #define fits_parse_extspec ffexts #define fits_parse_extnum ffextn #define fits_parse_binspec ffbins #define fits_parse_binrange ffbinr #define fits_parse_range ffrwrg #define fits_parse_rangell ffrwrgll #define fits_open_memfile ffomem /* use the following special macro to test that the fitsio.h include file that was used to build the CFITSIO library is the same version as included when compiling the application program */ #define fits_open_file(A, B, C, D) ffopentest( CFITSIO_VERSION, A, B, C, D) #define fits_open_data ffdopn #define fits_open_table fftopn #define fits_open_image ffiopn #define fits_open_diskfile ffdkopn #define fits_reopen_file ffreopen #define fits_create_file ffinit #define fits_create_diskfile ffdkinit #define fits_create_memfile ffimem #define fits_create_template fftplt #define fits_flush_file ffflus #define fits_flush_buffer ffflsh #define fits_close_file ffclos #define fits_delete_file ffdelt #define fits_file_name ffflnm #define fits_file_mode ffflmd #define fits_url_type ffurlt #define fits_get_version ffvers #define fits_uppercase ffupch #define fits_get_errstatus ffgerr #define fits_write_errmsg ffpmsg #define fits_write_errmark ffpmrk #define fits_read_errmsg ffgmsg #define fits_clear_errmsg ffcmsg #define fits_clear_errmark ffcmrk #define fits_report_error ffrprt #define fits_compare_str ffcmps #define fits_test_keyword fftkey #define fits_test_record fftrec #define fits_null_check ffnchk #define fits_make_keyn ffkeyn #define fits_make_nkey ffnkey #define fits_get_keyclass ffgkcl #define fits_get_keytype ffdtyp #define fits_parse_value ffpsvc #define fits_get_keyname ffgknm #define fits_parse_template ffgthd #define fits_ascii_tform ffasfm #define fits_binary_tform ffbnfm #define fits_binary_tformll ffbnfmll #define fits_get_tbcol ffgabc #define fits_get_rowsize ffgrsz #define fits_get_col_display_width ffgcdw #define fits_write_record ffprec #define fits_write_key ffpky #define fits_write_key_unit ffpunt #define fits_write_comment ffpcom #define fits_write_history ffphis #define fits_write_date ffpdat #define fits_get_system_time ffgstm #define fits_get_system_date ffgsdt #define fits_date2str ffdt2s #define fits_time2str fftm2s #define fits_str2date ffs2dt #define fits_str2time ffs2tm #define fits_write_key_longstr ffpkls #define fits_write_key_longwarn ffplsw #define fits_write_key_null ffpkyu #define fits_write_key_str ffpkys #define fits_write_key_log ffpkyl #define fits_write_key_lng ffpkyj #define fits_write_key_fixflt ffpkyf #define fits_write_key_flt ffpkye #define fits_write_key_fixdbl ffpkyg #define fits_write_key_dbl ffpkyd #define fits_write_key_fixcmp ffpkfc #define fits_write_key_cmp ffpkyc #define fits_write_key_fixdblcmp ffpkfm #define fits_write_key_dblcmp ffpkym #define fits_write_key_triple ffpkyt #define fits_write_tdim ffptdm #define fits_write_tdimll ffptdmll #define fits_write_keys_str ffpkns #define fits_write_keys_log ffpknl #define fits_write_keys_lng ffpknj #define fits_write_keys_fixflt ffpknf #define fits_write_keys_flt ffpkne #define fits_write_keys_fixdbl ffpkng #define fits_write_keys_dbl ffpknd #define fits_copy_key ffcpky #define fits_write_imghdr ffphps #define fits_write_imghdrll ffphpsll #define fits_write_grphdr ffphpr #define fits_write_grphdrll ffphprll #define fits_write_atblhdr ffphtb #define fits_write_btblhdr ffphbn #define fits_write_exthdr ffphext #define fits_write_key_template ffpktp #define fits_get_hdrspace ffghsp #define fits_get_hdrpos ffghps #define fits_movabs_key ffmaky #define fits_movrel_key ffmrky #define fits_find_nextkey ffgnxk #define fits_read_record ffgrec #define fits_read_card ffgcrd #define fits_read_key_unit ffgunt #define fits_read_keyn ffgkyn #define fits_read_key ffgky #define fits_read_keyword ffgkey #define fits_read_key_str ffgkys #define fits_read_key_log ffgkyl #define fits_read_key_lng ffgkyj #define fits_read_key_lnglng ffgkyjj #define fits_read_key_flt ffgkye #define fits_read_key_dbl ffgkyd #define fits_read_key_cmp ffgkyc #define fits_read_key_dblcmp ffgkym #define fits_read_key_triple ffgkyt #define fits_read_key_longstr ffgkls #define fits_read_tdim ffgtdm #define fits_read_tdimll ffgtdmll #define fits_decode_tdim ffdtdm #define fits_decode_tdimll ffdtdmll #define fits_read_keys_str ffgkns #define fits_read_keys_log ffgknl #define fits_read_keys_lng ffgknj #define fits_read_keys_flt ffgkne #define fits_read_keys_dbl ffgknd #define fits_read_imghdr ffghpr #define fits_read_imghdrll ffghprll #define fits_read_atblhdr ffghtb #define fits_read_btblhdr ffghbn #define fits_read_atblhdrll ffghtbll #define fits_read_btblhdrll ffghbnll #define fits_hdr2str ffhdr2str #define fits_update_card ffucrd #define fits_update_key ffuky #define fits_update_key_null ffukyu #define fits_update_key_str ffukys #define fits_update_key_longstr ffukls #define fits_update_key_log ffukyl #define fits_update_key_lng ffukyj #define fits_update_key_fixflt ffukyf #define fits_update_key_flt ffukye #define fits_update_key_fixdbl ffukyg #define fits_update_key_dbl ffukyd #define fits_update_key_fixcmp ffukfc #define fits_update_key_cmp ffukyc #define fits_update_key_fixdblcmp ffukfm #define fits_update_key_dblcmp ffukym #define fits_modify_record ffmrec #define fits_modify_card ffmcrd #define fits_modify_name ffmnam #define fits_modify_comment ffmcom #define fits_modify_key_null ffmkyu #define fits_modify_key_str ffmkys #define fits_modify_key_longstr ffmkls #define fits_modify_key_log ffmkyl #define fits_modify_key_lng ffmkyj #define fits_modify_key_fixflt ffmkyf #define fits_modify_key_flt ffmkye #define fits_modify_key_fixdbl ffmkyg #define fits_modify_key_dbl ffmkyd #define fits_modify_key_fixcmp ffmkfc #define fits_modify_key_cmp ffmkyc #define fits_modify_key_fixdblcmp ffmkfm #define fits_modify_key_dblcmp ffmkym #define fits_insert_record ffirec #define fits_insert_card ffikey #define fits_insert_key_null ffikyu #define fits_insert_key_str ffikys #define fits_insert_key_longstr ffikls #define fits_insert_key_log ffikyl #define fits_insert_key_lng ffikyj #define fits_insert_key_fixflt ffikyf #define fits_insert_key_flt ffikye #define fits_insert_key_fixdbl ffikyg #define fits_insert_key_dbl ffikyd #define fits_insert_key_fixcmp ffikfc #define fits_insert_key_cmp ffikyc #define fits_insert_key_fixdblcmp ffikfm #define fits_insert_key_dblcmp ffikym #define fits_delete_key ffdkey #define fits_delete_record ffdrec #define fits_get_hdu_num ffghdn #define fits_get_hdu_type ffghdt #define fits_get_hduaddr ffghad #define fits_get_hduaddrll ffghadll #define fits_get_hduoff ffghof #define fits_get_img_param ffgipr #define fits_get_img_paramll ffgiprll #define fits_get_img_type ffgidt #define fits_get_img_equivtype ffgiet #define fits_get_img_dim ffgidm #define fits_get_img_size ffgisz #define fits_get_img_sizell ffgiszll #define fits_movabs_hdu ffmahd #define fits_movrel_hdu ffmrhd #define fits_movnam_hdu ffmnhd #define fits_get_num_hdus ffthdu #define fits_create_img ffcrim #define fits_create_imgll ffcrimll #define fits_create_tbl ffcrtb #define fits_create_hdu ffcrhd #define fits_insert_img ffiimg #define fits_insert_imgll ffiimgll #define fits_insert_atbl ffitab #define fits_insert_btbl ffibin #define fits_resize_img ffrsim #define fits_resize_imgll ffrsimll #define fits_delete_hdu ffdhdu #define fits_copy_hdu ffcopy #define fits_copy_file ffcpfl #define fits_copy_header ffcphd #define fits_copy_data ffcpdt #define fits_write_hdu ffwrhdu #define fits_set_hdustruc ffrdef #define fits_set_hdrsize ffhdef #define fits_write_theap ffpthp #define fits_encode_chksum ffesum #define fits_decode_chksum ffdsum #define fits_write_chksum ffpcks #define fits_update_chksum ffupck #define fits_verify_chksum ffvcks #define fits_get_chksum ffgcks #define fits_set_bscale ffpscl #define fits_set_tscale fftscl #define fits_set_imgnull ffpnul #define fits_set_btblnull fftnul #define fits_set_atblnull ffsnul #define fits_get_colnum ffgcno #define fits_get_colname ffgcnn #define fits_get_coltype ffgtcl #define fits_get_coltypell ffgtclll #define fits_get_eqcoltype ffeqty #define fits_get_eqcoltypell ffeqtyll #define fits_get_num_rows ffgnrw #define fits_get_num_rowsll ffgnrwll #define fits_get_num_cols ffgncl #define fits_get_acolparms ffgacl #define fits_get_bcolparms ffgbcl #define fits_get_bcolparmsll ffgbclll #define fits_iterate_data ffiter #define fits_read_grppar_byt ffggpb #define fits_read_grppar_sbyt ffggpsb #define fits_read_grppar_usht ffggpui #define fits_read_grppar_ulng ffggpuj #define fits_read_grppar_sht ffggpi #define fits_read_grppar_lng ffggpj #define fits_read_grppar_lnglng ffggpjj #define fits_read_grppar_int ffggpk #define fits_read_grppar_uint ffggpuk #define fits_read_grppar_flt ffggpe #define fits_read_grppar_dbl ffggpd #define fits_read_pix ffgpxv #define fits_read_pixll ffgpxvll #define fits_read_pixnull ffgpxf #define fits_read_pixnullll ffgpxfll #define fits_read_img ffgpv #define fits_read_imgnull ffgpf #define fits_read_img_byt ffgpvb #define fits_read_img_sbyt ffgpvsb #define fits_read_img_usht ffgpvui #define fits_read_img_ulng ffgpvuj #define fits_read_img_sht ffgpvi #define fits_read_img_lng ffgpvj #define fits_read_img_lnglng ffgpvjj #define fits_read_img_uint ffgpvuk #define fits_read_img_int ffgpvk #define fits_read_img_flt ffgpve #define fits_read_img_dbl ffgpvd #define fits_read_imgnull_byt ffgpfb #define fits_read_imgnull_sbyt ffgpfsb #define fits_read_imgnull_usht ffgpfui #define fits_read_imgnull_ulng ffgpfuj #define fits_read_imgnull_sht ffgpfi #define fits_read_imgnull_lng ffgpfj #define fits_read_imgnull_lnglng ffgpfjj #define fits_read_imgnull_uint ffgpfuk #define fits_read_imgnull_int ffgpfk #define fits_read_imgnull_flt ffgpfe #define fits_read_imgnull_dbl ffgpfd #define fits_read_2d_byt ffg2db #define fits_read_2d_sbyt ffg2dsb #define fits_read_2d_usht ffg2dui #define fits_read_2d_ulng ffg2duj #define fits_read_2d_sht ffg2di #define fits_read_2d_lng ffg2dj #define fits_read_2d_lnglng ffg2djj #define fits_read_2d_uint ffg2duk #define fits_read_2d_int ffg2dk #define fits_read_2d_flt ffg2de #define fits_read_2d_dbl ffg2dd #define fits_read_3d_byt ffg3db #define fits_read_3d_sbyt ffg3dsb #define fits_read_3d_usht ffg3dui #define fits_read_3d_ulng ffg3duj #define fits_read_3d_sht ffg3di #define fits_read_3d_lng ffg3dj #define fits_read_3d_lnglng ffg3djj #define fits_read_3d_uint ffg3duk #define fits_read_3d_int ffg3dk #define fits_read_3d_flt ffg3de #define fits_read_3d_dbl ffg3dd #define fits_read_subset ffgsv #define fits_read_subset_byt ffgsvb #define fits_read_subset_sbyt ffgsvsb #define fits_read_subset_usht ffgsvui #define fits_read_subset_ulng ffgsvuj #define fits_read_subset_sht ffgsvi #define fits_read_subset_lng ffgsvj #define fits_read_subset_lnglng ffgsvjj #define fits_read_subset_uint ffgsvuk #define fits_read_subset_int ffgsvk #define fits_read_subset_flt ffgsve #define fits_read_subset_dbl ffgsvd #define fits_read_subsetnull_byt ffgsfb #define fits_read_subsetnull_sbyt ffgsfsb #define fits_read_subsetnull_usht ffgsfui #define fits_read_subsetnull_ulng ffgsfuj #define fits_read_subsetnull_sht ffgsfi #define fits_read_subsetnull_lng ffgsfj #define fits_read_subsetnull_lnglng ffgsfjj #define fits_read_subsetnull_uint ffgsfuk #define fits_read_subsetnull_int ffgsfk #define fits_read_subsetnull_flt ffgsfe #define fits_read_subsetnull_dbl ffgsfd #define ffcpimg fits_copy_image_section #define fits_compress_img fits_comp_img #define fits_decompress_img fits_decomp_img #define fits_read_col ffgcv #define fits_read_colnull ffgcf #define fits_read_col_str ffgcvs #define fits_read_col_log ffgcvl #define fits_read_col_byt ffgcvb #define fits_read_col_sbyt ffgcvsb #define fits_read_col_usht ffgcvui #define fits_read_col_ulng ffgcvuj #define fits_read_col_sht ffgcvi #define fits_read_col_lng ffgcvj #define fits_read_col_lnglng ffgcvjj #define fits_read_col_uint ffgcvuk #define fits_read_col_int ffgcvk #define fits_read_col_flt ffgcve #define fits_read_col_dbl ffgcvd #define fits_read_col_cmp ffgcvc #define fits_read_col_dblcmp ffgcvm #define fits_read_col_bit ffgcx #define fits_read_col_bit_usht ffgcxui #define fits_read_col_bit_uint ffgcxuk #define fits_read_colnull_str ffgcfs #define fits_read_colnull_log ffgcfl #define fits_read_colnull_byt ffgcfb #define fits_read_colnull_sbyt ffgcfsb #define fits_read_colnull_usht ffgcfui #define fits_read_colnull_ulng ffgcfuj #define fits_read_colnull_sht ffgcfi #define fits_read_colnull_lng ffgcfj #define fits_read_colnull_lnglng ffgcfjj #define fits_read_colnull_uint ffgcfuk #define fits_read_colnull_int ffgcfk #define fits_read_colnull_flt ffgcfe #define fits_read_colnull_dbl ffgcfd #define fits_read_colnull_cmp ffgcfc #define fits_read_colnull_dblcmp ffgcfm #define fits_read_descript ffgdes #define fits_read_descriptll ffgdesll #define fits_read_descripts ffgdess #define fits_read_descriptsll ffgdessll #define fits_read_tblbytes ffgtbb #define fits_write_grppar_byt ffpgpb #define fits_write_grppar_sbyt ffpgpsb #define fits_write_grppar_usht ffpgpui #define fits_write_grppar_ulng ffpgpuj #define fits_write_grppar_sht ffpgpi #define fits_write_grppar_lng ffpgpj #define fits_write_grppar_lnglng ffpgpjj #define fits_write_grppar_uint ffpgpuk #define fits_write_grppar_int ffpgpk #define fits_write_grppar_flt ffpgpe #define fits_write_grppar_dbl ffpgpd #define fits_write_pix ffppx #define fits_write_pixll ffppxll #define fits_write_pixnull ffppxn #define fits_write_pixnullll ffppxnll #define fits_write_img ffppr #define fits_write_img_byt ffpprb #define fits_write_img_sbyt ffpprsb #define fits_write_img_usht ffpprui #define fits_write_img_ulng ffppruj #define fits_write_img_sht ffppri #define fits_write_img_lng ffpprj #define fits_write_img_lnglng ffpprjj #define fits_write_img_uint ffppruk #define fits_write_img_int ffpprk #define fits_write_img_flt ffppre #define fits_write_img_dbl ffpprd #define fits_write_imgnull ffppn #define fits_write_imgnull_byt ffppnb #define fits_write_imgnull_sbyt ffppnsb #define fits_write_imgnull_usht ffppnui #define fits_write_imgnull_ulng ffppnuj #define fits_write_imgnull_sht ffppni #define fits_write_imgnull_lng ffppnj #define fits_write_imgnull_lnglng ffppnjj #define fits_write_imgnull_uint ffppnuk #define fits_write_imgnull_int ffppnk #define fits_write_imgnull_flt ffppne #define fits_write_imgnull_dbl ffppnd #define fits_write_img_null ffppru #define fits_write_null_img ffpprn #define fits_write_2d_byt ffp2db #define fits_write_2d_sbyt ffp2dsb #define fits_write_2d_usht ffp2dui #define fits_write_2d_ulng ffp2duj #define fits_write_2d_sht ffp2di #define fits_write_2d_lng ffp2dj #define fits_write_2d_lnglng ffp2djj #define fits_write_2d_uint ffp2duk #define fits_write_2d_int ffp2dk #define fits_write_2d_flt ffp2de #define fits_write_2d_dbl ffp2dd #define fits_write_3d_byt ffp3db #define fits_write_3d_sbyt ffp3dsb #define fits_write_3d_usht ffp3dui #define fits_write_3d_ulng ffp3duj #define fits_write_3d_sht ffp3di #define fits_write_3d_lng ffp3dj #define fits_write_3d_lnglng ffp3djj #define fits_write_3d_uint ffp3duk #define fits_write_3d_int ffp3dk #define fits_write_3d_flt ffp3de #define fits_write_3d_dbl ffp3dd #define fits_write_subset ffpss #define fits_write_subset_byt ffpssb #define fits_write_subset_sbyt ffpsssb #define fits_write_subset_usht ffpssui #define fits_write_subset_ulng ffpssuj #define fits_write_subset_sht ffpssi #define fits_write_subset_lng ffpssj #define fits_write_subset_lnglng ffpssjj #define fits_write_subset_uint ffpssuk #define fits_write_subset_int ffpssk #define fits_write_subset_flt ffpsse #define fits_write_subset_dbl ffpssd #define fits_write_col ffpcl #define fits_write_col_str ffpcls #define fits_write_col_log ffpcll #define fits_write_col_byt ffpclb #define fits_write_col_sbyt ffpclsb #define fits_write_col_usht ffpclui #define fits_write_col_ulng ffpcluj #define fits_write_col_sht ffpcli #define fits_write_col_lng ffpclj #define fits_write_col_lnglng ffpcljj #define fits_write_col_uint ffpcluk #define fits_write_col_int ffpclk #define fits_write_col_flt ffpcle #define fits_write_col_dbl ffpcld #define fits_write_col_cmp ffpclc #define fits_write_col_dblcmp ffpclm #define fits_write_col_null ffpclu #define fits_write_col_bit ffpclx #define fits_write_nulrows ffprwu #define fits_write_nullrows ffprwu #define fits_write_colnull ffpcn #define fits_write_colnull_str ffpcns #define fits_write_colnull_log ffpcnl #define fits_write_colnull_byt ffpcnb #define fits_write_colnull_sbyt ffpcnsb #define fits_write_colnull_usht ffpcnui #define fits_write_colnull_ulng ffpcnuj #define fits_write_colnull_sht ffpcni #define fits_write_colnull_lng ffpcnj #define fits_write_colnull_lnglng ffpcnjj #define fits_write_colnull_uint ffpcnuk #define fits_write_colnull_int ffpcnk #define fits_write_colnull_flt ffpcne #define fits_write_colnull_dbl ffpcnd #define fits_write_ext ffpextn #define fits_read_ext ffgextn #define fits_write_descript ffpdes #define fits_compress_heap ffcmph #define fits_test_heap fftheap #define fits_write_tblbytes ffptbb #define fits_insert_rows ffirow #define fits_delete_rows ffdrow #define fits_delete_rowrange ffdrrg #define fits_delete_rowlist ffdrws #define fits_delete_rowlistll ffdrwsll #define fits_insert_col fficol #define fits_insert_cols fficls #define fits_delete_col ffdcol #define fits_copy_col ffcpcl #define fits_modify_vector_len ffmvec #define fits_read_img_coord ffgics #define fits_read_tbl_coord ffgtcs #define fits_pix_to_world ffwldp #define fits_world_to_pix ffxypx #define fits_get_image_wcs_keys ffgiwcs #define fits_get_table_wcs_keys ffgtwcs #define fits_find_rows fffrow #define fits_find_first_row ffffrw #define fits_find_rows_cmp fffrwc #define fits_select_rows ffsrow #define fits_calc_rows ffcrow #define fits_calculator ffcalc #define fits_calculator_rng ffcalc_rng #define fits_test_expr fftexp #define fits_create_group ffgtcr #define fits_insert_group ffgtis #define fits_change_group ffgtch #define fits_remove_group ffgtrm #define fits_copy_group ffgtcp #define fits_merge_groups ffgtmg #define fits_compact_group ffgtcm #define fits_verify_group ffgtvf #define fits_open_group ffgtop #define fits_add_group_member ffgtam #define fits_get_num_members ffgtnm #define fits_get_num_groups ffgmng #define fits_open_member ffgmop #define fits_copy_member ffgmcp #define fits_transfer_member ffgmtf #define fits_remove_member ffgmrm #endif indi-0.5/src/cfitsio/putcoll.c0000644000175000017500000003264110610474375014203 0ustar jrjr/* This file, putcoll.c, contains routines that write data elements to */ /* a FITS image or table, with logical datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpcll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ char *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of logical values to a column in the current FITS HDU. */ { int tcode, maxelem, hdutype; long twidth, incre; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], ctrue = 'T', cfalse = 'F'; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ if (*status > 0) /* inherit input status value if > 0 */ return(*status); /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode != TLOGICAL) return(*status = NOT_LOGICAL_COL); /*---------------------------------------------------------------------*/ /* Now write the logical values one at a time to the FITS column. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { wrtptr = startpos + (rowlen * rownum) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ if (array[next]) ffpbyt(fptr, 1, &ctrue, status); else ffpbyt(fptr, 1, &cfalse, status); if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing element %.0f of input array of logicals (ffpcll).", (double) (next+1)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain--; if (remain) { next++; elemnum++; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ char *array, /* I - array of values to write */ char nulvalue, /* I - array flagging undefined pixels if true */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels flagged as null will be replaced by the appropriate null value in the output FITS file. */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* first write the whole input vector, then go back and fill in the nulls */ if (ffpcll(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) return(*status); /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ /* good values have already been written if (ffpcll(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) return(*status); */ ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ /* these have already been written ffpcll(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); */ } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffpclx( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG frow, /* I - first row to write (1 = 1st row) */ long fbit, /* I - first bit to write (1 = 1st) */ long nbit, /* I - number of bits to write */ char *larray, /* I - array of logicals corresponding to bits */ int *status) /* IO - error status */ /* write an array of logical values to a specified bit or byte column of the binary table. If larray is TRUE, then the corresponding bit is set to 1, otherwise it is set to 0. The binary table column being written to must have datatype 'B' or 'X'. */ { LONGLONG offset, bstart, repeat, rowlen, elemnum, rstart, estart, tnull; long fbyte, lbyte, nbyte, bitloc, ndone; long ii, twidth, incre; int tcode, descrp, maxelem, hdutype; double dummyd; char tform[12], snull[12]; unsigned char cbuff; static unsigned char onbit[8] = {128, 64, 32, 16, 8, 4, 2, 1}; static unsigned char offbit[8] = {127, 191, 223, 239, 247, 251, 253, 254}; tcolumn *colptr; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* check input parameters */ if (nbit < 1) return(*status); else if (frow < 1) return(*status = BAD_ROW_NUM); else if (fbit < 1) return(*status = BAD_ELEM_NUM); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); fbyte = (fbit + 7) / 8; lbyte = (fbit + nbit + 6) / 8; nbyte = lbyte - fbyte +1; /* Save the current heapsize; ffgcprll will increment the value if */ /* we are writing to a variable length column. */ offset = (fptr->Fptr)->heapsize; /* call ffgcprll in case we are writing beyond the current end of */ /* the table; it will allocate more space and shift any following */ /* HDU's. Otherwise, we have little use for most of the returned */ /* parameters, therefore just use dummy parameters. */ if (ffgcprll( fptr, colnum, frow, fbyte, nbyte, 1, &dummyd, &dummyd, tform, &twidth, &tcode, &maxelem, &bstart, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); bitloc = fbit - 1 - ((fbit - 1) / 8 * 8); ndone = 0; rstart = frow - 1; estart = fbyte - 1; colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (abs(tcode) > TBYTE) return(*status = NOT_LOGICAL_COL); /* not correct datatype column */ if (tcode > 0) { descrp = FALSE; /* not a variable length descriptor column */ repeat = colptr->trepeat; if (tcode == TBIT) repeat = (repeat + 7) / 8; /* convert from bits to bytes */ if (fbyte > repeat) return(*status = BAD_ELEM_NUM); /* calc the i/o pointer location to start of sequence of pixels */ bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) + colptr->tbcol + estart; } else { descrp = TRUE; /* a variable length descriptor column */ /* only bit arrays (tform = 'X') are supported for variable */ /* length arrays. REPEAT is the number of BITS in the array. */ repeat = fbit + nbit -1; /* write the number of elements and the starting offset. */ /* Note: ffgcprll previous wrote the descripter, but with the */ /* wrong repeat value (gave bytes instead of bits). */ if (tcode == -TBIT) ffpdes(fptr, colnum, frow, (long) repeat, offset, status); /* Calc the i/o pointer location to start of sequence of pixels. */ /* ffgcprll has already calculated a value for bstart that */ /* points to the first element of the vector; we just have to */ /* increment it to point to the first element we want to write to. */ /* Note: ffgcprll also already updated the size of the heap, so we */ /* don't have to do that again here. */ bstart += estart; } /* move the i/o pointer to the start of the pixel sequence */ ffmbyt(fptr, bstart, IGNORE_EOF, status); /* read the next byte (we may only be modifying some of the bits) */ while (1) { if (ffgbyt(fptr, 1, &cbuff, status) == END_OF_FILE) { /* hit end of file trying to read the byte, so just set byte = 0 */ *status = 0; cbuff = 0; } /* move back, to be able to overwrite the byte */ ffmbyt(fptr, bstart, IGNORE_EOF, status); for (ii = bitloc; (ii < 8) && (ndone < nbit); ii++, ndone++) { if(larray[ndone]) cbuff = cbuff | onbit[ii]; else cbuff = cbuff & offbit[ii]; } ffpbyt(fptr, 1, &cbuff, status); /* write the modified byte */ if (ndone == nbit) /* finished all the bits */ return(*status); /* not done, so get the next byte */ bstart++; if (!descrp) { estart++; if (estart == repeat) { /* move the i/o pointer to the next row of pixels */ estart = 0; rstart = rstart + 1; bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) + colptr->tbcol; ffmbyt(fptr, bstart, IGNORE_EOF, status); } } bitloc = 0; } } indi-0.5/src/cfitsio/putcolui.c0000644000175000017500000010250410610474375014361 0ustar jrjr/* This file, putcolui.c, contains routines that write data elements to */ /* a FITS image or table, with unsigned short datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; unsigned short nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TUSHORT, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclui(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values that are written */ unsigned short nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; unsigned short nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TUSHORT, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnui(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dui(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TUSHORT, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclui(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclui(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ unsigned short *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TUSHORT, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclui(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpui( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclui(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclui( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TSHORT): ffu2fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TLONGLONG): ffu2fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffu2fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TLONG): ffu2fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TFLOAT): ffu2fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffu2fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffu2fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpclui).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ unsigned short *array, /* I - array of values to write */ unsigned short nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclui(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclui(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclui(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fi1(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fi2(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 32768.) { /* Instead of subtracting 32768, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(short *) &input[ii] ) ^ 0x8000; } else if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fi4(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; /* copy input to output */ } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fi8(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fr4(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) (((double) input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fr8(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = ((double) input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffu2fstr(unsigned short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = ((double) input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } indi-0.5/src/cfitsio/fitscore.c0000644000175000017500000102342210610474374014334 0ustar jrjr/* This file, fitscore.c, contains the core set of FITSIO routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ /* Copyright (Unpublished--all rights reserved under the copyright laws of the United States), U.S. Government as represented by the Administrator of the National Aeronautics and Space Administration. No copyright is claimed in the United States under Title 17, U.S. Code. Permission to freely use, copy, modify, and distribute this software and its documentation without fee is hereby granted, provided that this copyright notice and disclaimer of warranty appears in all copies. DISCLAIMER: THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NASA BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT , OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER." */ #include #include #include #include #include #include /* stddef.h is apparently needed to define size_t with some compilers ?? */ #include #include "fitsio2.h" #define errmsgsiz 25 #define ESMARKER 27 /* Escape character is used as error stack marker */ #define DelAll 1 /* delete all messages on the error stack */ #define DelMark 2 /* delete newest messages back to and including marker */ #define DelNewest 3 /* delete the newest message from the stack */ #define GetMesg 4 /* pop and return oldest message, ignoring marks */ #define PutMesg 5 /* add a new message to the stack */ #define PutMark 6 /* add a marker to the stack */ /*--------------------------------------------------------------------------*/ float ffvers(float *version) /* IO - version number */ /* return the current version number of the FITSIO software */ { *version = (float) 3.03; /* 11 Dec 2006 Previous releases: *version = 3.02 18 Sep 2006 *version = 3.01 May 2006 included in FTOOLS 6.1 release *version = 3.006 20 Feb 2006 *version = 3.005 20 Dec 2005 (beta, in heasoft swift release *version = 3.004 16 Sep 2005 (beta, in heasoft swift release *version = 3.003 28 Jul 2005 (beta, in heasoft swift release *version = 3.002 15 Apr 2005 (beta) *version = 3.001 15 Mar 2005 (beta) released with heasoft 6.0 *version = 3.000 1 Mar 2005 (internal release only) *version = 2.51 2 Dec 2004 *version = 2.50 28 Jul 2004 *version = 2.49 11 Feb 2004 *version = 2.48 28 Jan 2004 *version = 2.470 18 Aug 2003 *version = 2.460 20 May 2003 *version = 2.450 30 Apr 2003 (internal release only) *version = 2.440 8 Jan 2003 *version = 2.430; 4 Nov 2002 *version = 2.420; 19 Jul 2002 *version = 2.410; 22 Apr 2002 used in ftools v5.2 *version = 2.401; 28 Jan 2002 *version = 2.400; 18 Jan 2002 *version = 2.301; 7 Dec 2001 *version = 2.300; 23 Oct 2001 *version = 2.204; 26 Jul 2001 *version = 2.203; 19 Jul 2001 used in ftools v5.1 *version = 2.202; 22 May 2001 *version = 2.201; 15 Mar 2001 *version = 2.200; 26 Jan 2001 *version = 2.100; 26 Sep 2000 *version = 2.037; 6 Jul 2000 *version = 2.036; 1 Feb 2000 *version = 2.035; 7 Dec 1999 (internal release only) *version = 2.034; 23 Nov 1999 *version = 2.033; 17 Sep 1999 *version = 2.032; 25 May 1999 *version = 2.031; 31 Mar 1999 *version = 2.030; 24 Feb 1999 *version = 2.029; 11 Feb 1999 *version = 2.028; 26 Jan 1999 *version = 2.027; 12 Jan 1999 *version = 2.026; 23 Dec 1998 *version = 2.025; 1 Dec 1998 *version = 2.024; 9 Nov 1998 *version = 2.023; 1 Nov 1998 first full release of V2.0 *version = 1.42; 30 Apr 1998 *version = 1.40; 6 Feb 1998 *version = 1.33; 16 Dec 1997 (internal release only) *version = 1.32; 21 Nov 1997 (internal release only) *version = 1.31; 4 Nov 1997 (internal release only) *version = 1.30; 11 Sep 1997 *version = 1.27; 3 Sep 1997 (internal release only) *version = 1.25; 2 Jul 1997 *version = 1.24; 2 May 1997 *version = 1.23; 24 Apr 1997 *version = 1.22; 18 Apr 1997 *version = 1.21; 26 Mar 1997 *version = 1.2; 29 Jan 1997 *version = 1.11; 04 Dec 1996 *version = 1.101; 13 Nov 1996 *version = 1.1; 6 Nov 1996 *version = 1.04; 17 Sep 1996 *version = 1.03; 20 Aug 1996 *version = 1.02; 15 Aug 1996 *version = 1.01; 12 Aug 1996 */ return(*version); } /*--------------------------------------------------------------------------*/ int ffflnm(fitsfile *fptr, /* I - FITS file pointer */ char *filename, /* O - name of the file */ int *status) /* IO - error status */ /* return the name of the FITS file */ { strcpy(filename,(fptr->Fptr)->filename); return(*status); } /*--------------------------------------------------------------------------*/ int ffflmd(fitsfile *fptr, /* I - FITS file pointer */ int *filemode, /* O - open mode of the file */ int *status) /* IO - error status */ /* return the access mode of the FITS file */ { *filemode = (fptr->Fptr)->writemode; return(*status); } /*--------------------------------------------------------------------------*/ void ffgerr(int status, /* I - error status value */ char *errtext) /* O - error message (max 30 char long + null) */ /* Return a short descriptive error message that corresponds to the input error status value. The message may be up to 30 characters long, plus the terminating null character. */ { errtext[0] = '\0'; if (status >= 0 && status < 300) { switch (status) { case 0: strcpy(errtext, "OK - no error"); break; case 1: strcpy(errtext, "non-CFITSIO program error"); break; case 101: strcpy(errtext, "same input and output files"); break; case 103: strcpy(errtext, "attempt to open too many files"); break; case 104: strcpy(errtext, "could not open the named file"); break; case 105: strcpy(errtext, "couldn't create the named file"); break; case 106: strcpy(errtext, "error writing to FITS file"); break; case 107: strcpy(errtext, "tried to move past end of file"); break; case 108: strcpy(errtext, "error reading from FITS file"); break; case 110: strcpy(errtext, "could not close the file"); break; case 111: strcpy(errtext, "array dimensions too big"); break; case 112: strcpy(errtext, "cannot write to readonly file"); break; case 113: strcpy(errtext, "could not allocate memory"); break; case 114: strcpy(errtext, "invalid fitsfile pointer"); break; case 115: strcpy(errtext, "NULL input pointer"); break; case 116: strcpy(errtext, "error seeking file position"); break; case 121: strcpy(errtext, "invalid URL prefix"); break; case 122: strcpy(errtext, "too many I/O drivers"); break; case 123: strcpy(errtext, "I/O driver init failed"); break; case 124: strcpy(errtext, "no I/O driver for this URLtype"); break; case 125: strcpy(errtext, "parse error in input file URL"); break; case 126: strcpy(errtext, "parse error in range list"); break; case 151: strcpy(errtext, "bad argument (shared mem drvr)"); break; case 152: strcpy(errtext, "null ptr arg (shared mem drvr)"); break; case 153: strcpy(errtext, "no free shared memory handles"); break; case 154: strcpy(errtext, "share mem drvr not initialized"); break; case 155: strcpy(errtext, "IPC system error (shared mem)"); break; case 156: strcpy(errtext, "no memory (shared mem drvr)"); break; case 157: strcpy(errtext, "share mem resource deadlock"); break; case 158: strcpy(errtext, "lock file open/create failed"); break; case 159: strcpy(errtext, "can't resize share mem block"); break; case 201: strcpy(errtext, "header already has keywords"); break; case 202: strcpy(errtext, "keyword not found in header"); break; case 203: strcpy(errtext, "keyword number out of bounds"); break; case 204: strcpy(errtext, "keyword value is undefined"); break; case 205: strcpy(errtext, "string missing closing quote"); break; case 206: strcpy(errtext, "error in indexed keyword name"); break; case 207: strcpy(errtext, "illegal character in keyword"); break; case 208: strcpy(errtext, "required keywords out of order"); break; case 209: strcpy(errtext, "keyword value not positive int"); break; case 210: strcpy(errtext, "END keyword not found"); break; case 211: strcpy(errtext, "illegal BITPIX keyword value"); break; case 212: strcpy(errtext, "illegal NAXIS keyword value"); break; case 213: strcpy(errtext, "illegal NAXISn keyword value"); break; case 214: strcpy(errtext, "illegal PCOUNT keyword value"); break; case 215: strcpy(errtext, "illegal GCOUNT keyword value"); break; case 216: strcpy(errtext, "illegal TFIELDS keyword value"); break; case 217: strcpy(errtext, "negative table row size"); break; case 218: strcpy(errtext, "negative number of rows"); break; case 219: strcpy(errtext, "named column not found"); break; case 220: strcpy(errtext, "illegal SIMPLE keyword value"); break; case 221: strcpy(errtext, "first keyword not SIMPLE"); break; case 222: strcpy(errtext, "second keyword not BITPIX"); break; case 223: strcpy(errtext, "third keyword not NAXIS"); break; case 224: strcpy(errtext, "missing NAXISn keywords"); break; case 225: strcpy(errtext, "first keyword not XTENSION"); break; case 226: strcpy(errtext, "CHDU not an ASCII table"); break; case 227: strcpy(errtext, "CHDU not a binary table"); break; case 228: strcpy(errtext, "PCOUNT keyword not found"); break; case 229: strcpy(errtext, "GCOUNT keyword not found"); break; case 230: strcpy(errtext, "TFIELDS keyword not found"); break; case 231: strcpy(errtext, "missing TBCOLn keyword"); break; case 232: strcpy(errtext, "missing TFORMn keyword"); break; case 233: strcpy(errtext, "CHDU not an IMAGE extension"); break; case 234: strcpy(errtext, "illegal TBCOLn keyword value"); break; case 235: strcpy(errtext, "CHDU not a table extension"); break; case 236: strcpy(errtext, "column exceeds width of table"); break; case 237: strcpy(errtext, "more than 1 matching col. name"); break; case 241: strcpy(errtext, "row width not = field widths"); break; case 251: strcpy(errtext, "unknown FITS extension type"); break; case 252: strcpy(errtext, "1st key not SIMPLE or XTENSION"); break; case 253: strcpy(errtext, "END keyword is not blank"); break; case 254: strcpy(errtext, "Header fill area not blank"); break; case 255: strcpy(errtext, "Data fill area invalid"); break; case 261: strcpy(errtext, "illegal TFORM format code"); break; case 262: strcpy(errtext, "unknown TFORM datatype code"); break; case 263: strcpy(errtext, "illegal TDIMn keyword value"); break; case 264: strcpy(errtext, "invalid BINTABLE heap pointer"); break; default: strcpy(errtext, "unknown error status"); break; } } else if (status < 600) { switch(status) { case 301: strcpy(errtext, "illegal HDU number"); break; case 302: strcpy(errtext, "column number < 1 or > tfields"); break; case 304: strcpy(errtext, "negative byte address"); break; case 306: strcpy(errtext, "negative number of elements"); break; case 307: strcpy(errtext, "bad first row number"); break; case 308: strcpy(errtext, "bad first element number"); break; case 309: strcpy(errtext, "not an ASCII (A) column"); break; case 310: strcpy(errtext, "not a logical (L) column"); break; case 311: strcpy(errtext, "bad ASCII table datatype"); break; case 312: strcpy(errtext, "bad binary table datatype"); break; case 314: strcpy(errtext, "null value not defined"); break; case 317: strcpy(errtext, "not a variable length column"); break; case 320: strcpy(errtext, "illegal number of dimensions"); break; case 321: strcpy(errtext, "1st pixel no. > last pixel no."); break; case 322: strcpy(errtext, "BSCALE or TSCALn = 0."); break; case 323: strcpy(errtext, "illegal axis length < 1"); break; case 340: strcpy(errtext, "not group table"); break; case 341: strcpy(errtext, "HDU already member of group"); break; case 342: strcpy(errtext, "group member not found"); break; case 343: strcpy(errtext, "group not found"); break; case 344: strcpy(errtext, "bad group id"); break; case 345: strcpy(errtext, "too many HDUs tracked"); break; case 346: strcpy(errtext, "HDU alread tracked"); break; case 347: strcpy(errtext, "bad Grouping option"); break; case 348: strcpy(errtext, "identical pointers (groups)"); break; case 360: strcpy(errtext, "malloc failed in parser"); break; case 361: strcpy(errtext, "file read error in parser"); break; case 362: strcpy(errtext, "null pointer arg (parser)"); break; case 363: strcpy(errtext, "empty line (parser)"); break; case 364: strcpy(errtext, "cannot unread > 1 line"); break; case 365: strcpy(errtext, "parser too deeply nested"); break; case 366: strcpy(errtext, "file open failed (parser)"); break; case 367: strcpy(errtext, "hit EOF (parser)"); break; case 368: strcpy(errtext, "bad argument (parser)"); break; case 369: strcpy(errtext, "unexpected token (parser)"); break; case 401: strcpy(errtext, "bad int to string conversion"); break; case 402: strcpy(errtext, "bad float to string conversion"); break; case 403: strcpy(errtext, "keyword value not integer"); break; case 404: strcpy(errtext, "keyword value not logical"); break; case 405: strcpy(errtext, "keyword value not floating pt"); break; case 406: strcpy(errtext, "keyword value not double"); break; case 407: strcpy(errtext, "bad string to int conversion"); break; case 408: strcpy(errtext, "bad string to float conversion"); break; case 409: strcpy(errtext, "bad string to double convert"); break; case 410: strcpy(errtext, "illegal datatype code value"); break; case 411: strcpy(errtext, "illegal no. of decimals"); break; case 412: strcpy(errtext, "datatype conversion overflow"); break; case 413: strcpy(errtext, "error compressing image"); break; case 414: strcpy(errtext, "error uncompressing image"); break; case 420: strcpy(errtext, "bad date or time conversion"); break; case 431: strcpy(errtext, "syntax error in expression"); break; case 432: strcpy(errtext, "expression result wrong type"); break; case 433: strcpy(errtext, "vector result too large"); break; case 434: strcpy(errtext, "missing output column"); break; case 435: strcpy(errtext, "bad data in parsed column"); break; case 436: strcpy(errtext, "output extension of wrong type"); break; case 501: strcpy(errtext, "WCS angle too large"); break; case 502: strcpy(errtext, "bad WCS coordinate"); break; case 503: strcpy(errtext, "error in WCS calculation"); break; case 504: strcpy(errtext, "bad WCS projection type"); break; case 505: strcpy(errtext, "WCS keywords not found"); break; default: strcpy(errtext, "unknown error status"); break; } } else { strcpy(errtext, "unknown error status"); } return; } /*--------------------------------------------------------------------------*/ void ffpmsg(const char *err_message) /* put message on to error stack */ { ffxmsg(PutMesg, (char *)err_message); return; } /*--------------------------------------------------------------------------*/ void ffpmrk(void) /* write a marker to the stack. It is then possible to pop only those messages following the marker off of the stack, leaving the previous messages unaffected. The marker is ignored by the ffgmsg routine. */ { char *dummy = 0; ffxmsg(PutMark, dummy); return; } /*--------------------------------------------------------------------------*/ int ffgmsg(char *err_message) /* get oldest message from error stack, ignoring markers */ { ffxmsg(GetMesg, err_message); return(*err_message); } /*--------------------------------------------------------------------------*/ void ffcmsg(void) /* erase all messages in the error stack */ { char *dummy = 0; ffxmsg(DelAll, dummy); return; } /*--------------------------------------------------------------------------*/ void ffcmrk(void) /* erase newest messages in the error stack, stopping if a marker is found. The marker is also erased in this case. */ { char *dummy = 0; ffxmsg(DelMark, dummy); return; } /*--------------------------------------------------------------------------*/ void ffxmsg( int action, char *errmsg) /* general routine to get, put, or clear the error message stack. Use a static array rather than allocating memory as needed for the error messages because it is likely to be more efficient and simpler to implement. Action Code: DelAll 1 delete all messages on the error stack DelMark 2 delete messages back to and including the 1st marker DelNewest 3 delete the newest message from the stack GetMesg 4 pop and return oldest message, ignoring marks PutMesg 5 add a new message to the stack PutMark 6 add a marker to the stack */ { int ii; char markflag; static char *txtbuff[errmsgsiz], *tmpbuff, *msgptr; static char errbuff[errmsgsiz][81]; /* initialize all = \0 */ static int nummsg = 0; if (action == DelAll) /* clear the whole message stack */ { for (ii = 0; ii < nummsg; ii ++) *txtbuff[ii] = '\0'; nummsg = 0; } else if (action == DelMark) /* clear up to and including first marker */ { while (nummsg > 0) { nummsg--; markflag = *txtbuff[nummsg]; /* store possible marker character */ *txtbuff[nummsg] = '\0'; /* clear the buffer for this msg */ if (markflag == ESMARKER) break; /* found a marker, so quit */ } } else if (action == DelNewest) /* remove newest message from stack */ { if (nummsg > 0) { nummsg--; *txtbuff[nummsg] = '\0'; /* clear the buffer for this msg */ } } else if (action == GetMesg) /* pop and return oldest message from stack */ { /* ignoring markers */ while (nummsg > 0) { strcpy(errmsg, txtbuff[0]); /* copy oldest message to output */ *txtbuff[0] = '\0'; /* clear the buffer for this msg */ nummsg--; for (ii = 0; ii < nummsg; ii++) txtbuff[ii] = txtbuff[ii + 1]; /* shift remaining pointers */ if (errmsg[0] != ESMARKER) /* quit if this is not a marker */ return; } errmsg[0] = '\0'; /* no messages in the stack */ } else if (action == PutMesg) /* add new message to stack */ { msgptr = errmsg; while (strlen(msgptr)) { if (nummsg == errmsgsiz) { tmpbuff = txtbuff[0]; /* buffers full; reuse oldest buffer */ *txtbuff[0] = '\0'; /* clear the buffer for this msg */ nummsg--; for (ii = 0; ii < nummsg; ii++) txtbuff[ii] = txtbuff[ii + 1]; /* shift remaining pointers */ txtbuff[nummsg] = tmpbuff; /* set pointer for the new message */ } else { for (ii = 0; ii < errmsgsiz; ii++) { if (*errbuff[ii] == '\0') /* find first empty buffer */ { txtbuff[nummsg] = errbuff[ii]; break; } } } strncat(txtbuff[nummsg], msgptr, 80); nummsg++; msgptr += minvalue(80, strlen(msgptr)); } } else if (action == PutMark) /* put a marker on the stack */ { if (nummsg == errmsgsiz) { tmpbuff = txtbuff[0]; /* buffers full; reuse oldest buffer */ *txtbuff[0] = '\0'; /* clear the buffer for this msg */ nummsg--; for (ii = 0; ii < nummsg; ii++) txtbuff[ii] = txtbuff[ii + 1]; /* shift remaining pointers */ txtbuff[nummsg] = tmpbuff; /* set pointer for the new message */ } else { for (ii = 0; ii < errmsgsiz; ii++) { if (*errbuff[ii] == '\0') /* find first empty buffer */ { txtbuff[nummsg] = errbuff[ii]; break; } } } *txtbuff[nummsg] = ESMARKER; /* write the marker */ *(txtbuff[nummsg] + 1) = '\0'; nummsg++; } return; } /*--------------------------------------------------------------------------*/ int ffpxsz(int datatype) /* return the number of bytes per pixel associated with the datatype */ { if (datatype == TBYTE) return(sizeof(char)); else if (datatype == TUSHORT) return(sizeof(short)); else if (datatype == TSHORT) return(sizeof(short)); else if (datatype == TULONG) return(sizeof(long)); else if (datatype == TLONG) return(sizeof(long)); else if (datatype == TINT) return(sizeof(int)); else if (datatype == TUINT) return(sizeof(int)); else if (datatype == TFLOAT) return(sizeof(float)); else if (datatype == TDOUBLE) return(sizeof(double)); else if (datatype == TLOGICAL) return(sizeof(char)); else return(0); } /*--------------------------------------------------------------------------*/ int fftkey(char *keyword, /* I - keyword name */ int *status) /* IO - error status */ /* Test that the keyword name conforms to the FITS standard. Must contain only capital letters, digits, minus or underscore chars. Trailing spaces are allowed. If the input status value is less than zero, then the test is modified so that upper or lower case letters are allowed, and no error messages are printed if the keyword is not legal. */ { size_t maxchr, ii; int spaces=0; char msg[81], testchar; if (*status > 0) /* inherit input status value if > 0 */ return(*status); maxchr=strlen(keyword); if (maxchr > 8) maxchr = 8; for (ii = 0; ii < maxchr; ii++) { if (*status == 0) testchar = keyword[ii]; else testchar = toupper(keyword[ii]); if ( (testchar >= 'A' && testchar <= 'Z') || (testchar >= '0' && testchar <= '9') || testchar == '-' || testchar == '_' ) { if (spaces) { if (*status == 0) { /* don't print error message if status < 0 */ sprintf(msg, "Keyword name contains embedded space(s): %.8s", keyword); ffpmsg(msg); } return(*status = BAD_KEYCHAR); } } else if (keyword[ii] == ' ') spaces = 1; else { if (*status == 0) { /* don't print error message if status < 0 */ sprintf(msg, "Character %d in this keyword is illegal: %.8s", (int) (ii+1), keyword); ffpmsg(msg); /* explicitly flag the 2 most common cases */ if (keyword[ii] == 0) ffpmsg(" (This a NULL (0) character)."); else if (keyword[ii] == 9) ffpmsg(" (This an ASCII TAB (9) character)."); } return(*status = BAD_KEYCHAR); } } return(*status); } /*--------------------------------------------------------------------------*/ int fftrec(char *card, /* I - keyword card to test */ int *status) /* IO - error status */ /* Test that the keyword card conforms to the FITS standard. Must contain only printable ASCII characters; */ { size_t ii, maxchr; char msg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); maxchr = strlen(card); for (ii = 8; ii < maxchr; ii++) { if (card[ii] < 32 || card[ii] > 126) { sprintf(msg, "Character %d in this keyword is illegal. Hex Value = %X", (int) (ii+1), (int) card[ii] ); ffpmsg(msg); strncpy(msg, card, 80); msg[80] = '\0'; ffpmsg(msg); return(*status = BAD_KEYCHAR); } } return(*status); } /*--------------------------------------------------------------------------*/ void ffupch(char *string) /* convert string to upper case, in place. */ { size_t len, ii; len = strlen(string); for (ii = 0; ii < len; ii++) string[ii] = toupper(string[ii]); return; } /*--------------------------------------------------------------------------*/ int ffmkky(char *keyname, /* I - keyword name */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ char *card, /* O - constructed keyword card */ int *status) /* IO - status value */ /* Make a complete FITS 80-byte keyword card from the input name, value and comment strings. Output card is null terminated without any trailing blanks. */ { size_t namelen, len, ii; char tmpname[FLEN_KEYWORD], *cptr; int tstatus = -1; if (*status > 0) return(*status); *tmpname = '\0'; *card = '\0'; cptr = keyname; while(*cptr == ' ') /* skip leading blanks in the name */ cptr++; strncat(tmpname, cptr, FLEN_KEYWORD - 1); namelen = strlen(tmpname); if (namelen) { cptr = tmpname + namelen - 1; while(*cptr == ' ') /* skip trailing blanks */ { *cptr = '\0'; cptr--; } namelen = cptr - tmpname + 1; } if (namelen <= 8 && (fftkey(keyname, &tstatus) <= 0) ) { /* a normal FITS keyword */ strcat(card, tmpname); /* copy keyword name to buffer */ for (ii = namelen; ii < 8; ii++) card[ii] = ' '; /* pad keyword name with spaces */ card[8] = '='; /* append '= ' in columns 9-10 */ card[9] = ' '; card[10] = '\0'; /* terminate the partial string */ namelen = 10; } else { /* use the ESO HIERARCH convention for longer keyword names */ /* check that the name does not contain an '=' (equals sign) */ if (strchr(tmpname, '=') ) { ffpmsg("Illegal keyword name; contains an equals sign (=)"); ffpmsg(tmpname); return(*status = BAD_KEYCHAR); } /* Don't repeat HIERARCH if the keyword already contains it */ if (FSTRNCMP(tmpname, "HIERARCH ", 9) && FSTRNCMP(tmpname, "hierarch ", 9)) strcat(card, "HIERARCH "); else namelen -= 9; /* deleted the string 'HIERARCH ' */ strcat(card, tmpname); strcat(card, " = "); namelen += 12; } len = strlen(value); if (len > 0) { if (value[0] == '\'') /* is this a quoted string value? */ { if (namelen > 77) { ffpmsg( "The following keyword + value is too long to fit on a card:"); ffpmsg(keyname); ffpmsg(value); return(*status = BAD_KEYCHAR); } strncat(card, value, 80 - namelen); /* append the value string */ len = minvalue(80, namelen + len); /* restore the closing quote if it got truncated */ if (len == 80) { card[79] = '\''; } if (comm) { if (comm[0] != 0) { if (len < 30) { for (ii = len; ii < 30; ii++) card[ii] = ' '; /* fill with spaces to col 30 */ card[30] = '\0'; len = 30; } } } } else { if (namelen + len > 80) { ffpmsg( "The following keyword + value is too long to fit on a card:"); ffpmsg(keyname); ffpmsg(value); return(*status = BAD_KEYCHAR); } else if (namelen + len < 30) { /* add spaces so field ends at least in col 30 */ strncat(card, " ", 30 - (namelen + len)); } strncat(card, value, 80 - namelen); /* append the value string */ len = minvalue(80, namelen + len); len = maxvalue(30, len); } if (comm) { if ((len < 77) && ( strlen(comm) > 0) ) /* room for a comment? */ { strcat(card, " / "); /* append comment separator */ strncat(card, comm, 77 - len); /* append comment (what fits) */ } } } else { if (namelen == 10) /* This case applies to normal keywords only */ { card[8] = ' '; /* keywords with no value have no '=' */ if (comm) { strncat(card, comm, 80 - namelen); /* append comment (what fits) */ } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffmkey(fitsfile *fptr, /* I - FITS file pointer */ char *card, /* I - card string value */ int *status) /* IO - error status */ /* replace the previously read card (i.e. starting 80 bytes before the (fptr->Fptr)->nextkey position) with the contents of the input card. */ { char tcard[81]; size_t len, ii; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); strncpy(tcard,card,80); tcard[80] = '\0'; len = strlen(tcard); for (ii=len; ii < 80; ii++) /* fill card with spaces if necessary */ tcard[ii] = ' '; for (ii=0; ii < 8; ii++) /* make sure keyword name is uppercase */ tcard[ii] = toupper(tcard[ii]); fftkey(tcard, status); /* test keyword name contains legal chars */ fftrec(tcard, status); /* test rest of keyword for legal chars */ /* move position of keyword to be over written */ ffmbyt(fptr, ((fptr->Fptr)->nextkey) - 80, REPORT_EOF, status); ffpbyt(fptr, 80, tcard, status); /* write the 80 byte card */ return(*status); } /*--------------------------------------------------------------------------*/ int ffkeyn(char *keyroot, /* I - root string for keyword name */ int value, /* I - index number to be appended to root name */ char *keyname, /* O - output root + index keyword name */ int *status) /* IO - error status */ /* Construct a keyword name string by appending the index number to the root. e.g., if root = "TTYPE" and value = 12 then keyname = "TTYPE12". */ { char suffix[16]; size_t rootlen; keyname[0] = '\0'; /* initialize output name to null */ rootlen = strlen(keyroot); if (rootlen == 0 || rootlen > 7 || value < 0 ) return(*status = 206); sprintf(suffix, "%d", value); /* construct keyword suffix */ if ( strlen(suffix) + rootlen > 8) return(*status = 206); strcpy(keyname, keyroot); /* copy root string to name string */ strcat(keyname, suffix); /* append suffix to the root */ return(*status); } /*--------------------------------------------------------------------------*/ int ffnkey(int value, /* I - index number to be appended to root name */ char *keyroot, /* I - root string for keyword name */ char *keyname, /* O - output root + index keyword name */ int *status) /* IO - error status */ /* Construct a keyword name string by appending the root string to the index number. e.g., if root = "TTYPE" and value = 12 then keyname = "12TTYPE". */ { size_t rootlen; keyname[0] = '\0'; /* initialize output name to null */ rootlen = strlen(keyroot); if (rootlen == 0 || rootlen > 7 || value < 0 ) return(*status = 206); sprintf(keyname, "%d", value); /* construct keyword prefix */ if (rootlen + strlen(keyname) > 8) return(*status = 206); strcat(keyname, keyroot); /* append root to the prefix */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpsvc(char *card, /* I - FITS header card (nominally 80 bytes long) */ char *value, /* O - value string parsed from the card */ char *comm, /* O - comment string parsed from the card */ int *status) /* IO - error status */ /* ParSe the Value and Comment strings from the input header card string. If the card contains a quoted string value, the returned value string includes the enclosing quote characters. If comm = NULL, don't return the comment string. */ { int jj; size_t ii, cardlen, nblank, valpos; if (*status > 0) return(*status); value[0] = '\0'; if (comm) comm[0] = '\0'; cardlen = strlen(card); /* support for ESO HIERARCH keywords; find the '=' */ if (FSTRNCMP(card, "HIERARCH ", 9) == 0) { valpos = strcspn(card, "="); if (valpos == cardlen) /* no value indicator ??? */ { if (comm != NULL) { if (cardlen > 8) { strcpy(comm, &card[8]); jj=cardlen - 8; for (jj--; jj >= 0; jj--) /* replace trailing blanks with nulls */ { if (comm[jj] == ' ') comm[jj] = '\0'; else break; } } } return(*status); /* no value indicator */ } valpos++; /* point to the position after the '=' */ } else if (cardlen < 9 || FSTRNCMP(card, "COMMENT ", 8) == 0 || /* keywords with no value */ FSTRNCMP(card, "HISTORY ", 8) == 0 || FSTRNCMP(card, "END ", 8) == 0 || FSTRNCMP(card, " ", 8) == 0 || FSTRNCMP(&card[8], "= ", 2) != 0 ) /* no '= ' in cols 9-10 */ { /* no value, so the comment extends from cols 9 - 80 */ if (comm != NULL) { if (cardlen > 8) { strcpy(comm, &card[8]); jj=cardlen - 8; for (jj--; jj >= 0; jj--) /* replace trailing blanks with nulls */ { if (comm[jj] == ' ') comm[jj] = '\0'; else break; } } } return(*status); } else { valpos = 10; /* starting position of the value field */ } nblank = strspn(&card[valpos], " "); /* find number of leading blanks */ if (nblank + valpos == cardlen) { /* the absence of a value string is legal, and simply indicates that the keyword value is undefined. Don't write an error message in this case. */ return(*status); } ii = valpos + nblank; if (card[ii] == '/' ) /* slash indicates start of the comment */ { ii++; } else if (card[ii] == '\'' ) /* is this a quoted string value? */ { value[0] = card[ii]; for (jj=1, ii++; ii < cardlen; ii++, jj++) { if (card[ii] == '\'') /* is this the closing quote? */ { if (card[ii+1] == '\'') /* 2 successive quotes? */ { value[jj] = card[ii]; ii++; jj++; } else { value[jj] = card[ii]; break; /* found the closing quote, so exit this loop */ } } value[jj] = card[ii]; /* copy the next character to the output */ } if (ii == cardlen) { value[jj] = '\0'; /* terminate the bad value string */ ffpmsg("This keyword string value has no closing quote:"); ffpmsg(card); return(*status = NO_QUOTE); } else { value[jj+1] = '\0'; /* terminate the good value string */ ii++; /* point to the character following the value */ } } else if (card[ii] == '(' ) /* is this a complex value? */ { nblank = strcspn(&card[ii], ")" ); /* find closing ) */ if (nblank == strlen( &card[ii] ) ) { ffpmsg("This complex keyword value has no closing ')':"); ffpmsg(card); return(*status = NO_QUOTE); } nblank++; strncpy(value, &card[ii], nblank); value[nblank] = '\0'; ii = ii + nblank; } else /* an integer, floating point, or logical FITS value string */ { nblank = strcspn(&card[ii], " /"); /* find the end of the token */ strncpy(value, &card[ii], nblank); value[nblank] = '\0'; ii = ii + nblank; } /* now find the comment string, if any */ if (comm) { nblank = strspn(&card[ii], " "); /* find next non-space character */ ii = ii + nblank; if (ii < 80) { if (card[ii] == '/') /* ignore the slash separator */ { ii++; if (card[ii] == ' ') /* also ignore the following space */ ii++; } strcat(comm, &card[ii]); /* copy the remaining characters */ jj=strlen(comm); for (jj--; jj >= 0; jj--) /* replace trailing blanks with nulls */ { if (comm[jj] == ' ') comm[jj] = '\0'; else break; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgthd(char *tmplt, /* I - input header template string */ char *card, /* O - returned FITS header record */ int *hdtype, /* O - how to interpreter the returned card string */ /* -2 = modify the name of a keyword; the old keyword name is returned starting at address chars[0]; the new name is returned starting at address char[40] (to be consistent with the Fortran version). Both names are null terminated. -1 = card contains the name of a keyword that is to be deleted 0 = append this keyword if it doesn't already exist, or modify the value if the keyword already exists. 1 = append this comment keyword ('HISTORY', 'COMMENT', or blank keyword name) 2 = this is the END keyword; do not write it to the header */ int *status) /* IO - error status */ /* 'Get Template HeaDer' parse a template header line and create a formated character string which is suitable for appending to a FITS header */ { char keyname[FLEN_KEYWORD], value[140], comment[140]; char *tok, *suffix, *loc, tvalue[140]; int len, vlen, more, tstatus; double dval; if (*status > 0) return(*status); card[0] = '\0'; *hdtype = 0; if (!FSTRNCMP(tmplt, " ", 8) ) { /* if first 8 chars of template are blank, then this is a comment */ strncat(card, tmplt, 80); *hdtype = 1; return(*status); } tok = tmplt; /* point to start of template string */ keyname[0] = '\0'; value[0] = '\0'; comment[0] = '\0'; len = strspn(tok, " "); /* no. of spaces before keyword */ tok += len; if (tok[0] == '-') /* is there a leading minus sign? */ { /* first token is name of keyword to be deleted or renamed */ *hdtype = -1; tok++; len = strspn(tok, " "); /* no. of spaces before keyword */ tok += len; if (len < 8) /* not a blank name? */ { len = strcspn(tok, " ="); /* length of name */ if (len >= FLEN_KEYWORD) return(*status = BAD_KEYCHAR); strncat(card, tok, len); /* The HIERARCH convention supports non-standard characters in the keyword name, so don't always convert to upper case or abort if there are illegal characters in the name or if the name is greater than 8 characters long. */ if (len < 9) /* this is possibly a normal FITS keyword name */ { ffupch(card); tstatus = 0; if (fftkey(card, &tstatus) > 0) { /* name contained non-standard characters, so reset */ card[0] = '\0'; strncat(card, tok, len); } } tok += len; } /* second token, if present, is the new name for the keyword */ len = strspn(tok, " "); /* no. of spaces before next token */ tok += len; if (tok[0] == '\0' || tok[0] == '=') return(*status); /* no second token */ *hdtype = -2; len = strcspn(tok, " "); /* length of new name */ if (len > 40) /* name has to fit on columns 41-80 of card */ return(*status = BAD_KEYCHAR); /* copy the new name to card + 40; This is awkward, */ /* but is consistent with the way the Fortran FITSIO works */ strcat(card," "); strncpy(&card[40], tok, len+1); /* copy len+1 to get terminator */ /* The HIERARCH convention supports non-standard characters in the keyword name, so don't always convert to upper case or abort if there are illegal characters in the name or if the name is greater than 8 characters long. */ if (len < 9) /* this is possibly a normal FITS keyword name */ { ffupch(&card[40]); tstatus = 0; if (fftkey(&card[40], &tstatus) > 0) { /* name contained non-standard characters, so reset */ strncpy(&card[40], tok, len); } } } else /* no negative sign at beginning of template */ { /* get the keyword name token */ len = strcspn(tok, " ="); /* length of keyword name */ if (len >= FLEN_KEYWORD) return(*status = BAD_KEYCHAR); strncat(keyname, tok, len); /* The HIERARCH convention supports non-standard characters in the keyword name, so don't always convert to upper case or abort if there are illegal characters in the name or if the name is greater than 8 characters long. */ if (len < 9) /* this is possibly a normal FITS keyword name */ { ffupch(keyname); tstatus = 0; if (fftkey(keyname, &tstatus) > 0) { /* name contained non-standard characters, so reset */ keyname[0] = '\0'; strncat(keyname, tok, len); } } if (!FSTRCMP(keyname, "END") ) { strcpy(card, "END"); *hdtype = 2; return(*status); } tok += len; /* move token pointer to end of the keyword */ if (!FSTRCMP(keyname, "COMMENT") || !FSTRCMP(keyname, "HISTORY") || !FSTRCMP(keyname, "HIERARCH") ) { *hdtype = 1; /* simply append COMMENT and HISTORY keywords */ strcpy(card, keyname); strncat(card, tok, 73); return(*status); } /* look for the value token */ len = strspn(tok, " ="); /* spaces or = between name and value */ tok += len; if (*tok == '\'') /* is value enclosed in quotes? */ { more = TRUE; while (more) { tok++; /* temporarily move past the quote char */ len = strcspn(tok, "'"); /* length of quoted string */ tok--; strncat(value, tok, len + 2); tok += len + 1; if (tok[0] != '\'') /* check there is a closing quote */ return(*status = NO_QUOTE); tok++; if (tok[0] != '\'') /* 2 quote chars = literal quote */ more = FALSE; } } else if (*tok == '/' || *tok == '\0') /* There is no value */ { strcat(value, " "); } else /* not a quoted string value */ { len = strcspn(tok, " /"); /* length of value string */ strncat(value, tok, len); if (!( (tok[0] == 'T' || tok[0] == 'F') && (tok[1] == ' ' || tok[1] == '/' || tok[1] == '\0') )) { /* not a logical value */ dval = strtod(value, &suffix); /* try to read value as number */ if (*suffix != '\0' && *suffix != ' ' && *suffix != '/') { /* value not recognized as a number; might be because it */ /* contains a 'd' or 'D' exponent character */ strcpy(tvalue, value); loc = strchr(tvalue, 'D'); if (loc) { *loc = 'E'; /* replace D's with E's. */ dval = strtod(tvalue, &suffix); /* read value again */ } else { loc = strchr(tvalue, 'd'); if (loc) { *loc = 'E'; /* replace d's with E's. */ dval = strtod(tvalue, &suffix); /* read value again */ } } } if (*suffix != '\0' && *suffix != ' ' && *suffix != '/') { /* value is not a number; must enclose it in quotes */ strcpy(value, "'"); strncat(value, tok, len); strcat(value, "'"); /* the following useless statement stops the compiler warning */ /* that dval is not used anywhere */ if (dval == 0.) len += (int) dval; } else { /* value is a number; convert any 'e' to 'E', or 'd' to 'D' */ loc = strchr(value, 'e'); if (loc) { *loc = 'E'; } else { loc = strchr(value, 'd'); if (loc) { *loc = 'D'; } } } } tok += len; } len = strspn(tok, " /"); /* no. of spaces between value and comment */ tok += len; vlen = strlen(value); if (vlen > 0 && vlen < 10 && value[0] == '\'') { /* pad quoted string with blanks so it is at least 8 chars long */ value[vlen-1] = '\0'; strncat(value, " ", 10 - vlen); strcat(&value[9], "'"); } /* get the comment string */ strncat(comment, tok, 70); /* construct the complete FITS header card */ ffmkky(keyname, value, comment, card, status); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_translate_keyword( char *inrec, /* I - input string */ char *outrec, /* O - output converted string, or */ /* a null string if input does not */ /* match any of the patterns */ char *patterns[][2],/* I - pointer to input / output string */ /* templates */ int npat, /* I - number of templates passed */ int n_value, /* I - base 'n' template value of interest */ int n_offset, /* I - offset to be applied to the 'n' */ /* value in the output string */ int n_range, /* I - controls range of 'n' template */ /* values of interest (-1,0, or +1) */ int *pat_num, /* O - matched pattern number (0 based) or -1 */ int *i, /* O - value of i, if any, else 0 */ int *j, /* O - value of j, if any, else 0 */ int *m, /* O - value of m, if any, else 0 */ int *n, /* O - value of n, if any, else 0 */ int *status) /* IO - error status */ /* Translate a keyword name to a new name, based on a set of patterns. The user passes an array of patterns to be matched. Input pattern number i is pattern[i][0], and output pattern number i is pattern[i][1]. Keywords are matched against the input patterns. If a match is found then the keyword is re-written according to the output pattern. Order is important. The first match is accepted. The fastest match will be made when templates with the same first character are grouped together. Several characters have special meanings: i,j - single digits, preserved in output template n - column number of one or more digits, preserved in output template m - generic number of one or more digits, preserved in output template a - coordinate designator, preserved in output template # - number of one or more digits ? - any character * - only allowed in first character position, to match all keywords; only useful as last pattern in the list i, j, n, and m are returned by the routine. For example, the input pattern "iCTYPn" will match "1CTYP5" (if n_value is 5); the output pattern "CTYPEi" will be re-written as "CTYPE1". Notice that "i" is preserved. The following output patterns are special Special output pattern characters: "-" - do not copy a keyword that matches the corresponding input pattern "+" - copy the input unchanged The inrec string could be just the 8-char keyword name, or the entire 80-char header record. Characters 9 = 80 in the input string simply get appended to the translated keyword name. If n_range = 0, then only keywords with 'n' equal to n_value will be considered as a pattern match. If n_range = +1, then all values of 'n' greater than or equal to n_value will be a match, and if -1, then values of 'n' less than or equal to n_value will match. This routine was written by Craig Markwardt, GSFC */ { int i1 = 0, j1 = 0, n1 = 0, m1 = 0; int fac; char a = ' '; char oldp = ' '; char c, s; int ip, ic, pat, pass = 0, firstfail = 0; char *spat; if (*status > 0) return(*status); if ((inrec == 0) || (outrec == 0)) return (*status = NULL_INPUT_PTR); *outrec = '\0'; if (*inrec == '\0') return 0; oldp = '\0'; firstfail = 0; /* ===== Pattern match stage */ for (pat=0; pat < npat; pat++) { spat = patterns[pat][0]; i1 = 0; j1 = 0; m1 = -1; n1 = -1; a = ' '; /* Initialize the place-holders */ pass = 0; /* Pass the wildcard pattern */ if (spat[0] == '*') { pass = 1; break; } /* Optimization: if we have seen this initial pattern character before, then it must have failed, and we can skip the pattern */ if (firstfail && spat[0] == oldp) continue; oldp = spat[0]; /* ip = index of pattern character being matched ic = index of keyname character being matched firstfail = 1 if we fail on the first characteor (0=not) */ for (ip=0, ic=0, firstfail=1; (spat[ip]) && (ic < 8); ip++, ic++, firstfail=0) { c = inrec[ic]; s = spat[ip]; if (s == 'i') { /* Special pattern: 'i' placeholder */ if (isdigit(c)) { i1 = c - '0'; pass = 1;} } else if (s == 'j') { /* Special pattern: 'j' placeholder */ if (isdigit(c)) { j1 = c - '0'; pass = 1;} } else if ((s == 'n')||(s == 'm')||(s == '#')) { /* Special patterns: multi-digit number */ int val = 0; pass = 0; if (isdigit(c)) { pass = 1; /* NOTE, could fail below */ /* Parse decimal number */ while (ic<8 && isdigit(c)) { val = val*10 + (c - '0'); ic++; c = inrec[ic]; } ic--; c = inrec[ic]; if (s == 'n') { /* Is it a column number? */ if ( val >= 1 && val <= 999 && /* Row range check */ (((n_range == 0) && (val == n_value)) || /* Strict equality */ ((n_range == -1) && (val <= n_value)) || /* n <= n_value */ ((n_range == +1) && (val >= n_value))) ) { /* n >= n_value */ n1 = val; } else { pass = 0; } } else if (s == 'm') { /* Generic number */ m1 = val; } } } else if (s == 'a') { /* Special pattern: coordinate designator */ if (isupper(c) || c == ' ') { a = c; pass = 1;} } else if (s == '?') { /* Match any individual character */ pass = 1; } else if (c == s) { /* Match a specific character */ pass = 1; } else { /* FAIL */ pass = 0; } if (!pass) break; } /* Must pass to the end of the keyword. No partial matches allowed */ if (pass && (ic >= 8 || inrec[ic] == ' ')) break; } /* Transfer the pattern-matched numbers to the output parameters */ if (i) { *i = i1; } if (j) { *j = j1; } if (n) { *n = n1; } if (m) { *m = m1; } if (pat_num) { *pat_num = pat; } /* ===== Keyword rewriting and output stage */ spat = patterns[pat][1]; /* Return case: no match, or explicit deletion pattern */ if (pass == 0 || spat[0] == '\0' || spat[0] == '-') return 0; /* A match: we start by copying the input record to the output */ strcpy(outrec, inrec); /* Return case: return the input record unchanged */ if (spat[0] == '+') return 0; /* Final case: a new output pattern */ for (ip=0, ic=0; spat[ip]; ip++, ic++) { s = spat[ip]; if (s == 'i') { outrec[ic] = (i1+'0'); } else if (s == 'j') { outrec[ic] = (j1+'0'); } else if (s == 'n') { if (n1 == -1) { n1 = n_value; } if (n1 > 0) { n1 += n_offset; for (fac = 1; (n1/fac) > 0; fac *= 10); fac /= 10; while(fac > 0) { outrec[ic] = ((n1/fac) % 10) + '0'; fac /= 10; ic ++; } ic--; } } else if (s == 'm' && m1 >= 0) { for (fac = 1; (m1/fac) > 0; fac *= 10); fac /= 10; while(fac > 0) { outrec[ic] = ((m1/fac) % 10) + '0'; fac /= 10; ic ++; } ic --; } else if (s == 'a') { outrec[ic] = a; } else { outrec[ic] = s; } } /* Pad the keyword name with spaces */ for ( ; ic<8; ic++) { outrec[ic] = ' '; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_translate_keywords( fitsfile *infptr, /* I - pointer to input HDU */ fitsfile *outfptr, /* I - pointer to output HDU */ int firstkey, /* I - first HDU record number to start with */ char *patterns[][2],/* I - pointer to input / output keyword templates */ int npat, /* I - number of templates passed */ int n_value, /* I - base 'n' template value of interest */ int n_offset, /* I - offset to be applied to the 'n' */ /* value in the output string */ int n_range, /* I - controls range of 'n' template */ /* values of interest (-1,0, or +1) */ int *status) /* IO - error status */ /* Copy relevant keywords from the table header into the newly created primary array header. Convert names of keywords where appropriate. See fits_translate_keyword() for the definitions. Translation begins at header record number 'firstkey', and continues to the end of the header. This routine was written by Craig Markwardt, GSFC */ { int nrec, nkeys, nmore; char rec[FLEN_CARD]; int i = 0, j = 0, n = 0, m = 0; int pat_num = 0; char outrec[FLEN_CARD]; if (*status > 0) return(*status); ffghsp(infptr, &nkeys, &nmore, status); /* get number of keywords */ for (nrec = firstkey; nrec <= nkeys; nrec++) { outrec[0] = '\0'; ffgrec(infptr, nrec, rec, status); fits_translate_keyword(rec, outrec, patterns, npat, n_value, n_offset, n_range, &pat_num, &i, &j, &m, &n, status); if (outrec[0]) { ffprec(outfptr, outrec, status); /* copy the keyword */ rec[8] = 0; outrec[8] = 0; } else { rec[8] = 0; outrec[8] = 0; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffasfm(char *tform, /* I - format code from the TFORMn keyword */ int *dtcode, /* O - numerical datatype code */ long *twidth, /* O - width of the field, in chars */ int *decimals, /* O - number of decimal places (F, E, D format) */ int *status) /* IO - error status */ { /* parse the ASCII table TFORM column format to determine the data type, the field width, and number of decimal places (if relevant) */ int ii, datacode; long longval, width; float fwidth; char *form, temp[FLEN_VALUE], message[FLEN_ERRMSG]; if (*status > 0) return(*status); if (dtcode) *dtcode = 0; if (twidth) *twidth = 0; if (decimals) *decimals = 0; ii = 0; while (tform[ii] != 0 && tform[ii] == ' ') /* find first non-blank char */ ii++; strcpy(temp, &tform[ii]); /* copy format string */ ffupch(temp); /* make sure it is in upper case */ form = temp; /* point to start of format string */ if (form[0] == 0) { ffpmsg("Error: ASCII table TFORM code is blank"); return(*status = BAD_TFORM); } /*-----------------------------------------------*/ /* determine default datatype code */ /*-----------------------------------------------*/ if (form[0] == 'A') datacode = TSTRING; else if (form[0] == 'I') datacode = TLONG; else if (form[0] == 'F') datacode = TFLOAT; else if (form[0] == 'E') datacode = TFLOAT; else if (form[0] == 'D') datacode = TDOUBLE; else { sprintf(message, "Illegal ASCII table TFORMn datatype: \'%s\'", tform); ffpmsg(message); return(*status = BAD_TFORM_DTYPE); } if (dtcode) *dtcode = datacode; form++; /* point to the start of field width */ if (datacode == TSTRING || datacode == TLONG) { /*-----------------------------------------------*/ /* A or I data formats: */ /*-----------------------------------------------*/ if (ffc2ii(form, &width, status) <= 0) /* read the width field */ { if (width <= 0) { width = 0; *status = BAD_TFORM; } else { /* set to shorter precision if I4 or less */ if (width <= 4 && datacode == TLONG) datacode = TSHORT; } } } else { /*-----------------------------------------------*/ /* F, E or D data formats: */ /*-----------------------------------------------*/ if (ffc2rr(form, &fwidth, status) <= 0) /* read ww.dd width field */ { if (fwidth <= 0.) *status = BAD_TFORM; else { width = (long) fwidth; /* convert from float to long */ if (width > 7 && *temp == 'F') datacode = TDOUBLE; /* type double if >7 digits */ if (width < 10) form = form + 1; /* skip 1 digit */ else form = form + 2; /* skip 2 digits */ if (form[0] == '.') /* should be a decimal point here */ { form++; /* point to start of decimals field */ if (ffc2ii(form, &longval, status) <= 0) /* read decimals */ { if (decimals) *decimals = longval; /* long to short convertion */ if (longval >= width) /* width < no. of decimals */ *status = BAD_TFORM; if (longval > 6 && *temp == 'E') datacode = TDOUBLE; /* type double if >6 digits */ } } } } } if (*status > 0) { *status = BAD_TFORM; sprintf(message,"Illegal ASCII table TFORMn code: \'%s\'", tform); ffpmsg(message); } if (dtcode) *dtcode = datacode; if (twidth) *twidth = width; return(*status); } /*--------------------------------------------------------------------------*/ int ffbnfm(char *tform, /* I - format code from the TFORMn keyword */ int *dtcode, /* O - numerical datatype code */ long *trepeat, /* O - repeat count of the field */ long *twidth, /* O - width of the field, in chars */ int *status) /* IO - error status */ { /* parse the binary table TFORM column format to determine the data type, repeat count, and the field width (if it is an ASCII (A) field) */ size_t ii, nchar; int datacode, variable, iread; long width, repeat; char *form, temp[FLEN_VALUE], message[FLEN_ERRMSG]; if (*status > 0) return(*status); if (dtcode) *dtcode = 0; if (trepeat) *trepeat = 0; if (twidth) *twidth = 0; nchar = strlen(tform); for (ii = 0; ii < nchar; ii++) { if (tform[ii] != ' ') /* find first non-space char */ break; } if (ii == nchar) { ffpmsg("Error: binary table TFORM code is blank (ffbnfm)."); return(*status = BAD_TFORM); } strcpy(temp, &tform[ii]); /* copy format string */ ffupch(temp); /* make sure it is in upper case */ form = temp; /* point to start of format string */ /*-----------------------------------------------*/ /* get the repeat count */ /*-----------------------------------------------*/ ii = 0; while(isdigit((int) form[ii])) ii++; /* look for leading digits in the field */ if (ii == 0) repeat = 1; /* no explicit repeat count */ else sscanf(form,"%ld", &repeat); /* read repeat count */ /*-----------------------------------------------*/ /* determine datatype code */ /*-----------------------------------------------*/ form = form + ii; /* skip over the repeat field */ if (form[0] == 'P' || form[0] == 'Q') { variable = 1; /* this is a variable length column */ repeat = 1; /* disregard any other repeat value */ form++; /* move to the next data type code char */ } else variable = 0; if (form[0] == 'U') /* internal code to signify unsigned integer */ { datacode = TUSHORT; width = 2; } else if (form[0] == 'I') { datacode = TSHORT; width = 2; } else if (form[0] == 'V') /* internal code to signify unsigned integer */ { datacode = TULONG; width = 4; } else if (form[0] == 'J') { datacode = TLONG; width = 4; } else if (form[0] == 'K') { datacode = TLONGLONG; width = 8; } else if (form[0] == 'E') { datacode = TFLOAT; width = 4; } else if (form[0] == 'D') { datacode = TDOUBLE; width = 8; } else if (form[0] == 'A') { datacode = TSTRING; /* the following code is used to support the non-standard datatype of the form rAw where r = total width of the field and w = width of fixed-length substrings within the field. */ iread = 0; if (form[1] != 0) { if (form[1] == '(' ) /* skip parenthesis around */ form++; /* variable length column width */ iread = sscanf(&form[1],"%ld", &width); } if (iread != 1 || (!variable && (width > repeat)) ) width = repeat; } else if (form[0] == 'L') { datacode = TLOGICAL; width = 1; } else if (form[0] == 'X') { datacode = TBIT; width = 1; } else if (form[0] == 'B') { datacode = TBYTE; width = 1; } else if (form[0] == 'S') /* internal code to signify signed byte */ { datacode = TSBYTE; width = 1; } else if (form[0] == 'C') { datacode = TCOMPLEX; width = 8; } else if (form[0] == 'M') { datacode = TDBLCOMPLEX; width = 16; } else { sprintf(message, "Illegal binary table TFORMn datatype: \'%s\' ", tform); ffpmsg(message); return(*status = BAD_TFORM_DTYPE); } if (variable) datacode = datacode * (-1); /* flag variable cols w/ neg type code */ if (dtcode) *dtcode = datacode; if (trepeat) *trepeat = repeat; if (twidth) *twidth = width; return(*status); } /*--------------------------------------------------------------------------*/ int ffbnfmll(char *tform, /* I - format code from the TFORMn keyword */ int *dtcode, /* O - numerical datatype code */ LONGLONG *trepeat, /* O - repeat count of the field */ long *twidth, /* O - width of the field, in chars */ int *status) /* IO - error status */ { /* parse the binary table TFORM column format to determine the data type, repeat count, and the field width (if it is an ASCII (A) field) */ size_t ii, nchar; int datacode, variable, iread; long width; LONGLONG repeat; char *form, temp[FLEN_VALUE], message[FLEN_ERRMSG]; double drepeat; if (*status > 0) return(*status); if (dtcode) *dtcode = 0; if (trepeat) *trepeat = 0; if (twidth) *twidth = 0; nchar = strlen(tform); for (ii = 0; ii < nchar; ii++) { if (tform[ii] != ' ') /* find first non-space char */ break; } if (ii == nchar) { ffpmsg("Error: binary table TFORM code is blank (ffbnfm)."); return(*status = BAD_TFORM); } strcpy(temp, &tform[ii]); /* copy format string */ ffupch(temp); /* make sure it is in upper case */ form = temp; /* point to start of format string */ /*-----------------------------------------------*/ /* get the repeat count */ /*-----------------------------------------------*/ ii = 0; while(isdigit((int) form[ii])) ii++; /* look for leading digits in the field */ if (ii == 0) repeat = 1; /* no explicit repeat count */ else { /* read repeat count */ /* print as double, because the string-to-64-bit int conversion */ /* character is platform dependent (%lld, %ld, %I64d) */ sscanf(form,"%lf", &drepeat); repeat = (LONGLONG) (drepeat + 0.1); } /*-----------------------------------------------*/ /* determine datatype code */ /*-----------------------------------------------*/ form = form + ii; /* skip over the repeat field */ if (form[0] == 'P' || form[0] == 'Q') { variable = 1; /* this is a variable length column */ repeat = 1; /* disregard any other repeat value */ form++; /* move to the next data type code char */ } else variable = 0; if (form[0] == 'U') /* internal code to signify unsigned integer */ { datacode = TUSHORT; width = 2; } else if (form[0] == 'I') { datacode = TSHORT; width = 2; } else if (form[0] == 'V') /* internal code to signify unsigned integer */ { datacode = TULONG; width = 4; } else if (form[0] == 'J') { datacode = TLONG; width = 4; } else if (form[0] == 'K') { datacode = TLONGLONG; width = 8; } else if (form[0] == 'E') { datacode = TFLOAT; width = 4; } else if (form[0] == 'D') { datacode = TDOUBLE; width = 8; } else if (form[0] == 'A') { datacode = TSTRING; /* the following code is used to support the non-standard datatype of the form rAw where r = total width of the field and w = width of fixed-length substrings within the field. */ iread = 0; if (form[1] != 0) { if (form[1] == '(' ) /* skip parenthesis around */ form++; /* variable length column width */ iread = sscanf(&form[1],"%ld", &width); } if (iread != 1 || (!variable && (width > repeat)) ) width = (long) repeat; } else if (form[0] == 'L') { datacode = TLOGICAL; width = 1; } else if (form[0] == 'X') { datacode = TBIT; width = 1; } else if (form[0] == 'B') { datacode = TBYTE; width = 1; } else if (form[0] == 'S') /* internal code to signify signed byte */ { datacode = TSBYTE; width = 1; } else if (form[0] == 'C') { datacode = TCOMPLEX; width = 8; } else if (form[0] == 'M') { datacode = TDBLCOMPLEX; width = 16; } else { sprintf(message, "Illegal binary table TFORMn datatype: \'%s\' ", tform); ffpmsg(message); return(*status = BAD_TFORM_DTYPE); } if (variable) datacode = datacode * (-1); /* flag variable cols w/ neg type code */ if (dtcode) *dtcode = datacode; if (trepeat) *trepeat = repeat; if (twidth) *twidth = width; return(*status); } /*--------------------------------------------------------------------------*/ void ffcfmt(char *tform, /* value of an ASCII table TFORMn keyword */ char *cform) /* equivalent format code in C language syntax */ /* convert the FITS format string for an ASCII Table extension column into the equivalent C format string that can be used in a printf statement, after the values have been read as a double. */ { int ii; cform[0] = '\0'; ii = 0; while (tform[ii] != 0 && tform[ii] == ' ') /* find first non-blank char */ ii++; if (tform[ii] == 0) return; /* input format string was blank */ cform[0] = '%'; /* start the format string */ strcpy(&cform[1], &tform[ii + 1]); /* append the width and decimal code */ if (tform[ii] == 'A') strcat(cform, "s"); else if (tform[ii] == 'I') strcat(cform, ".0f"); /* 0 precision to suppress decimal point */ if (tform[ii] == 'F') strcat(cform, "f"); if (tform[ii] == 'E') strcat(cform, "E"); if (tform[ii] == 'D') strcat(cform, "E"); return; } /*--------------------------------------------------------------------------*/ void ffcdsp(char *tform, /* value of an ASCII table TFORMn keyword */ char *cform) /* equivalent format code in C language syntax */ /* convert the FITS TDISPn display format into the equivalent C format suitable for use in a printf statement. */ { int ii; cform[0] = '\0'; ii = 0; while (tform[ii] != 0 && tform[ii] == ' ') /* find first non-blank char */ ii++; if (tform[ii] == 0) { cform[0] = '\0'; return; /* input format string was blank */ } cform[0] = '%'; /* start the format string */ strcpy(&cform[1], &tform[ii + 1]); /* append the width and decimal code */ if (tform[ii] == 'A' || tform[ii] == 'a') strcat(cform, "s"); else if (tform[ii] == 'I' || tform[ii] == 'i') strcat(cform, "d"); else if (tform[ii] == 'O' || tform[ii] == 'o') strcat(cform, "o"); else if (tform[ii] == 'Z' || tform[ii] == 'z') strcat(cform, "X"); else if (tform[ii] == 'F' || tform[ii] == 'f') strcat(cform, "f"); else if (tform[ii] == 'E' || tform[ii] == 'e') strcat(cform, "E"); else if (tform[ii] == 'D' || tform[ii] == 'd') strcat(cform, "E"); else if (tform[ii] == 'G' || tform[ii] == 'g') strcat(cform, "G"); else cform[0] = '\0'; /* unrecognized tform code */ return; } /*--------------------------------------------------------------------------*/ int ffgcno( fitsfile *fptr, /* I - FITS file pionter */ int casesen, /* I - case sensitive string comparison? 0=no */ char *templt, /* I - input name of column (w/wildcards) */ int *colnum, /* O - number of the named column; 1=first col */ int *status) /* IO - error status */ /* Determine the column number corresponding to an input column name. The first column of the table = column 1; This supports the * and ? wild cards in the input template. */ { char colname[FLEN_VALUE]; /* temporary string to hold column name */ ffgcnn(fptr, casesen, templt, colname, colnum, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcnn( fitsfile *fptr, /* I - FITS file pointer */ int casesen, /* I - case sensitive string comparison? 0=no */ char *templt, /* I - input name of column (w/wildcards) */ char *colname, /* O - full column name up to 68 + 1 chars long*/ int *colnum, /* O - number of the named column; 1=first col */ int *status) /* IO - error status */ /* Return the full column name and column number of the next column whose TTYPEn keyword value matches the input template string. The template may contain the * and ? wildcards. Status = 237 is returned if the match is not unique. If so, one may call this routine again with input status=237 to get the next match. A status value of 219 is returned when there are no more matching columns. */ { char errmsg[FLEN_ERRMSG]; static int startcol; int tstatus, ii, founde, foundw, match, exact, unique; long ivalue; tcolumn *colptr; if (*status <= 0) { startcol = 0; /* start search with first column */ tstatus = 0; } else if (*status == COL_NOT_UNIQUE) /* start search from previous spot */ { tstatus = COL_NOT_UNIQUE; *status = 0; } else return(*status); /* bad input status value */ colname[0] = 0; /* initialize null return */ *colnum = 0; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header to get col struct */ return(*status); colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (startcol); /* offset to starting column */ founde = FALSE; /* initialize 'found exact match' flag */ foundw = FALSE; /* initialize 'found wildcard match' flag */ unique = FALSE; for (ii = startcol; ii < (fptr->Fptr)->tfield; ii++, colptr++) { ffcmps(templt, colptr->ttype, casesen, &match, &exact); if (match) { if (founde && exact) { /* warning: this is the second exact match we've found */ /*reset pointer to first match so next search starts there */ startcol = *colnum; return(*status = COL_NOT_UNIQUE); } else if (founde) /* a wildcard match */ { /* already found exact match so ignore this non-exact match */ } else if (exact) { /* this is the first exact match we have found, so save it. */ strcpy(colname, colptr->ttype); *colnum = ii + 1; founde = TRUE; } else if (foundw) { /* we have already found a wild card match, so not unique */ /* continue searching for other matches */ unique = FALSE; } else { /* this is the first wild card match we've found. save it */ strcpy(colname, colptr->ttype); *colnum = ii + 1; startcol = *colnum; foundw = TRUE; unique = TRUE; } } } /* OK, we've checked all the names now see if we got any matches */ if (founde) { if (tstatus == COL_NOT_UNIQUE) /* we did find 1 exact match but */ *status = COL_NOT_UNIQUE; /* there was a previous match too */ } else if (foundw) { /* found one or more wildcard matches; report error if not unique */ if (!unique || tstatus == COL_NOT_UNIQUE) *status = COL_NOT_UNIQUE; } else { /* didn't find a match; check if template is a positive integer */ ffc2ii(templt, &ivalue, &tstatus); if (tstatus == 0 && ivalue <= (fptr->Fptr)->tfield && ivalue > 0) { *colnum = ivalue; colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (ivalue - 1); /* offset to correct column */ strcpy(colname, colptr->ttype); } else { *status = COL_NOT_FOUND; if (tstatus != COL_NOT_UNIQUE) { sprintf(errmsg, "ffgcnn could not find column: %.45s", templt); ffpmsg(errmsg); } } } startcol = *colnum; /* save pointer for next time */ return(*status); } /*--------------------------------------------------------------------------*/ void ffcmps(char *templt, /* I - input template (may have wildcards) */ char *colname, /* I - full column name up to 68 + 1 chars long */ int casesen, /* I - case sensitive string comparison? 1=yes */ int *match, /* O - do template and colname match? 1=yes */ int *exact) /* O - do strings exactly match, or wildcards */ /* compare the template to the string and test if they match. The strings are limited to 68 characters or less (the max. length of a FITS string keyword value. This routine reports whether the two strings match and whether the match is exact or involves wildcards. This algorithm is very similar to the way unix filename wildcards work except that this first treats a wild card as a literal character when looking for a match. If there is no literal match, then it interpretes it as a wild card. So the template 'AB*DE' is considered to be an exact rather than a wild card match to the string 'AB*DE'. The '#' wild card in the template string will match any consecutive string of decimal digits in the colname. */ { int ii, found, t1, s1, wildsearch = 0, tsave = 0, ssave = 0; char temp[FLEN_VALUE], col[FLEN_VALUE]; *match = FALSE; *exact = TRUE; strncpy(temp, templt, FLEN_VALUE); /* copy strings to work area */ strncpy(col, colname, FLEN_VALUE); temp[FLEN_VALUE - 1] = '\0'; /* make sure strings are terminated */ col[FLEN_VALUE - 1] = '\0'; /* truncate trailing non-significant blanks */ for (ii = strlen(temp) - 1; ii >= 0 && temp[ii] == ' '; ii--) temp[ii] = '\0'; for (ii = strlen(col) - 1; ii >= 0 && col[ii] == ' '; ii--) col[ii] = '\0'; if (!casesen) { /* convert both strings to uppercase before comparison */ ffupch(temp); ffupch(col); } if (!FSTRCMP(temp, col) ) { *match = TRUE; /* strings exactly match */ return; } *exact = FALSE; /* strings don't exactly match */ t1 = 0; /* start comparison with 1st char of each string */ s1 = 0; while(1) /* compare corresponding chars in each string */ { if (temp[t1] == '\0' && col[s1] == '\0') { /* completely scanned both strings so they match */ *match = TRUE; return; } else if (temp[t1] == '\0') { if (wildsearch) { /* the previous wildcard search may have been going down a blind alley. Backtrack, and resume the wildcard search with the next character in the string. */ t1 = tsave; s1 = ssave + 1; } else { /* reached end of template string so they don't match */ return; } } else if (col[s1] == '\0') { /* reached end of other string; they match if the next */ /* character in the template string is a '*' wild card */ if (temp[t1] == '*' && temp[t1 + 1] == '\0') { *match = TRUE; } return; } if (temp[t1] == col[s1] || (temp[t1] == '?') ) { s1++; /* corresponding chars in the 2 strings match */ t1++; /* increment both pointers and loop back again */ } else if (temp[t1] == '#' && isdigit((int) col[s1]) ) { s1++; /* corresponding chars in the 2 strings match */ t1++; /* increment both pointers */ /* find the end of the string of digits */ while (isdigit((int) col[s1]) ) s1++; } else if (temp[t1] == '*') { /* save current string locations, in case we need to restart */ wildsearch = 1; tsave = t1; ssave = s1; /* get next char from template and look for it in the col name */ t1++; if (temp[t1] == '\0' || temp[t1] == ' ') { /* reached end of template so strings match */ *match = TRUE; return; } found = FALSE; while (col[s1] && !found) { if (temp[t1] == col[s1]) { t1++; /* found matching characters; incre both pointers */ s1++; /* and loop back to compare next chars */ found = TRUE; } else s1++; /* increment the column name pointer and try again */ } if (!found) { return; /* hit end of column name and failed to find a match */ } } else { if (wildsearch) { /* the previous wildcard search may have been going down a blind alley. Backtrack, and resume the wildcard search with the next character in the string. */ t1 = tsave; s1 = ssave + 1; } else { return; /* strings don't match */ } } } } /*--------------------------------------------------------------------------*/ int ffgtcl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int *typecode, /* O - datatype code (21 = short, etc) */ long *repeat, /* O - repeat count of field */ long *width, /* O - if ASCII, width of field or unit string */ int *status) /* IO - error status */ /* Get Type of table column. Returns the datatype code of the column, as well as the vector repeat count and (if it is an ASCII character column) the width of the field or a unit string within the field. This supports the TFORMn = 'rAw' syntax for specifying arrays of substrings, so if TFORMn = '60A12' then repeat = 60 and width = 12. */ { LONGLONG trepeat, twidth; ffgtclll(fptr, colnum, typecode, &trepeat, &twidth, status); if (*status > 0) return(*status); if (repeat) *repeat= (long) trepeat; if (width) *width = (long) twidth; return(*status); } /*--------------------------------------------------------------------------*/ int ffgtclll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int *typecode, /* O - datatype code (21 = short, etc) */ LONGLONG *repeat, /* O - repeat count of field */ LONGLONG *width, /* O - if ASCII, width of field or unit string */ int *status) /* IO - error status */ /* Get Type of table column. Returns the datatype code of the column, as well as the vector repeat count and (if it is an ASCII character column) the width of the field or a unit string within the field. This supports the TFORMn = 'rAw' syntax for specifying arrays of substrings, so if TFORMn = '60A12' then repeat = 60 and width = 12. */ { tcolumn *colptr; int hdutype, decims; long tmpwidth; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (colnum - 1); /* offset to correct column */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == ASCII_TBL) { ffasfm(colptr->tform, typecode, &tmpwidth, &decims, status); *width = tmpwidth; if (repeat) *repeat = 1; } else { if (typecode) *typecode = colptr->tdatatype; if (width) *width = colptr->twidth; if (repeat) *repeat = colptr->trepeat; } return(*status); } /*--------------------------------------------------------------------------*/ int ffeqty( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int *typecode, /* O - datatype code (21 = short, etc) */ long *repeat, /* O - repeat count of field */ long *width, /* O - if ASCII, width of field or unit string */ int *status) /* IO - error status */ /* Get the 'equivalent' table column type. This routine is similar to the ffgtcl routine (which returns the physical datatype of the column, as stored in the FITS file) except that if the TSCALn and TZEROn keywords are defined for the column, then it returns the 'equivalent' datatype. Thus, if the column is defined as '1I' (short integer) this routine may return the type as 'TUSHORT' or as 'TFLOAT' depending on the TSCALn and TZEROn values. Returns the datatype code of the column, as well as the vector repeat count and (if it is an ASCII character column) the width of the field or a unit string within the field. This supports the TFORMn = 'rAw' syntax for specifying arrays of substrings, so if TFORMn = '60A12' then repeat = 60 and width = 12. */ { LONGLONG trepeat, twidth; ffeqtyll(fptr, colnum, typecode, &trepeat, &twidth, status); if (repeat) *repeat= (long) trepeat; if (width) *width = (long) twidth; return(*status); } /*--------------------------------------------------------------------------*/ int ffeqtyll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int *typecode, /* O - datatype code (21 = short, etc) */ LONGLONG *repeat, /* O - repeat count of field */ LONGLONG *width, /* O - if ASCII, width of field or unit string */ int *status) /* IO - error status */ /* Get the 'equivalent' table column type. This routine is similar to the ffgtcl routine (which returns the physical datatype of the column, as stored in the FITS file) except that if the TSCALn and TZEROn keywords are defined for the column, then it returns the 'equivalent' datatype. Thus, if the column is defined as '1I' (short integer) this routine may return the type as 'TUSHORT' or as 'TFLOAT' depending on the TSCALn and TZEROn values. Returns the datatype code of the column, as well as the vector repeat count and (if it is an ASCII character column) the width of the field or a unit string within the field. This supports the TFORMn = 'rAw' syntax for specifying arrays of substrings, so if TFORMn = '60A12' then repeat = 60 and width = 12. */ { tcolumn *colptr; int hdutype, decims, tcode, effcode; double tscale, tzero, min_val, max_val; long lngscale = 1, lngzero = 0, tmpwidth; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (colnum - 1); /* offset to correct column */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == ASCII_TBL) { ffasfm(colptr->tform, typecode, &tmpwidth, &decims, status); *width = tmpwidth; if (repeat) *repeat = 1; } else { if (typecode) *typecode = colptr->tdatatype; if (width) *width = colptr->twidth; if (repeat) *repeat = colptr->trepeat; } /* return if caller is not interested in the typecode value */ if (!typecode) return(*status); /* check if the tscale and tzero keywords are defined, which might change the effective datatype of the column */ tscale = colptr->tscale; tzero = colptr->tzero; if (tscale == 1.0 && tzero == 0.0) /* no scaling */ return(*status); tcode = abs(*typecode); switch (tcode) { case TBYTE: /* binary table 'rB' column */ min_val = 0.; max_val = 255.0; break; case TSHORT: min_val = -32768.0; max_val = 32767.0; break; case TLONG: min_val = -2147483648.0; max_val = 2147483647.0; break; default: /* don't have to deal with other data types */ return(*status); } if (tscale >= 0.) { min_val = tzero + tscale * min_val; max_val = tzero + tscale * max_val; } else { max_val = tzero + tscale * min_val; min_val = tzero + tscale * max_val; } if (tzero < 2147483648.) /* don't exceed range of 32-bit integer */ lngzero = (long) tzero; lngscale = (long) tscale; if ((tzero != 2147483648.) && /* special value that exceeds integer range */ (lngzero != tzero || lngscale != tscale)) { /* not integers? */ /* floating point scaled values; just decide on required precision */ if (tcode == TBYTE || tcode == TSHORT) effcode = TFLOAT; else effcode = TDOUBLE; /* In all the remaining cases, TSCALn and TZEROn are integers, and not equal to 1 and 0, respectively. */ } else if ((min_val == -128.) && (max_val == 127.)) { effcode = TSBYTE; } else if ((min_val >= -32768.0) && (max_val <= 32767.0)) { effcode = TSHORT; } else if ((min_val >= 0.0) && (max_val <= 65535.0)) { effcode = TUSHORT; } else if ((min_val >= -2147483648.0) && (max_val <= 2147483647.0)) { effcode = TLONG; } else if ((min_val >= 0.0) && (max_val < 4294967296.0)) { effcode = TULONG; } else { /* exceeds the range of a 32-bit integer */ effcode = TDOUBLE; } /* return the effective datatype code (negative if variable length col.) */ if (*typecode < 0) /* variable length array column */ *typecode = -effcode; else *typecode = effcode; return(*status); } /*--------------------------------------------------------------------------*/ int ffgncl( fitsfile *fptr, /* I - FITS file pointer */ int *ncols, /* O - number of columns in the table */ int *status) /* IO - error status */ /* Get the number of columns in the table (= TFIELDS keyword) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) return(*status = NOT_TABLE); *ncols = (fptr->Fptr)->tfield; return(*status); } /*--------------------------------------------------------------------------*/ int ffgnrw( fitsfile *fptr, /* I - FITS file pointer */ long *nrows, /* O - number of rows in the table */ int *status) /* IO - error status */ /* Get the number of rows in the table (= NAXIS2 keyword) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) return(*status = NOT_TABLE); /* the NAXIS2 keyword may not be up to date, so use the structure value */ *nrows = (long) (fptr->Fptr)->numrows; return(*status); } /*--------------------------------------------------------------------------*/ int ffgnrwll( fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *nrows, /* O - number of rows in the table */ int *status) /* IO - error status */ /* Get the number of rows in the table (= NAXIS2 keyword) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) return(*status = NOT_TABLE); /* the NAXIS2 keyword may not be up to date, so use the structure value */ *nrows = (fptr->Fptr)->numrows; return(*status); } /*--------------------------------------------------------------------------*/ int ffgacl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ char *ttype, /* O - TTYPEn keyword value */ long *tbcol, /* O - TBCOLn keyword value */ char *tunit, /* O - TUNITn keyword value */ char *tform, /* O - TFORMn keyword value */ double *tscal, /* O - TSCALn keyword value */ double *tzero, /* O - TZEROn keyword value */ char *tnull, /* O - TNULLn keyword value */ char *tdisp, /* O - TDISPn keyword value */ int *status) /* IO - error status */ /* get ASCII column keyword values */ { char name[FLEN_KEYWORD], comm[FLEN_COMMENT]; tcolumn *colptr; int tstatus; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); /* get what we can from the column structure */ colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (colnum -1); /* offset to correct column */ if (ttype) strcpy(ttype, colptr->ttype); if (tbcol) *tbcol = (long) ((colptr->tbcol) + 1); /* first col is 1, not 0 */ if (tform) strcpy(tform, colptr->tform); if (tscal) *tscal = colptr->tscale; if (tzero) *tzero = colptr->tzero; if (tnull) strcpy(tnull, colptr->strnull); /* read keywords to get additional parameters */ if (tunit) { ffkeyn("TUNIT", colnum, name, status); tstatus = 0; *tunit = '\0'; ffgkys(fptr, name, tunit, comm, &tstatus); } if (tdisp) { ffkeyn("TDISP", colnum, name, status); tstatus = 0; *tdisp = '\0'; ffgkys(fptr, name, tdisp, comm, &tstatus); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgbcl( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ char *ttype, /* O - TTYPEn keyword value */ char *tunit, /* O - TUNITn keyword value */ char *dtype, /* O - datatype char: I, J, E, D, etc. */ long *repeat, /* O - vector column repeat count */ double *tscal, /* O - TSCALn keyword value */ double *tzero, /* O - TZEROn keyword value */ long *tnull, /* O - TNULLn keyword value integer cols only */ char *tdisp, /* O - TDISPn keyword value */ int *status) /* IO - error status */ /* get BINTABLE column keyword values */ { LONGLONG trepeat, ttnull; if (*status > 0) return(*status); ffgbclll(fptr, colnum, ttype, tunit, dtype, &trepeat, tscal, tzero, &ttnull, tdisp, status); if (repeat) *repeat = (long) trepeat; if (tnull) *tnull = (long) ttnull; return(*status); } /*--------------------------------------------------------------------------*/ int ffgbclll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ char *ttype, /* O - TTYPEn keyword value */ char *tunit, /* O - TUNITn keyword value */ char *dtype, /* O - datatype char: I, J, E, D, etc. */ LONGLONG *repeat, /* O - vector column repeat count */ double *tscal, /* O - TSCALn keyword value */ double *tzero, /* O - TZEROn keyword value */ LONGLONG *tnull, /* O - TNULLn keyword value integer cols only */ char *tdisp, /* O - TDISPn keyword value */ int *status) /* IO - error status */ /* get BINTABLE column keyword values */ { char name[FLEN_KEYWORD], comm[FLEN_COMMENT]; tcolumn *colptr; int tstatus; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) return(*status = BAD_COL_NUM); /* get what we can from the column structure */ colptr = (fptr->Fptr)->tableptr; /* pointer to first column */ colptr += (colnum -1); /* offset to correct column */ if (ttype) strcpy(ttype, colptr->ttype); if (dtype) { if (colptr->tdatatype < 0) /* add the "P" prefix for */ strcpy(dtype, "P"); /* variable length columns */ else dtype[0] = 0; if (abs(colptr->tdatatype) == TBIT) strcat(dtype, "X"); else if (abs(colptr->tdatatype) == TBYTE) strcat(dtype, "B"); else if (abs(colptr->tdatatype) == TLOGICAL) strcat(dtype, "L"); else if (abs(colptr->tdatatype) == TSTRING) strcat(dtype, "A"); else if (abs(colptr->tdatatype) == TSHORT) strcat(dtype, "I"); else if (abs(colptr->tdatatype) == TLONG) strcat(dtype, "J"); else if (abs(colptr->tdatatype) == TLONGLONG) strcat(dtype, "K"); else if (abs(colptr->tdatatype) == TFLOAT) strcat(dtype, "E"); else if (abs(colptr->tdatatype) == TDOUBLE) strcat(dtype, "D"); else if (abs(colptr->tdatatype) == TCOMPLEX) strcat(dtype, "C"); else if (abs(colptr->tdatatype) == TDBLCOMPLEX) strcat(dtype, "M"); } if (repeat) *repeat = colptr->trepeat; if (tscal) *tscal = colptr->tscale; if (tzero) *tzero = colptr->tzero; if (tnull) *tnull = colptr->tnull; /* read keywords to get additional parameters */ if (tunit) { ffkeyn("TUNIT", colnum, name, status); tstatus = 0; *tunit = '\0'; ffgkys(fptr, name, tunit, comm, &tstatus); } if (tdisp) { ffkeyn("TDISP", colnum, name, status); tstatus = 0; *tdisp = '\0'; ffgkys(fptr, name, tdisp, comm, &tstatus); } return(*status); } /*--------------------------------------------------------------------------*/ int ffghdn(fitsfile *fptr, /* I - FITS file pointer */ int *chdunum) /* O - number of the CHDU; 1 = primary array */ /* Return the number of the Current HDU in the FITS file. The primary array is HDU number 1. Note that this is one of the few cfitsio routines that does not return the error status value as the value of the function. */ { *chdunum = (fptr->HDUposition) + 1; return(*chdunum); } /*--------------------------------------------------------------------------*/ int ffghadll(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *headstart, /* O - byte offset to beginning of CHDU */ LONGLONG *datastart, /* O - byte offset to beginning of next HDU */ LONGLONG *dataend, /* O - byte offset to beginning of next HDU */ int *status) /* IO - error status */ /* Return the address (= byte offset) in the FITS file to the beginning of the current HDU, the beginning of the data unit, and the end of the data unit. */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { if (ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status) > 0) return(*status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if (ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } if (headstart) *headstart = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]; if (datastart) *datastart = (fptr->Fptr)->datastart; if (dataend) *dataend = (fptr->Fptr)->headstart[((fptr->Fptr)->curhdu) + 1]; return(*status); } /*--------------------------------------------------------------------------*/ int ffghof(fitsfile *fptr, /* I - FITS file pointer */ OFF_T *headstart, /* O - byte offset to beginning of CHDU */ OFF_T *datastart, /* O - byte offset to beginning of next HDU */ OFF_T *dataend, /* O - byte offset to beginning of next HDU */ int *status) /* IO - error status */ /* Return the address (= byte offset) in the FITS file to the beginning of the current HDU, the beginning of the data unit, and the end of the data unit. */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { if (ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status) > 0) return(*status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if (ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } if (headstart) *headstart = (OFF_T) (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu]; if (datastart) *datastart = (OFF_T) (fptr->Fptr)->datastart; if (dataend) *dataend = (OFF_T) (fptr->Fptr)->headstart[((fptr->Fptr)->curhdu) + 1]; return(*status); } /*--------------------------------------------------------------------------*/ int ffghad(fitsfile *fptr, /* I - FITS file pointer */ long *headstart, /* O - byte offset to beginning of CHDU */ long *datastart, /* O - byte offset to beginning of next HDU */ long *dataend, /* O - byte offset to beginning of next HDU */ int *status) /* IO - error status */ /* Return the address (= byte offset) in the FITS file to the beginning of the current HDU, the beginning of the data unit, and the end of the data unit. */ { LONGLONG shead, sdata, edata; if (*status > 0) return(*status); ffghadll(fptr, &shead, &sdata, &edata, status); if (headstart) { if (shead > LONG_MAX) *status = NUM_OVERFLOW; else *headstart = (long) shead; } if (datastart) { if (sdata > LONG_MAX) *status = NUM_OVERFLOW; else *datastart = (long) sdata; } if (dataend) { if (edata > LONG_MAX) *status = NUM_OVERFLOW; else *dataend = (long) edata; } return(*status); } /*--------------------------------------------------------------------------*/ int ffrhdu(fitsfile *fptr, /* I - FITS file pointer */ int *hdutype, /* O - type of HDU */ int *status) /* IO - error status */ /* read the required keywords of the CHDU and initialize the corresponding structure elements that describe the format of the HDU */ { int ii, tstatus; char card[FLEN_CARD]; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char xname[FLEN_VALUE], *xtension, urltype[20]; if (*status > 0) return(*status); if (ffgrec(fptr, 1, card, status) > 0 ) /* get the 80-byte card */ { ffpmsg("Cannot read first keyword in header (ffrhdu)."); return(*status); } strncpy(name,card,8); /* first 8 characters = the keyword name */ name[8] = '\0'; for (ii=7; ii >= 0; ii--) /* replace trailing blanks with nulls */ { if (name[ii] == ' ') name[ii] = '\0'; else break; } if (ffpsvc(card, value, comm, status) > 0) /* parse value and comment */ { ffpmsg("Cannot read value of first keyword in header (ffrhdu):"); ffpmsg(card); return(*status); } if (!strcmp(name, "SIMPLE")) /* this is the primary array */ { ffpinit(fptr, status); /* initialize the primary array */ if (hdutype != NULL) *hdutype = 0; } else if (!strcmp(name, "XTENSION")) /* this is an XTENSION keyword */ { if (ffc2s(value, xname, status) > 0) /* get the value string */ { ffpmsg("Bad value string for XTENSION keyword:"); ffpmsg(value); return(*status); } xtension = xname; while (*xtension == ' ') /* ignore any leading spaces in name */ xtension++; if (!strcmp(xtension, "TABLE")) { ffainit(fptr, status); /* initialize the ASCII table */ if (hdutype != NULL) *hdutype = 1; } else if (!strcmp(xtension, "BINTABLE") || !strcmp(xtension, "A3DTABLE") || !strcmp(xtension, "3DTABLE") ) { ffbinit(fptr, status); /* initialize the binary table */ if (hdutype != NULL) *hdutype = 2; } else { tstatus = 0; ffpinit(fptr, &tstatus); /* probably an IMAGE extension */ if (tstatus == UNKNOWN_EXT && hdutype != NULL) *hdutype = -1; /* don't recognize this extension type */ else { *status = tstatus; if (hdutype != NULL) *hdutype = 0; } } } else /* not the start of a new extension */ { if (card[0] == 0 || card[0] == 10) /* some editors append this character to EOF */ { *status = END_OF_FILE; } else { *status = UNKNOWN_REC; /* found unknown type of record */ ffpmsg ("Extension doesn't start with SIMPLE or XTENSION keyword. (ffrhdu)"); ffpmsg(card); } } /* compare the starting position of the next HDU (if any) with the size */ /* of the whole file to see if this is the last HDU in the file */ if ((fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] < (fptr->Fptr)->logfilesize ) { (fptr->Fptr)->lasthdu = 0; /* no, not the last HDU */ } else { (fptr->Fptr)->lasthdu = 1; /* yes, this is the last HDU */ /* special code for mem:// type files (FITS file in memory) */ /* Allocate enough memory to hold the entire HDU. */ /* Without this code, CFITSIO would repeatedly realloc memory */ /* to incrementally increase the size of the file by 2880 bytes */ /* at a time, until it reached the final size */ ffurlt(fptr, urltype, status); if (!strcmp(urltype,"mem://") || !strcmp(urltype,"memkeep://")) { fftrun(fptr, (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1], status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffpinit(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* initialize the parameters defining the structure of the primary array or an Image extension */ { int groups, tstatus, simple, bitpix, naxis, extend, nspace; int ttype = 0, bytlen = 0, ii; long pcount, gcount; LONGLONG naxes[999], npix, blank; double bscale, bzero; char comm[FLEN_COMMENT]; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->hdutype = IMAGE_HDU; /* primary array or IMAGE extension */ (fptr->Fptr)->headend = (fptr->Fptr)->logfilesize; /* set max size */ groups = 0; tstatus = *status; /* get all the descriptive info about this HDU */ ffgphd(fptr, 999, &simple, &bitpix, &naxis, naxes, &pcount, &gcount, &extend, &bscale, &bzero, &blank, &nspace, status); if (*status == NOT_IMAGE) *status = tstatus; /* ignore 'unknown extension type' error */ else if (*status > 0) return(*status); /* the logical end of the header is 80 bytes before the current position, minus any trailing blank keywords just before the END keyword. */ (fptr->Fptr)->headend = (fptr->Fptr)->nextkey - (80 * (nspace + 1)); /* the data unit begins at the beginning of the next logical block */ (fptr->Fptr)->datastart = (((fptr->Fptr)->nextkey - 80) / 2880 + 1) * 2880; if (naxis > 0 && naxes[0] == 0) /* test for 'random groups' */ { tstatus = 0; if (ffgkyl(fptr, "GROUPS", &groups, comm, &tstatus)) groups = 0; /* GROUPS keyword not found */ } if (bitpix == BYTE_IMG) /* test bitpix and set the datatype code */ { ttype=TBYTE; bytlen=1; } else if (bitpix == SHORT_IMG) { ttype=TSHORT; bytlen=2; } else if (bitpix == LONG_IMG) { ttype=TLONG; bytlen=4; } else if (bitpix == LONGLONG_IMG) { ttype=TLONGLONG; bytlen=8; } else if (bitpix == FLOAT_IMG) { ttype=TFLOAT; bytlen=4; } else if (bitpix == DOUBLE_IMG) { ttype=TDOUBLE; bytlen=8; } /* calculate the size of the primary array */ if (naxis == 0) { npix = 0; } else { if (groups) { npix = 1; /* NAXIS1 = 0 is a special flag for 'random groups' */ } else { npix = naxes[0]; } for (ii=1; ii < naxis; ii++) { npix = npix*naxes[ii]; /* calc number of pixels in the array */ } } /* now we know everything about the array; just fill in the parameters: the next HDU begins in the next logical block after the data */ (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] = (fptr->Fptr)->datastart + ( (LONGLONG)(pcount + npix) * bytlen * gcount + 2879) / 2880 * 2880; /* initialize the fictitious heap starting address (immediately following the array data) and a zero length heap. This is used to find the end of the data when checking the fill values in the last block. */ (fptr->Fptr)->heapstart = (npix + pcount) * bytlen * gcount; (fptr->Fptr)->heapsize = 0; (fptr->Fptr)->compressimg = 0; /* this is not a compressed image */ if (naxis == 0) { (fptr->Fptr)->rowlength = 0; /* rows have zero length */ (fptr->Fptr)->tfield = 0; /* table has no fields */ if ((fptr->Fptr)->tableptr) free((fptr->Fptr)->tableptr); /* free memory for the old CHDU */ (fptr->Fptr)->tableptr = 0; /* set a null table structure pointer */ (fptr->Fptr)->numrows = 0; (fptr->Fptr)->origrows = 0; } else { /* The primary array is actually interpreted as a binary table. There are two columns: the first column contains the group parameters if any. The second column contains the primary array of data as a single vector column element. In the case of 'random grouped' format, each group is stored in a separate row of the table. */ /* the number of rows is equal to the number of groups */ (fptr->Fptr)->numrows = gcount; (fptr->Fptr)->origrows = gcount; (fptr->Fptr)->rowlength = (npix + pcount) * bytlen; /* total size */ (fptr->Fptr)->tfield = 2; /* 2 fields: group params and the image */ if ((fptr->Fptr)->tableptr) free((fptr->Fptr)->tableptr); /* free memory for the old CHDU */ colptr = (tcolumn *) calloc(2, sizeof(tcolumn) ) ; if (!colptr) { ffpmsg ("malloc failed to get memory for FITS array descriptors (ffpinit)"); (fptr->Fptr)->tableptr = 0; /* set a null table structure pointer */ return(*status = ARRAY_TOO_BIG); } /* copy the table structure address to the fitsfile structure */ (fptr->Fptr)->tableptr = colptr; /* the first column represents the group parameters, if any */ colptr->tbcol = 0; colptr->tdatatype = ttype; colptr->twidth = bytlen; colptr->trepeat = (LONGLONG) pcount; colptr->tscale = 1.; colptr->tzero = 0.; colptr->tnull = blank; colptr++; /* increment pointer to the second column */ /* the second column represents the image array */ colptr->tbcol = pcount * bytlen; /* col starts after the group parms */ colptr->tdatatype = ttype; colptr->twidth = bytlen; colptr->trepeat = npix; colptr->tscale = bscale; colptr->tzero = bzero; colptr->tnull = blank; } /* reset next keyword pointer to the start of the header */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu ]; return(*status); } /*--------------------------------------------------------------------------*/ int ffainit(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ { /* initialize the parameters defining the structure of an ASCII table */ int ii, nspace; long tfield; LONGLONG pcount, rowlen, nrows, tbcoln; tcolumn *colptr = 0; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char message[FLEN_ERRMSG], errmsg[81]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->hdutype = ASCII_TBL; /* set that this is an ASCII table */ (fptr->Fptr)->headend = (fptr->Fptr)->logfilesize; /* set max size */ /* get table parameters and test that the header is a valid: */ if (ffgttb(fptr, &rowlen, &nrows, &pcount, &tfield, status) > 0) return(*status); if (pcount != 0) { ffpmsg("PCOUNT keyword not equal to 0 in ASCII table (ffainit)."); sprintf(errmsg, " PCOUNT = %ld", (long) pcount); ffpmsg(errmsg); return(*status = BAD_PCOUNT); } (fptr->Fptr)->rowlength = rowlen; /* store length of a row */ (fptr->Fptr)->tfield = tfield; /* store number of table fields in row */ if ((fptr->Fptr)->tableptr) free((fptr->Fptr)->tableptr); /* free memory for the old CHDU */ /* mem for column structures ; space is initialized = 0 */ if (tfield > 0) { colptr = (tcolumn *) calloc(tfield, sizeof(tcolumn) ); if (!colptr) { ffpmsg ("malloc failed to get memory for FITS table descriptors (ffainit)"); (fptr->Fptr)->tableptr = 0; /* set a null table structure pointer */ return(*status = ARRAY_TOO_BIG); } } /* copy the table structure address to the fitsfile structure */ (fptr->Fptr)->tableptr = colptr; /* initialize the table field parameters */ for (ii = 0; ii < tfield; ii++, colptr++) { colptr->ttype[0] = '\0'; /* null column name */ colptr->tscale = 1.; colptr->tzero = 0.; colptr->strnull[0] = ASCII_NULL_UNDEFINED; /* null value undefined */ colptr->tbcol = -1; /* initialize to illegal value */ colptr->tdatatype = -9999; /* initialize to illegal value */ } /* Initialize the fictitious heap starting address (immediately following the table data) and a zero length heap. This is used to find the end of the table data when checking the fill values in the last block. There is no special data following an ASCII table. */ (fptr->Fptr)->numrows = nrows; (fptr->Fptr)->origrows = nrows; (fptr->Fptr)->heapstart = rowlen * nrows; (fptr->Fptr)->heapsize = 0; (fptr->Fptr)->compressimg = 0; /* this is not a compressed image */ /* now search for the table column keywords and the END keyword */ for (nspace = 0, ii = 8; 1; ii++) /* infinite loop */ { ffgkyn(fptr, ii, name, value, comm, status); /* try to ignore minor syntax errors */ if (*status == NO_QUOTE) { strcat(value, "'"); *status = 0; } else if (*status == BAD_KEYCHAR) { *status = 0; } if (*status == END_OF_FILE) { ffpmsg("END keyword not found in ASCII table header (ffainit)."); return(*status = NO_END); } else if (*status > 0) return(*status); else if (name[0] == 'T') /* keyword starts with 'T' ? */ ffgtbp(fptr, name, value, status); /* test if column keyword */ else if (!FSTRCMP(name, "END")) /* is this the END keyword? */ break; if (!name[0] && !value[0] && !comm[0]) /* a blank keyword? */ nspace++; else nspace = 0; } /* test that all required keywords were found and have legal values */ colptr = (fptr->Fptr)->tableptr; for (ii = 0; ii < tfield; ii++, colptr++) { tbcoln = colptr->tbcol; /* the starting column number (zero based) */ if (colptr->tdatatype == -9999) { ffkeyn("TFORM", ii+1, name, status); /* construct keyword name */ sprintf(message,"Required %s keyword not found (ffainit).", name); ffpmsg(message); return(*status = NO_TFORM); } else if (tbcoln == -1) { ffkeyn("TBCOL", ii+1, name, status); /* construct keyword name */ sprintf(message,"Required %s keyword not found (ffainit).", name); ffpmsg(message); return(*status = NO_TBCOL); } else if ((fptr->Fptr)->rowlength != 0 && (tbcoln < 0 || tbcoln >= (fptr->Fptr)->rowlength ) ) { ffkeyn("TBCOL", ii+1, name, status); /* construct keyword name */ sprintf(message,"Value of %s keyword out of range: %ld (ffainit).", name, (long) tbcoln); ffpmsg(message); return(*status = BAD_TBCOL); } else if ((fptr->Fptr)->rowlength != 0 && tbcoln + colptr->twidth > (fptr->Fptr)->rowlength ) { sprintf(message,"Column %d is too wide to fit in table (ffainit)", ii+1); ffpmsg(message); sprintf(message, " TFORM = %s and NAXIS1 = %ld", colptr->tform, (long) (fptr->Fptr)->rowlength); ffpmsg(message); return(*status = COL_TOO_WIDE); } } /* now we know everything about the table; just fill in the parameters: the 'END' record is 80 bytes before the current position, minus any trailing blank keywords just before the END keyword. */ (fptr->Fptr)->headend = (fptr->Fptr)->nextkey - (80 * (nspace + 1)); /* the data unit begins at the beginning of the next logical block */ (fptr->Fptr)->datastart = (((fptr->Fptr)->nextkey - 80) / 2880 + 1) * 2880; /* the next HDU begins in the next logical block after the data */ (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] = (fptr->Fptr)->datastart + ( ((LONGLONG)rowlen * nrows + 2879) / 2880 * 2880 ); /* reset next keyword pointer to the start of the header */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu ]; return(*status); } /*--------------------------------------------------------------------------*/ int ffbinit(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ { /* initialize the parameters defining the structure of a binary table */ int ii, nspace; long tfield; LONGLONG pcount, rowlen, nrows, totalwidth; tcolumn *colptr = 0; char name[FLEN_KEYWORD], value[FLEN_VALUE], comm[FLEN_COMMENT]; char message[FLEN_ERRMSG]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); (fptr->Fptr)->hdutype = BINARY_TBL; /* set that this is a binary table */ (fptr->Fptr)->headend = (fptr->Fptr)->logfilesize; /* set max size */ /* get table parameters and test that the header is valid: */ if (ffgttb(fptr, &rowlen, &nrows, &pcount, &tfield, status) > 0) return(*status); (fptr->Fptr)->rowlength = rowlen; /* store length of a row */ (fptr->Fptr)->tfield = tfield; /* store number of table fields in row */ if ((fptr->Fptr)->tableptr) free((fptr->Fptr)->tableptr); /* free memory for the old CHDU */ /* mem for column structures ; space is initialized = 0 */ if (tfield > 0) { colptr = (tcolumn *) calloc(tfield, sizeof(tcolumn) ); if (!colptr) { ffpmsg ("malloc failed to get memory for FITS table descriptors (ffbinit)"); (fptr->Fptr)->tableptr = 0; /* set a null table structure pointer */ return(*status = ARRAY_TOO_BIG); } } /* copy the table structure address to the fitsfile structure */ (fptr->Fptr)->tableptr = colptr; /* initialize the table field parameters */ for (ii = 0; ii < tfield; ii++, colptr++) { colptr->ttype[0] = '\0'; /* null column name */ colptr->tscale = 1.; colptr->tzero = 0.; colptr->tnull = NULL_UNDEFINED; /* (integer) null value undefined */ colptr->tdatatype = -9999; /* initialize to illegal value */ colptr->trepeat = 1; colptr->strnull[0] = '\0'; /* for ASCII string columns (TFORM = rA) */ } /* Initialize the heap starting address (immediately following the table data) and the size of the heap. This is used to find the end of the table data when checking the fill values in the last block. */ (fptr->Fptr)->numrows = nrows; (fptr->Fptr)->origrows = nrows; (fptr->Fptr)->heapstart = rowlen * nrows; (fptr->Fptr)->heapsize = pcount; (fptr->Fptr)->compressimg = 0; /* initialize as not a compressed image */ /* now search for the table column keywords and the END keyword */ for (nspace = 0, ii = 8; 1; ii++) /* infinite loop */ { ffgkyn(fptr, ii, name, value, comm, status); /* try to ignore minor syntax errors */ if (*status == NO_QUOTE) { strcat(value, "'"); *status = 0; } else if (*status == BAD_KEYCHAR) { *status = 0; } if (*status == END_OF_FILE) { ffpmsg("END keyword not found in binary table header (ffbinit)."); return(*status = NO_END); } else if (*status > 0) return(*status); else if (name[0] == 'T') /* keyword starts with 'T' ? */ ffgtbp(fptr, name, value, status); /* test if column keyword */ else if (!FSTRCMP(name, "ZIMAGE")) { if (value[0] == 'T') (fptr->Fptr)->compressimg = 1; /* this is a compressed image */ } else if (!FSTRCMP(name, "END")) /* is this the END keyword? */ break; if (!name[0] && !value[0] && !comm[0]) /* a blank keyword? */ nspace++; else nspace = 0; /* reset number of consecutive spaces before END */ } /* test that all the required keywords were found and have legal values */ colptr = (fptr->Fptr)->tableptr; /* set pointer to first column */ for (ii = 0; ii < tfield; ii++, colptr++) { if (colptr->tdatatype == -9999) { ffkeyn("TFORM", ii+1, name, status); /* construct keyword name */ sprintf(message,"Required %s keyword not found (ffbinit).", name); ffpmsg(message); return(*status = NO_TFORM); } } /* now we know everything about the table; just fill in the parameters: the 'END' record is 80 bytes before the current position, minus any trailing blank keywords just before the END keyword. */ (fptr->Fptr)->headend = (fptr->Fptr)->nextkey - (80 * (nspace + 1)); /* the data unit begins at the beginning of the next logical block */ (fptr->Fptr)->datastart = (((fptr->Fptr)->nextkey - 80) / 2880 + 1) * 2880; /* the next HDU begins in the next logical block after the data */ (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] = (fptr->Fptr)->datastart + ( (rowlen * nrows + pcount + 2879) / 2880 * 2880 ); /* determine the byte offset to the beginning of each column */ ffgtbc(fptr, &totalwidth, status); if (totalwidth != rowlen) { sprintf(message, "NAXIS1 = %ld is not equal to the sum of column widths: %ld", (long) rowlen, (long) totalwidth); ffpmsg(message); *status = BAD_ROW_WIDTH; } /* reset next keyword pointer to the start of the header */ (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu ]; if ( (fptr->Fptr)->compressimg == 1) /* Is this a compressed image */ imcomp_get_compressed_image_par(fptr, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgabc(int tfields, /* I - number of columns in the table */ char **tform, /* I - value of TFORMn keyword for each column */ int space, /* I - number of spaces to leave between cols */ long *rowlen, /* O - total width of a table row */ long *tbcol, /* O - starting byte in row for each column */ int *status) /* IO - error status */ /* calculate the starting byte offset of each column of an ASCII table and the total length of a row, in bytes. The input space value determines how many blank spaces to leave between each column (1 is recommended). */ { int ii, datacode, decims; long width; if (*status > 0) return(*status); *rowlen=0; if (tfields <= 0) return(*status); tbcol[0] = 1; for (ii = 0; ii < tfields; ii++) { tbcol[ii] = *rowlen + 1; /* starting byte in row of column */ ffasfm(tform[ii], &datacode, &width, &decims, status); *rowlen += (width + space); /* total length of row */ } *rowlen -= space; /* don't add space after the last field */ return (*status); } /*--------------------------------------------------------------------------*/ int ffgtbc(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *totalwidth, /* O - total width of a table row */ int *status) /* IO - error status */ { /* calculate the starting byte offset of each column of a binary table. Use the values of the datatype code and repeat counts in the column structure. Return the total length of a row, in bytes. */ int tfields, ii; LONGLONG nbytes; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); tfields = (fptr->Fptr)->tfield; colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ *totalwidth = 0; for (ii = 0; ii < tfields; ii++, colptr++) { colptr->tbcol = *totalwidth; /* byte offset in row to this column */ if (colptr->tdatatype == TSTRING) { nbytes = colptr->trepeat; /* one byte per char */ } else if (colptr->tdatatype == TBIT) { nbytes = ( colptr->trepeat + 7) / 8; } else if (colptr->tdatatype > 0) { nbytes = colptr->trepeat * (colptr->tdatatype / 10); } else if ((colptr->tform[0] == 'P') || (colptr->tform[1] == 'P')) /* this is a 'P' variable length descriptor (neg. tdatatype) */ nbytes = 8; else /* this is a 'Q' variable length descriptor (neg. tdatatype) */ nbytes = 16; *totalwidth = *totalwidth + nbytes; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgtbp(fitsfile *fptr, /* I - FITS file pointer */ char *name, /* I - name of the keyword */ char *value, /* I - value string of the keyword */ int *status) /* IO - error status */ { /* Get TaBle Parameter. The input keyword name begins with the letter T. Test if the keyword is one of the table column definition keywords of an ASCII or binary table. If so, decode it and update the value in the structure. */ int tstatus, datacode, decimals; long width, repeat, nfield, ivalue; LONGLONG jjvalue; double dvalue; char tvalue[FLEN_VALUE]; char message[FLEN_ERRMSG]; tcolumn *colptr; if (*status > 0) return(*status); tstatus = 0; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if(!FSTRNCMP(name + 1, "TYPE", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if (ffc2s(value, tvalue, &tstatus) > 0) /* remove quotes */ return(*status); strcpy(colptr->ttype, tvalue); /* copy col name to structure */ } else if(!FSTRNCMP(name + 1, "FORM", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if (ffc2s(value, tvalue, &tstatus) > 0) /* remove quotes */ return(*status); strncpy(colptr->tform, tvalue, 9); /* copy TFORM to structure */ colptr->tform[9] = '\0'; /* make sure it is terminated */ if ((fptr->Fptr)->hdutype == ASCII_TBL) /* ASCII table */ { if (ffasfm(tvalue, &datacode, &width, &decimals, status) > 0) return(*status); /* bad format code */ colptr->tdatatype = TSTRING; /* store datatype code */ colptr->trepeat = 1; /* field repeat count == 1 */ colptr->twidth = width; /* the width of the field, in bytes */ } else /* binary table */ { if (ffbnfm(tvalue, &datacode, &repeat, &width, status) > 0) return(*status); /* bad format code */ colptr->tdatatype = datacode; /* store datatype code */ colptr->trepeat = (LONGLONG) repeat; /* field repeat count */ colptr->twidth = width; /* width of a unit value in chars */ } } else if(!FSTRNCMP(name + 1, "BCOL", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if ((fptr->Fptr)->hdutype == BINARY_TBL) return(*status); /* binary tables don't have TBCOL keywords */ if (ffc2ii(value, &ivalue, status) > 0) { sprintf(message, "Error reading value of %s as an integer: %s", name, value); ffpmsg(message); return(*status); } colptr->tbcol = ivalue - 1; /* convert to zero base */ } else if(!FSTRNCMP(name + 1, "SCAL", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if (ffc2dd(value, &dvalue, &tstatus) > 0) { sprintf(message, "Error reading value of %s as a double: %s", name, value); ffpmsg(message); /* ignore this error, so don't return error status */ return(*status); } colptr->tscale = dvalue; } else if(!FSTRNCMP(name + 1, "ZERO", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if (ffc2dd(value, &dvalue, &tstatus) > 0) { sprintf(message, "Error reading value of %s as a double: %s", name, value); ffpmsg(message); /* ignore this error, so don't return error status */ return(*status); } colptr->tzero = dvalue; } else if(!FSTRNCMP(name + 1, "NULL", 4) ) { /* get the index number */ if( ffc2ii(name + 5, &nfield, &tstatus) > 0) /* read index no. */ return(*status); /* must not be an indexed keyword */ if (nfield < 1 || nfield > (fptr->Fptr)->tfield ) /* out of range */ return(*status); colptr = (fptr->Fptr)->tableptr; /* get pointer to columns */ colptr = colptr + nfield - 1; /* point to the correct column */ if ((fptr->Fptr)->hdutype == ASCII_TBL) /* ASCII table */ { if (ffc2s(value, tvalue, &tstatus) > 0) /* remove quotes */ return(*status); strncpy(colptr->strnull, tvalue, 17); /* copy TNULL string */ colptr->strnull[17] = '\0'; /* terminate the strnull field */ } else /* binary table */ { if (ffc2jj(value, &jjvalue, &tstatus) > 0) { sprintf(message, "Error reading value of %s as an integer: %s", name, value); ffpmsg(message); /* ignore this error, so don't return error status */ return(*status); } colptr->tnull = jjvalue; /* null value for integer column */ } } else if (!FSTRNCMP(name + 1, "HEAP", 4) ) { if ((fptr->Fptr)->hdutype == ASCII_TBL) /* ASCII table */ return(*status); /* ASCII tables don't have a heap */ if (ffc2jj(value, &jjvalue, &tstatus) > 0) { sprintf(message, "Error reading value of %s as an integer: %s", name, value); ffpmsg(message); /* ignore this error, so don't return error status */ return(*status); } (fptr->Fptr)->heapstart = jjvalue; /* starting byte of the heap */ return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcprll( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG firstrow, /* I - first row (1 = 1st row of table) */ LONGLONG firstelem, /* I - first element within vector (1 = 1st) */ LONGLONG nelem, /* I - number of elements to read or write */ int writemode, /* I - = 1 if writing data, = 0 if reading data */ /* If = 2, then writing data, but don't modify */ /* the returned values of repeat and incre. */ /* If = -1, then reading data in reverse */ /* direction. */ double *scale, /* O - FITS scaling factor (TSCALn keyword value) */ double *zero, /* O - FITS scaling zero pt (TZEROn keyword value) */ char *tform, /* O - ASCII column format: value of TFORMn keyword */ long *twidth, /* O - width of ASCII column (characters) */ int *tcode, /* O - column datatype code: I*4=41, R*4=42, etc */ int *maxelem, /* O - max number of elements that fit in buffer */ LONGLONG *startpos,/* O - offset in file to starting row & column */ LONGLONG *elemnum, /* O - starting element number ( 0 = 1st element) */ long *incre, /* O - byte offset between elements within a row */ LONGLONG *repeat, /* O - number of elements in a row (vector column) */ LONGLONG *rowlen, /* O - length of a row, in bytes */ int *hdutype, /* O - HDU type: 0, 1, 2 = primary, table, bintable */ LONGLONG *tnull, /* O - null value for integer columns */ char *snull, /* O - null value for ASCII table columns */ int *status) /* IO - error status */ /* Get Column PaRameters, and test starting row and element numbers for validity. This is a workhorse routine that is call by nearly every other routine that reads or writes to FITS files. */ { int nulpos, rangecheck = 1, tstatus = 0; LONGLONG datastart, endpos; long nblock; LONGLONG heapoffset, lrepeat, endrow, nrows, tbcol; char message[81]; tcolumn *colptr; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); /* Do sanity check of input parameters */ if (firstrow < 1) { if ((fptr->Fptr)->hdutype == IMAGE_HDU) /* Primary Array or IMAGE */ { sprintf(message, "Image group number is less than 1: %.0f", (double) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } else { sprintf(message, "Starting row number is less than 1: %.0f", (double) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } } else if ((fptr->Fptr)->hdutype != ASCII_TBL && firstelem < 1) { sprintf(message, "Starting element number less than 1: %ld", (long) firstelem); ffpmsg(message); return(*status = BAD_ELEM_NUM); } else if (nelem < 0) { sprintf(message, "Tried to read or write less than 0 elements: %.0f", (double) nelem); ffpmsg(message); return(*status = NEG_BYTES); } else if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { sprintf(message, "Specified column number is out of range: %d", colnum); ffpmsg(message); sprintf(message, " There are %d columns in this table.", (fptr->Fptr)->tfield ); ffpmsg(message); return(*status = BAD_COL_NUM); } /* copy relevant parameters from the structure */ *hdutype = (fptr->Fptr)->hdutype; /* image, ASCII table, or BINTABLE */ *rowlen = (fptr->Fptr)->rowlength; /* width of the table, in bytes */ datastart = (fptr->Fptr)->datastart; /* offset in file to start of table */ colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ *scale = colptr->tscale; /* value scaling factor; default = 1.0 */ *zero = colptr->tzero; /* value scaling zeropoint; default = 0.0 */ *tnull = colptr->tnull; /* null value for integer columns */ tbcol = colptr->tbcol; /* offset to start of column within row */ *twidth = colptr->twidth; /* width of a single datum, in bytes */ *incre = colptr->twidth; /* increment between datums, in bytes */ *tcode = colptr->tdatatype; *repeat = colptr->trepeat; strcpy(tform, colptr->tform); /* value of TFORMn keyword */ strcpy(snull, colptr->strnull); /* null value for ASCII table columns */ if (*hdutype == ASCII_TBL && snull[0] == '\0') { /* In ASCII tables, a null value is equivalent to all spaces */ strcpy(snull, " "); /* maximum of 17 spaces */ nulpos = minvalue(17, *twidth); /* truncate to width of column */ snull[nulpos] = '\0'; } /* Special case: interpret writemode = -1 as reading data, but */ /* don't do error check for exceeding the range of pixels */ if (writemode == -1) { writemode = 0; rangecheck = 0; } /* Special case: interprete 'X' column as 'B' */ if (abs(*tcode) == TBIT) { *tcode = *tcode / TBIT * TBYTE; *repeat = (*repeat + 7) / 8; } /* Special case: support the 'rAw' format in BINTABLEs */ if (*hdutype == BINARY_TBL && *tcode == TSTRING) { *repeat = *repeat / *twidth; /* repeat = # of unit strings in field */ } else if (*hdutype == BINARY_TBL && *tcode == -TSTRING) { /* variable length string */ *incre = 1; *twidth = (long) nelem; } if (*hdutype == ASCII_TBL) *elemnum = 0; /* ASCII tables don't have vector elements */ else *elemnum = firstelem - 1; /* interprete complex and double complex as pairs of floats or doubles */ if (abs(*tcode) >= TCOMPLEX) { if (*tcode > 0) *tcode = (*tcode + 1) / 2; else *tcode = (*tcode - 1) / 2; *repeat = *repeat * 2; *twidth = *twidth / 2; *incre = *incre / 2; } /* calculate no. of pixels that fit in buffer */ /* allow for case where floats are 8 bytes long */ if (abs(*tcode) == TFLOAT) *maxelem = DBUFFSIZE / sizeof(float); else if (abs(*tcode) == TDOUBLE) *maxelem = DBUFFSIZE / sizeof(double); else if (abs(*tcode) == TSTRING) { *maxelem = (DBUFFSIZE - 1)/ *twidth; /* leave room for final \0 */ if (*maxelem == 0) { sprintf(message, "ASCII string column is too wide: %ld; max supported width is %d", *twidth, DBUFFSIZE - 1); ffpmsg(message); return(*status = COL_TOO_WIDE); } } else *maxelem = DBUFFSIZE / *twidth; /* calc starting byte position to 1st element of col */ /* (this does not apply to variable length columns) */ *startpos = datastart + ((LONGLONG)(firstrow - 1) * *rowlen) + tbcol; if (*hdutype == IMAGE_HDU && writemode) /* Primary Array or IMAGE */ { /* For primary arrays, set the repeat count greater than the total number of pixels to be written. This prevents an out-of-range error message in cases where the final image array size is not yet known or defined. */ if (*repeat < *elemnum + nelem) *repeat = *elemnum + nelem; } else if (*tcode > 0) /* Fixed length table column */ { if (*elemnum >= *repeat) { sprintf(message, "First element to write is too large: %ld; max allowed value is %ld", (long) ((*elemnum) + 1), (long) *repeat); ffpmsg(message); return(*status = BAD_ELEM_NUM); } /* last row number to be read or written */ endrow = ((*elemnum + nelem - 1) / *repeat) + firstrow; if (writemode) { /* check if we are writing beyond the current end of table */ if ((endrow > (fptr->Fptr)->numrows) && (nelem > 0) ) { /* if there are more HDUs following the current one, or */ /* if there is a data heap, then we must insert space */ /* for the new rows. */ if ( !((fptr->Fptr)->lasthdu) || (fptr->Fptr)->heapsize > 0) { nrows = endrow - ((fptr->Fptr)->numrows); if (ffirow(fptr, (fptr->Fptr)->numrows, nrows, status) > 0) { sprintf(message, "Failed to add space for %.0f new rows in table.", (double) nrows); ffpmsg(message); return(*status); } } else { /* update heap starting address */ (fptr->Fptr)->heapstart += ((LONGLONG)(endrow - (fptr->Fptr)->numrows) * (fptr->Fptr)->rowlength ); (fptr->Fptr)->numrows = endrow; /* update number of rows */ } } } else /* reading from the file */ { if ( endrow > (fptr->Fptr)->numrows && rangecheck) { if (*hdutype == IMAGE_HDU) /* Primary Array or IMAGE */ { if (firstrow > (fptr->Fptr)->numrows) { sprintf(message, "Attempted to read from group %ld of the HDU,", (long) firstrow); ffpmsg(message); sprintf(message, "however the HDU only contains %ld group(s).", (long) ((fptr->Fptr)->numrows) ); ffpmsg(message); } else { ffpmsg("Attempt to read past end of array:"); sprintf(message, " Image has %ld elements;", (long) *repeat); ffpmsg(message); sprintf(message, " Tried to read %ld elements starting at element %ld.", (long) nelem, (long) firstelem); ffpmsg(message); } } else { ffpmsg("Attempt to read past end of table:"); sprintf(message, " Table has %.0f rows with %.0f elements per row;", (double) ((fptr->Fptr)->numrows), (double) *repeat); ffpmsg(message); sprintf(message, " Tried to read %.0f elements starting at row %.0f, element %.0f.", (double) nelem, (double) firstrow, (double) ((*elemnum) + 1)); ffpmsg(message); } return(*status = BAD_ROW_NUM); } } if (*repeat == 1 && nelem > 1 && writemode != 2) { /* When accessing a scalar column, fool the calling routine into thinking that this is a vector column with very big elements. This allows multiple values (up to the maxelem number of elements that will fit in the buffer) to be read or written with a single routine call, which increases the efficiency. If writemode == 2, then the calling program does not want to have this efficiency trick applied. */ *incre = (long) *rowlen; *repeat = nelem; } } else /* Variable length Binary Table column */ { *tcode *= (-1); if (writemode) /* return next empty heap address for writing */ { *repeat = nelem + *elemnum; /* total no. of elements in the field */ /* first, check if we are overwriting an existing row, and */ /* if so, if the existing space is big enough for the new vector */ if ( firstrow <= (fptr->Fptr)->numrows ) { ffgdesll(fptr, colnum, firstrow, &lrepeat, &heapoffset, &tstatus); if (!tstatus) { if (colptr->tdatatype <= -TCOMPLEX) lrepeat = lrepeat * 2; /* no. of float or double values */ else if (colptr->tdatatype == -TBIT) lrepeat = (lrepeat + 7) / 8; /* convert from bits to bytes */ if (lrepeat >= *repeat) /* enough existing space? */ { *startpos = datastart + heapoffset + (fptr->Fptr)->heapstart; /* write the descriptor into the fixed length part of table */ if (colptr->tdatatype <= -TCOMPLEX) { /* divide repeat count by 2 to get no. of complex values */ ffpdes(fptr, colnum, firstrow, *repeat / 2, heapoffset, status); } else { ffpdes(fptr, colnum, firstrow, *repeat, heapoffset, status); } return(*status); } } } /* Add more rows to the table, if writing beyond the end. */ /* It is necessary to shift the heap down in this case */ if ( firstrow > (fptr->Fptr)->numrows) { nrows = firstrow - ((fptr->Fptr)->numrows); if (ffirow(fptr, (fptr->Fptr)->numrows, nrows, status) > 0) { sprintf(message, "Failed to add space for %.0f new rows in table.", (double) nrows); ffpmsg(message); return(*status); } } /* calculate starting position (for writing new data) in the heap */ *startpos = datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; /* write the descriptor into the fixed length part of table */ if (colptr->tdatatype <= -TCOMPLEX) { /* divide repeat count by 2 to get no. of complex values */ ffpdes(fptr, colnum, firstrow, *repeat / 2, (fptr->Fptr)->heapsize, status); } else { ffpdes(fptr, colnum, firstrow, *repeat, (fptr->Fptr)->heapsize, status); } /* If this is not the last HDU in the file, then check if */ /* extending the heap would overwrite the following header. */ /* If so, then have to insert more blocks. */ if ( !((fptr->Fptr)->lasthdu) ) { endpos = datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize + ( *repeat * (*incre)); if (endpos > (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1]) { /* calc the number of blocks that need to be added */ nblock = (long) (((endpos - 1 - (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] ) / 2880) + 1); if (ffiblk(fptr, nblock, 1, status) > 0) /* insert blocks */ { sprintf(message, "Failed to extend the size of the variable length heap by %ld blocks.", nblock); ffpmsg(message); return(*status); } } } /* increment the address to the next empty heap position */ (fptr->Fptr)->heapsize += ( *repeat * (*incre)); } else /* get the read start position in the heap */ { if ( firstrow > (fptr->Fptr)->numrows) { ffpmsg("Attempt to read past end of table"); sprintf(message, " Table has %.0f rows and tried to read row %.0f.", (double) ((fptr->Fptr)->numrows), (double) firstrow); ffpmsg(message); return(*status = BAD_ROW_NUM); } ffgdesll(fptr, colnum, firstrow, &lrepeat, &heapoffset, status); *repeat = lrepeat; if (colptr->tdatatype <= -TCOMPLEX) *repeat = *repeat * 2; /* no. of float or double values */ else if (colptr->tdatatype == -TBIT) *repeat = (*repeat + 7) / 8; /* convert from bits to bytes */ if (*elemnum >= *repeat) { sprintf(message, "Starting element to read in variable length column is too large: %ld", (long) firstelem); ffpmsg(message); sprintf(message, " This row only contains %ld elements", (long) *repeat); ffpmsg(message); return(*status = BAD_ELEM_NUM); } *startpos = datastart + heapoffset + (fptr->Fptr)->heapstart; } } return(*status); } /*---------------------------------------------------------------------------*/ int fftheap(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG *heapsz, /* O - current size of the heap */ LONGLONG *unused, /* O - no. of unused bytes in the heap */ LONGLONG *overlap, /* O - no. of bytes shared by > 1 descriptors */ int *valid, /* O - are all the heap addresses valid? */ int *status) /* IO - error status */ /* Tests the contents of the binary table variable length array heap. Returns the number of bytes that are currently not pointed to by any of the descriptors, and also the number of bytes that are pointed to by more than one descriptor. It returns valid = FALSE if any of the descriptors point to addresses that are out of the bounds of the heap. */ { int jj, typecode, pixsize; long ii, kk, theapsz, nbytes; LONGLONG repeat, offset, tunused = 0, toverlap = 0; char *buffer, message[81]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if ( fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header to make sure everything is up to date */ else if ( ffrdef(fptr, status) > 0) return(*status); if (valid) *valid = TRUE; if (heapsz) *heapsz = (fptr->Fptr)->heapsize; if (unused) *unused = 0; if (overlap) *overlap = 0; /* return if this is not a binary table HDU or if the heap is empty */ if ( (fptr->Fptr)->hdutype != BINARY_TBL || (fptr->Fptr)->heapsize == 0 ) return(*status); if ((fptr->Fptr)->heapsize > LONG_MAX) { ffpmsg("Heap is too big to test ( > 2**31 bytes). (fftheap)"); return(*status = MEMORY_ALLOCATION); } theapsz = (long) (fptr->Fptr)->heapsize; buffer = calloc(1, theapsz); /* allocate temp space */ if (!buffer ) { sprintf(message,"Failed to allocate buffer to test the heap"); ffpmsg(message); return(*status = MEMORY_ALLOCATION); } /* loop over all cols */ for (jj = 1; jj <= (fptr->Fptr)->tfield && *status <= 0; jj++) { ffgtcl(fptr, jj, &typecode, NULL, NULL, status); if (typecode > 0) continue; /* ignore fixed length columns */ pixsize = -typecode / 10; for (ii = 1; ii <= (fptr->Fptr)->numrows; ii++) { ffgdesll(fptr, jj, ii, &repeat, &offset, status); if (typecode == -TBIT) nbytes = (long) (repeat + 7) / 8; else nbytes = (long) repeat * pixsize; if (offset < 0 || offset + nbytes > theapsz) { if (valid) *valid = FALSE; /* address out of bounds */ sprintf(message, "Descriptor in row %ld, column %d has invalid heap address", ii, jj); ffpmsg(message); } else { for (kk = 0; kk < nbytes; kk++) buffer[kk + offset]++; /* increment every used byte */ } } } for (kk = 0; kk < theapsz; kk++) { if (buffer[kk] == 0) tunused++; else if (buffer[kk] > 1) toverlap++; } if (heapsz) *heapsz = theapsz; if (unused) *unused = tunused; if (overlap) *overlap = toverlap; free(buffer); return(*status); } /*--------------------------------------------------------------------------*/ int ffcmph(fitsfile *fptr, /* I -FITS file pointer */ int *status) /* IO - error status */ /* compress the binary table heap by reordering the contents heap and recovering any unused space */ { fitsfile *tptr; int jj, typecode, pixsize, valid; long ii, buffsize = 10000, nblock, nbytes; LONGLONG unused, overlap; LONGLONG repeat, offset; char *buffer, *tbuff = 0, comm[FLEN_COMMENT]; char message[81]; LONGLONG pcount; LONGLONG readheapstart, writeheapstart, endpos, t1heapsize, t2heapsize; if (*status > 0) return(*status); /* get information about the current heap */ fftheap(fptr, NULL, &unused, &overlap, &valid, status); if (!valid) return(*status = BAD_HEAP_PTR); /* bad heap pointers */ /* return if this is not a binary table HDU or if the heap is OK as is */ if ( (fptr->Fptr)->hdutype != BINARY_TBL || (fptr->Fptr)->heapsize == 0 || (unused == 0 && overlap == 0) || *status > 0 ) return(*status); /* copy the current HDU to a temporary file in memory */ if (ffinit( &tptr, "mem://tempheapfile", status) ) { sprintf(message,"Failed to create temporary file for the heap"); ffpmsg(message); return(*status); } if ( ffcopy(fptr, tptr, 0, status) ) { sprintf(message,"Failed to create copy of the heap"); ffpmsg(message); ffclos(tptr, status); return(*status); } buffer = (char *) malloc(buffsize); /* allocate initial buffer */ if (!buffer) { sprintf(message,"Failed to allocate buffer to copy the heap"); ffpmsg(message); ffclos(tptr, status); return(*status = MEMORY_ALLOCATION); } readheapstart = (tptr->Fptr)->datastart + (tptr->Fptr)->heapstart; writeheapstart = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart; t1heapsize = (fptr->Fptr)->heapsize; /* save original heap size */ (fptr->Fptr)->heapsize = 0; /* reset heap to zero */ /* loop over all cols */ for (jj = 1; jj <= (fptr->Fptr)->tfield && *status <= 0; jj++) { ffgtcl(tptr, jj, &typecode, NULL, NULL, status); if (typecode > 0) continue; /* ignore fixed length columns */ pixsize = -typecode / 10; /* copy heap data, row by row */ for (ii = 1; ii <= (fptr->Fptr)->numrows; ii++) { ffgdesll(tptr, jj, ii, &repeat, &offset, status); if (typecode == -TBIT) nbytes = (long) (repeat + 7) / 8; else nbytes = (long) repeat * pixsize; /* increase size of buffer if necessary to read whole array */ if (nbytes > buffsize) { tbuff = realloc(buffer, nbytes); if (tbuff) { buffer = tbuff; buffsize = nbytes; } else *status = MEMORY_ALLOCATION; } /* If this is not the last HDU in the file, then check if */ /* extending the heap would overwrite the following header. */ /* If so, then have to insert more blocks. */ if ( !((fptr->Fptr)->lasthdu) ) { endpos = writeheapstart + (fptr->Fptr)->heapsize + nbytes; if (endpos > (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1]) { /* calc the number of blocks that need to be added */ nblock = (long) (((endpos - 1 - (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] ) / 2880) + 1); if (ffiblk(fptr, nblock, 1, status) > 0) /* insert blocks */ { sprintf(message, "Failed to extend the size of the variable length heap by %ld blocks.", nblock); ffpmsg(message); } } } /* read arrray of bytes from temporary copy */ ffmbyt(tptr, readheapstart + offset, REPORT_EOF, status); ffgbyt(tptr, nbytes, buffer, status); /* write arrray of bytes back to original file */ ffmbyt(fptr, writeheapstart + (fptr->Fptr)->heapsize, IGNORE_EOF, status); ffpbyt(fptr, nbytes, buffer, status); /* write descriptor */ ffpdes(fptr, jj, ii, repeat, (fptr->Fptr)->heapsize, status); (fptr->Fptr)->heapsize += nbytes; /* update heapsize */ if (*status > 0) { free(buffer); ffclos(tptr, status); return(*status); } } } free(buffer); ffclos(tptr, status); /* delete any empty blocks at the end of the HDU */ nblock = (long) (( (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] - (writeheapstart + (fptr->Fptr)->heapsize) ) / 2880); if (nblock > 0) { t2heapsize = (fptr->Fptr)->heapsize; /* save new heap size */ (fptr->Fptr)->heapsize = t1heapsize; /* restore original heap size */ ffdblk(fptr, nblock, status); (fptr->Fptr)->heapsize = t2heapsize; /* reset correct heap size */ } /* update the PCOUNT value (size of heap) */ ffgkyjj(fptr, "PCOUNT", &pcount, comm, status); if ((fptr->Fptr)->heapsize != pcount) { ffmkyj(fptr, "PCOUNT", (fptr->Fptr)->heapsize, comm, status); } ffrdef(fptr, status); /* rescan new HDU structure */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgdes(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG rownum, /* I - row number (1 = 1st row of table) */ long *length, /* O - number of elements in the row */ long *heapaddr, /* O - heap pointer to the data */ int *status) /* IO - error status */ /* get (read) the variable length vector descriptor from the table. */ { LONGLONG lengthjj, heapaddrjj; if (ffgdesll(fptr, colnum, rownum, &lengthjj, &heapaddrjj, status) > 0) return(*status); /* convert the temporary 8-byte values to 4-byte values */ /* check for overflow */ if (length) { if (lengthjj > LONG_MAX) *status = NUM_OVERFLOW; else *length = (long) lengthjj; } if (heapaddr) { if (heapaddrjj > LONG_MAX) *status = NUM_OVERFLOW; else *heapaddr = (long) heapaddrjj; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgdesll(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG rownum, /* I - row number (1 = 1st row of table) */ LONGLONG *length, /* O - number of elements in the row */ LONGLONG *heapaddr, /* O - heap pointer to the data */ int *status) /* IO - error status */ /* get (read) the variable length vector descriptor from the binary table. This is similar to ffgdes, except it supports the full 8-byte range of the length and offset values in 'Q' columns, as well as 'P' columns. */ { LONGLONG bytepos; unsigned int descript4[2] = {0,0}; LONGLONG descript8[2] = {0,0}; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* offset to the correct column */ if (colptr->tdatatype >= 0) { *status = NOT_VARI_LEN; return(*status); } bytepos = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * (rownum - 1)) + colptr->tbcol; if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P') { /* read 4-byte descriptor */ if (ffgi4b(fptr, bytepos, 2, 4, (INT32BIT *) descript4, status) <= 0) { if (length) *length = (LONGLONG) descript4[0]; /* 1st word is the length */ if (heapaddr) *heapaddr = (LONGLONG) descript4[1]; /* 2nd word is the address */ } } else /* this is for 'Q' columns */ { /* read 8 byte descriptor */ if (ffgi8b(fptr, bytepos, 2, 8, (long *) descript8, status) <= 0) { if (length) *length = descript8[0]; /* 1st word is the length */ if (heapaddr) *heapaddr = descript8[1]; /* 2nd word is the address */ } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgdess(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG firstrow, /* I - first row (1 = 1st row of table) */ LONGLONG nrows, /* I - number or rows to read */ long *length, /* O - number of elements in the row */ long *heapaddr, /* O - heap pointer to the data */ int *status) /* IO - error status */ /* get (read) a range of variable length vector descriptors from the table. */ { LONGLONG rowsize, bytepos; long ii; INT32BIT descript4[2] = {0,0}; LONGLONG descript8[2] = {0,0}; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* offset to the correct column */ if (colptr->tdatatype >= 0) { *status = NOT_VARI_LEN; return(*status); } rowsize = (fptr->Fptr)->rowlength; bytepos = (fptr->Fptr)->datastart + (rowsize * (firstrow - 1)) + colptr->tbcol; if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P') { /* read 4-byte descriptors */ for (ii = 0; ii < nrows; ii++) { /* read descriptors */ if (ffgi4b(fptr, bytepos, 2, 4, descript4, status) <= 0) { if (length) { *length = (long) descript4[0]; /* 1st word is the length */ length++; } if (heapaddr) { *heapaddr = (long) descript4[1]; /* 2nd word is the address */ heapaddr++; } bytepos += rowsize; } else return(*status); } } else /* this is for 'Q' columns */ { /* read 8-byte descriptors */ for (ii = 0; ii < nrows; ii++) { /* read descriptors */ if (ffgi8b(fptr, bytepos, 2, 8, (long *) descript8, status) <= 0) { if (length) { if (descript8[0] > LONG_MAX)*status = NUM_OVERFLOW; *length = (long) descript8[0]; /* 1st word is the length */ length++; } if (heapaddr) { if (descript8[1] > LONG_MAX)*status = NUM_OVERFLOW; *heapaddr = (long) descript8[1]; /* 2nd word is the address */ heapaddr++; } bytepos += rowsize; } else return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgdessll(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG firstrow, /* I - first row (1 = 1st row of table) */ LONGLONG nrows, /* I - number or rows to read */ LONGLONG *length, /* O - number of elements in the row */ LONGLONG *heapaddr, /* O - heap pointer to the data */ int *status) /* IO - error status */ /* get (read) a range of variable length vector descriptors from the table. */ { LONGLONG rowsize, bytepos; long ii; unsigned int descript4[2] = {0,0}; LONGLONG descript8[2] = {0,0}; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* offset to the correct column */ if (colptr->tdatatype >= 0) { *status = NOT_VARI_LEN; return(*status); } rowsize = (fptr->Fptr)->rowlength; bytepos = (fptr->Fptr)->datastart + (rowsize * (firstrow - 1)) + colptr->tbcol; if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P') { /* read 4-byte descriptors */ for (ii = 0; ii < nrows; ii++) { /* read descriptors */ if (ffgi4b(fptr, bytepos, 2, 4, (INT32BIT *) descript4, status) <= 0) { if (length) { *length = (LONGLONG) descript4[0]; /* 1st word is the length */ length++; } if (heapaddr) { *heapaddr = (LONGLONG) descript4[1]; /* 2nd word is the address */ heapaddr++; } bytepos += rowsize; } else return(*status); } } else /* this is for 'Q' columns */ { /* read 8-byte descriptors */ for (ii = 0; ii < nrows; ii++) { /* read descriptors */ /* cast to type (long *) even though it is actually (LONGLONG *) */ if (ffgi8b(fptr, bytepos, 2, 8, (long *) descript8, status) <= 0) { if (length) { *length = descript8[0]; /* 1st word is the length */ length++; } if (heapaddr) { *heapaddr = descript8[1]; /* 2nd word is the address */ heapaddr++; } bytepos += rowsize; } else return(*status); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffpdes(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number (1 = 1st column of table) */ LONGLONG rownum, /* I - row number (1 = 1st row of table) */ LONGLONG length, /* I - number of elements in the row */ LONGLONG heapaddr, /* I - heap pointer to the data */ int *status) /* IO - error status */ /* put (write) the variable length vector descriptor to the table. */ { LONGLONG bytepos; unsigned int descript4[2]; LONGLONG descript8[2]; tcolumn *colptr; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); colptr = (fptr->Fptr)->tableptr; /* point to first column structure */ colptr += (colnum - 1); /* offset to the correct column */ if (colptr->tdatatype >= 0) *status = NOT_VARI_LEN; bytepos = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * (rownum - 1)) + colptr->tbcol; ffmbyt(fptr, bytepos, IGNORE_EOF, status); /* move to element */ if (colptr->tform[0] == 'P' || colptr->tform[1] == 'P') { if (length > UINT_MAX || length < 0 || heapaddr > UINT_MAX || heapaddr < 0) { ffpmsg("P variable length column descriptor is out of range"); *status = NUM_OVERFLOW; return(*status); } descript4[0] = (unsigned int) length; /* 1st word is the length */ descript4[1] = (unsigned int) heapaddr; /* 2nd word is the address */ ffpi4b(fptr, 2, 4, (INT32BIT *) descript4, status); /* write the descriptor */ } else /* this is a 'Q' descriptor column */ { descript8[0] = length; /* 1st word is the length */ descript8[1] = heapaddr; /* 2nd word is the address */ ffpi8b(fptr, 2, 8, (long *) descript8, status); /* write the descriptor */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffchdu(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ { /* close the current HDU. If we have write access to the file, then: - write the END keyword and pad header with blanks if necessary - check the data fill values, and rewrite them if not correct */ char message[FLEN_ERRMSG]; /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* no need to do any further updating of the HDU */ } else if ((fptr->Fptr)->writemode == 1) { ffrdef(fptr, status); /* scan header to redefine structure */ if ((fptr->Fptr)->heapsize > 0) ffuptf(fptr, status); /* update the variable length TFORM values */ ffpdfl(fptr, status); /* insure correct data file values */ } if ((fptr->Fptr)->open_count == 1) { /* free memory for the CHDU structure only if no other files are using it */ if ((fptr->Fptr)->tableptr) { free((fptr->Fptr)->tableptr); (fptr->Fptr)->tableptr = NULL; } } if (*status > 0 && *status != NO_CLOSE_ERROR) { sprintf(message, "Error while closing HDU number %d (ffchdu).", (fptr->Fptr)->curhdu); ffpmsg(message); } return(*status); } /*--------------------------------------------------------------------------*/ int ffuptf(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Update the value of the TFORM keywords for the variable length array columns to make sure they all have the form 1Px(len) or Px(len) where 'len' is the maximum length of the vector in the table (e.g., '1PE(400)') */ { int ii; long tflds; LONGLONG length, addr, maxlen, naxis2, jj; char comment[FLEN_COMMENT], keyname[FLEN_KEYWORD]; char tform[FLEN_VALUE], newform[FLEN_VALUE], lenval[40]; char card[FLEN_CARD]; char message[FLEN_ERRMSG]; ffgkyj(fptr, "TFIELDS", &tflds, comment, status); ffgkyjj(fptr, "NAXIS2", &naxis2, comment, status); for (ii = 1; ii <= tflds; ii++) /* loop over all the columns */ { ffkeyn("TFORM", ii, keyname, status); /* construct name */ if (ffgkys(fptr, keyname, tform, comment, status) > 0) { sprintf(message, "Error while updating variable length vector TFORMn values (ffuptf)."); ffpmsg(message); return(*status); } /* is this a variable array length column ? */ if (tform[0] == 'P' || tform[1] == 'P' || tform[0] == 'Q' || tform[1] == 'Q') { if (strlen(tform) < 5) /* is maxlen field missing? */ { /* get the max length */ maxlen = 0; for (jj=1; jj <= naxis2; jj++) { ffgdesll(fptr, ii, jj, &length, &addr, status); if (length > maxlen) maxlen = length; } /* construct the new keyword value */ strcpy(newform, "'"); strcat(newform, tform); /* print as double, because the string-to-64-bit */ /* conversion is platform dependent (%lld, %ld, %I64d) */ sprintf(lenval, "(%.0f)", (double) maxlen); strcat(newform,lenval); while(strlen(newform) < 9) strcat(newform," "); /* append spaces 'till length = 8 */ strcat(newform,"'" ); /* append closing parenthesis */ /* would be simpler to just call ffmkyj here, but this */ /* would force linking in all the modkey & putkey routines */ ffmkky(keyname, newform, comment, card, status); /* make new card */ ffmkey(fptr, card, status); /* replace last read keyword */ } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffrdef(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* ReDEFine the structure of a data unit. This routine re-reads the CHDU header keywords to determine the structure and length of the current data unit. This redefines the start of the next HDU. */ { int dummy, tstatus = 0; LONGLONG naxis2; LONGLONG pcount; char card[FLEN_CARD], comm[FLEN_COMMENT], valstring[FLEN_VALUE]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->writemode == 1) /* write access to the file? */ { /* don't need to check NAXIS2 and PCOUNT if data hasn't been written */ if ((fptr->Fptr)->datastart != DATA_UNDEFINED) { /* update NAXIS2 keyword if more rows were written to the table */ /* and if the user has not explicitly reset the NAXIS2 value */ if ((fptr->Fptr)->hdutype != IMAGE_HDU) { if (ffgkyjj(fptr, "NAXIS2", &naxis2, comm, &tstatus) > 0) { /* Couldn't read NAXIS2 (odd!); in certain circumstances */ /* this may be normal, so ignore the error. */ naxis2 = (fptr->Fptr)->numrows; } if ((fptr->Fptr)->numrows > naxis2 && (fptr->Fptr)->origrows == naxis2) /* if origrows is not equal to naxis2, then the user must */ /* have manually modified the NAXIS2 keyword value, and */ /* we will assume that the current value is correct. */ { /* would be simpler to just call ffmkyj here, but this */ /* would force linking in all the modkey & putkey routines */ /* print as double because the 64-bit int conversion */ /* is platform dependent (%lld, %ld, %I64 ) */ sprintf(valstring, "%.0f", (double) ((fptr->Fptr)->numrows)); ffmkky("NAXIS2", valstring, comm, card, status); ffmkey(fptr, card, status); } } /* if data has been written to variable length columns in a */ /* binary table, then we may need to update the PCOUNT value */ if ((fptr->Fptr)->heapsize > 0) { ffgkyjj(fptr, "PCOUNT", &pcount, comm, status); if ((fptr->Fptr)->heapsize > pcount) { ffmkyj(fptr, "PCOUNT", (fptr->Fptr)->heapsize, comm, status); } } } if (ffwend(fptr, status) <= 0) /* rewrite END keyword and fill */ { ffrhdu(fptr, &dummy, status); /* re-scan the header keywords */ } } return(*status); } /*--------------------------------------------------------------------------*/ int ffhdef(fitsfile *fptr, /* I - FITS file pointer */ int morekeys, /* I - reserve space for this many keywords */ int *status) /* IO - error status */ /* based on the number of keywords which have already been written, plus the number of keywords to reserve space for, we then can define where the data unit should start (it must start at the beginning of a 2880-byte logical block). This routine will only have any effect if the starting location of the data unit following the header is not already defined. In any case, it is always possible to add more keywords to the header even if the data has already been written. It is just more efficient to reserve the space in advance. */ { LONGLONG delta; if (*status > 0 || morekeys < 1) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { ffrdef(fptr, status); /* ffrdef defines the offset to datastart and the start of */ /* the next HDU based on the number of existing keywords. */ /* We need to increment both of these values based on */ /* the number of new keywords to be added. */ delta = (((fptr->Fptr)->headend + (morekeys * 80)) / 2880 + 1) * 2880 - (fptr->Fptr)->datastart; (fptr->Fptr)->datastart += delta; (fptr->Fptr)->headstart[ (fptr->Fptr)->curhdu + 1] += delta; } return(*status); } /*--------------------------------------------------------------------------*/ int ffwend(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* write the END card and following fill (space chars) in the current header */ { int ii, tstatus; LONGLONG endpos; long nspace; char blankkey[FLEN_CARD], endkey[FLEN_CARD], keyrec[FLEN_CARD]; if (*status > 0) return(*status); endpos = (fptr->Fptr)->headend; /* we assume that the HDUposition == curhdu in all cases */ /* calc the data starting position if not currently defined */ if ((fptr->Fptr)->datastart == DATA_UNDEFINED) (fptr->Fptr)->datastart = ( endpos / 2880 + 1 ) * 2880; /* calculate the number of blank keyword slots in the header */ nspace = (long) (( (fptr->Fptr)->datastart - endpos ) / 80); /* construct a blank and END keyword (80 spaces ) */ strcpy(blankkey, " "); strcat(blankkey, " "); strcpy(endkey, "END "); strcat(endkey, " "); /* check if header is already correctly terminated with END and fill */ tstatus=0; ffmbyt(fptr, endpos, REPORT_EOF, &tstatus); /* move to header end */ for (ii=0; ii < nspace; ii++) { ffgbyt(fptr, 80, keyrec, &tstatus); /* get next keyword */ if (strncmp(keyrec, blankkey, 80) && strncmp(keyrec, endkey, 80)) break; } if (ii == nspace && !tstatus) { /* check if the END keyword exists at the correct position */ endpos=maxvalue( endpos, ( (fptr->Fptr)->datastart - 2880 ) ); ffmbyt(fptr, endpos, REPORT_EOF, &tstatus); /* move to END position */ ffgbyt(fptr, 80, keyrec, &tstatus); /* read the END keyword */ if ( !strncmp(keyrec, endkey, 80) && !tstatus) return(*status); /* END card was already correct */ } /* header was not correctly terminated, so write the END and blank fill */ endpos = (fptr->Fptr)->headend; ffmbyt(fptr, endpos, IGNORE_EOF, status); /* move to header end */ for (ii=0; ii < nspace; ii++) ffpbyt(fptr, 80, blankkey, status); /* write the blank keywords */ /* The END keyword must either be placed immediately after the last keyword that was written (as indicated by the headend value), or must be in the first 80 bytes of the 2880-byte FITS record immediately preceeding the data unit, whichever is further in the file. The latter will occur if space has been reserved for more header keywords which have not yet been written. */ endpos=maxvalue( endpos, ( (fptr->Fptr)->datastart - 2880 ) ); ffmbyt(fptr, endpos, REPORT_EOF, status); /* move to END position */ ffpbyt(fptr, 80, endkey, status); /* write the END keyword to header */ if (*status > 0) ffpmsg("Error while writing END card (ffwend)."); return(*status); } /*--------------------------------------------------------------------------*/ int ffpdfl(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Write the Data Unit Fill values if they are not already correct. The fill values are used to fill out the last 2880 byte block of the HDU. Fill the data unit with zeros or blanks depending on the type of HDU from the end of the data to the end of the current FITS 2880 byte block */ { char chfill, fill[2880]; LONGLONG fillstart; int nfill, tstatus, ii; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) return(*status); /* fill has already been correctly written */ if ((fptr->Fptr)->heapstart == 0) return(*status); /* null data unit, so there is no fill */ fillstart = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; nfill = (long) ((fillstart + 2879) / 2880 * 2880 - fillstart); if ((fptr->Fptr)->hdutype == ASCII_TBL) chfill = 32; /* ASCII tables are filled with spaces */ else chfill = 0; /* all other extensions are filled with zeros */ tstatus = 0; if (!nfill) /* no fill bytes; just check that entire table exists */ { fillstart--; nfill = 1; ffmbyt(fptr, fillstart, REPORT_EOF, &tstatus); /* move to last byte */ ffgbyt(fptr, nfill, fill, &tstatus); /* get the last byte */ if (tstatus == 0) return(*status); /* no EOF error, so everything is OK */ } else { ffmbyt(fptr, fillstart, REPORT_EOF, &tstatus); /* move to fill area */ ffgbyt(fptr, nfill, fill, &tstatus); /* get the fill bytes */ if (tstatus == 0) { for (ii = 0; ii < nfill; ii++) { if (fill[ii] != chfill) break; } if (ii == nfill) return(*status); /* all the fill values were correct */ } } /* fill values are incorrect or have not been written, so write them */ memset(fill, chfill, nfill); /* fill the buffer with the fill value */ ffmbyt(fptr, fillstart, IGNORE_EOF, status); /* move to fill area */ ffpbyt(fptr, nfill, fill, status); /* write the fill bytes */ if (*status > 0) ffpmsg("Error writing Data Unit fill bytes (ffpdfl)."); return(*status); } /********************************************************************** ffchfl : Check Header Fill values Check that the header unit is correctly filled with blanks from the END card to the end of the current FITS 2880-byte block Function parameters: fptr Fits file pointer status output error status Translated ftchfl into C by Peter Wilson, Oct. 1997 **********************************************************************/ int ffchfl( fitsfile *fptr, int *status) { int nblank,i,gotend; LONGLONG endpos; char rec[FLEN_CARD]; char *blanks=" "; /* 80 spaces */ if( *status > 0 ) return (*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* calculate the number of blank keyword slots in the header */ endpos=(fptr->Fptr)->headend; nblank=(long) (((fptr->Fptr)->datastart-endpos)/80); /* move the i/o pointer to the end of the header keywords */ ffmbyt(fptr,endpos,TRUE,status); /* find the END card (there may be blank keywords perceeding it) */ gotend=FALSE; for(i=0;i 0 ) { rec[FLEN_CARD - 1] = '\0'; /* make sure string is null terminated */ ffpmsg(rec); return( *status ); } } return( *status ); } /********************************************************************** ffcdfl : Check Data Unit Fill values Check that the data unit is correctly filled with zeros or blanks from the end of the data to the end of the current FITS 2880 byte block Function parameters: fptr Fits file pointer status output error status Translated ftcdfl into C by Peter Wilson, Oct. 1997 **********************************************************************/ int ffcdfl( fitsfile *fptr, int *status) { int nfill,i; LONGLONG filpos; char chfill,chbuff[2880]; if( *status > 0 ) return( *status ); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* check if the data unit is null */ if( (fptr->Fptr)->heapstart==0 ) return( *status ); /* calculate starting position of the fill bytes, if any */ filpos = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; /* calculate the number of fill bytes */ nfill = (long) ((filpos + 2879) / 2880 * 2880 - filpos); if( nfill == 0 ) return( *status ); /* move to the beginning of the fill bytes */ ffmbyt(fptr, filpos, FALSE, status); if( ffgbyt(fptr, nfill, chbuff, status) > 0) { ffpmsg("Error reading data unit fill bytes (ffcdfl)."); return( *status ); } if( (fptr->Fptr)->hdutype==ASCII_TBL ) chfill = 32; /* ASCII tables are filled with spaces */ else chfill = 0; /* all other extensions are filled with zeros */ /* check for all zeros or blanks */ for(i=0;iFptr)->hdutype==ASCII_TBL ) ffpmsg("Warning: remaining bytes following ASCII table data are not filled with blanks."); else ffpmsg("Warning: remaining bytes following data are not filled with zeros."); return( *status ); } } return( *status ); } /*--------------------------------------------------------------------------*/ int ffcrhd(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* CReate Header Data unit: Create, initialize, and move the i/o pointer to a new extension appended to the end of the FITS file. */ { int tstatus = 0; LONGLONG bytepos, *ptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* If the current header is empty, we don't have to do anything */ if ((fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) return(*status); while (ffmrhd(fptr, 1, 0, &tstatus) == 0); /* move to end of file */ if ((fptr->Fptr)->maxhdu == (fptr->Fptr)->MAXHDU) { /* allocate more space for the headstart array */ ptr = (LONGLONG*) realloc( (fptr->Fptr)->headstart, ((fptr->Fptr)->MAXHDU + 1001) * sizeof(LONGLONG) ); if (ptr == NULL) return (*status = MEMORY_ALLOCATION); else { (fptr->Fptr)->MAXHDU = (fptr->Fptr)->MAXHDU + 1000; (fptr->Fptr)->headstart = ptr; } } if (ffchdu(fptr, status) <= 0) /* close the current HDU */ { bytepos = (fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1]; /* last */ ffmbyt(fptr, bytepos, IGNORE_EOF, status); /* move file ptr to it */ (fptr->Fptr)->maxhdu++; /* increment the known number of HDUs */ (fptr->Fptr)->curhdu = (fptr->Fptr)->maxhdu; /* set current HDU loc */ fptr->HDUposition = (fptr->Fptr)->maxhdu; /* set current HDU loc */ (fptr->Fptr)->nextkey = bytepos; /* next keyword = start of header */ (fptr->Fptr)->headend = bytepos; /* end of header */ (fptr->Fptr)->datastart = DATA_UNDEFINED; /* start data unit undefined */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffdblk(fitsfile *fptr, /* I - FITS file pointer */ long nblocks, /* I - number of 2880-byte blocks to delete */ int *status) /* IO - error status */ /* Delete the specified number of 2880-byte blocks from the end of the CHDU by shifting all following extensions up this number of blocks. */ { char buffer[2880]; int tstatus, ii; LONGLONG readpos, writepos; if (*status > 0 || nblocks <= 0) return(*status); tstatus = 0; /* pointers to the read and write positions */ readpos = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; readpos = ((readpos + 2879) / 2880) * 2880; /* start of block */ /* the following formula is wrong because the current data unit may have been extended without updating the headstart value of the following HDU. readpos = (fptr->Fptr)->headstart[((fptr->Fptr)->curhdu) + 1]; */ writepos = readpos - ((LONGLONG)nblocks * 2880); while ( !ffmbyt(fptr, readpos, REPORT_EOF, &tstatus) && !ffgbyt(fptr, 2880L, buffer, &tstatus) ) { ffmbyt(fptr, writepos, REPORT_EOF, status); ffpbyt(fptr, 2880L, buffer, status); if (*status > 0) { ffpmsg("Error deleting FITS blocks (ffdblk)"); return(*status); } readpos += 2880; /* increment to next block to transfer */ writepos += 2880; } /* now fill the last nblock blocks with zeros */ memset(buffer, 0, 2880); ffmbyt(fptr, writepos, REPORT_EOF, status); for (ii = 0; ii < nblocks; ii++) ffpbyt(fptr, 2880L, buffer, status); /* move back before the deleted blocks, since they may be deleted */ /* and we do not want to delete the current active buffer */ ffmbyt(fptr, writepos - 1, REPORT_EOF, status); /* truncate the file to the new size, if supported on this device */ fftrun(fptr, writepos, status); /* recalculate the starting location of all subsequent HDUs */ for (ii = (fptr->Fptr)->curhdu; ii <= (fptr->Fptr)->maxhdu; ii++) (fptr->Fptr)->headstart[ii + 1] -= ((LONGLONG)nblocks * 2880); return(*status); } /*--------------------------------------------------------------------------*/ int ffghdt(fitsfile *fptr, /* I - FITS file pointer */ int *exttype, /* O - type of extension, 0, 1, or 2 */ /* for IMAGE_HDU, ASCII_TBL, or BINARY_TBL */ int *status) /* IO - error status */ /* Return the type of the CHDU. This returns the 'logical' type of the HDU, not necessarily the physical type, so in the case of a compressed image stored in a binary table, this will return the type as an Image, not a binary table. */ { if (*status > 0) return(*status); if (fptr->HDUposition == 0 && (fptr->Fptr)->headend == 0) { /* empty primary array is alway an IMAGE_HDU */ *exttype = IMAGE_HDU; } else { /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { /* rescan header if data structure is undefined */ if ( ffrdef(fptr, status) > 0) return(*status); } *exttype = (fptr->Fptr)->hdutype; /* return the type of HDU */ /* check if this is a compressed image */ if ((fptr->Fptr)->compressimg) *exttype = IMAGE_HDU; } return(*status); } /*--------------------------------------------------------------------------*/ int fits_is_compressed_image(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Returns TRUE if the CHDU is a compressed image, else returns zero. */ { if (*status > 0) return(0); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { /* rescan header if data structure is undefined */ if ( ffrdef(fptr, status) > 0) return(*status); } /* check if this is a compressed image */ if ((fptr->Fptr)->compressimg) return(1); return(0); } /*--------------------------------------------------------------------------*/ int ffgipr(fitsfile *infptr, /* I - FITS file pointer */ int maxaxis, /* I - max number of axes to return */ int *bitpix, /* O - image data type */ int *naxis, /* O - image dimension (NAXIS value) */ long *naxes, /* O - size of image dimensions */ int *status) /* IO - error status */ /* get the datatype and size of the input image */ { if (*status > 0) return(*status); /* don't return the parameter if a null pointer was given */ if (bitpix) fits_get_img_type(infptr, bitpix, status); /* get BITPIX value */ if (naxis) fits_get_img_dim(infptr, naxis, status); /* get NAXIS value */ if (naxes) fits_get_img_size(infptr, maxaxis, naxes, status); /* get NAXISn values */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgiprll(fitsfile *infptr, /* I - FITS file pointer */ int maxaxis, /* I - max number of axes to return */ int *bitpix, /* O - image data type */ int *naxis, /* O - image dimension (NAXIS value) */ LONGLONG *naxes, /* O - size of image dimensions */ int *status) /* IO - error status */ /* get the datatype and size of the input image */ { if (*status > 0) return(*status); /* don't return the parameter if a null pointer was given */ if (bitpix) fits_get_img_type(infptr, bitpix, status); /* get BITPIX value */ if (naxis) fits_get_img_dim(infptr, naxis, status); /* get NAXIS value */ if (naxes) fits_get_img_sizell(infptr, maxaxis, naxes, status); /* get NAXISn values */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgidt( fitsfile *fptr, /* I - FITS file pointer */ int *imgtype, /* O - image data type */ int *status) /* IO - error status */ /* Get the datatype of the image (= BITPIX keyword for normal image, or ZBITPIX for a compressed image) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffgky(fptr, TINT, "BITPIX", imgtype, NULL, status); } else if ((fptr->Fptr)->compressimg) { /* this is a binary table containing a compressed image */ ffgky(fptr, TINT, "ZBITPIX", imgtype, NULL, status); } else { *status = NOT_IMAGE; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgiet( fitsfile *fptr, /* I - FITS file pointer */ int *imgtype, /* O - image data type */ int *status) /* IO - error status */ /* Get the effective datatype of the image (= BITPIX keyword for normal image, or ZBITPIX for a compressed image) */ { int tstatus; long lngscale = 1, lngzero = 0; double bscale, bzero, min_val, max_val; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffgky(fptr, TINT, "BITPIX", imgtype, NULL, status); tstatus = 0; ffgky(fptr, TDOUBLE, "BSCALE", &bscale, NULL, &tstatus); if (tstatus) bscale = 1.0; tstatus = 0; ffgky(fptr, TDOUBLE, "BZERO", &bzero, NULL, &tstatus); if (tstatus) bzero = 0.0; } else if ((fptr->Fptr)->compressimg) { /* this is a binary table containing a compressed image */ ffgky(fptr, TINT, "ZBITPIX", imgtype, NULL, status); } else { *status = NOT_IMAGE; return(*status); } /* check if the BSCALE and BZERO keywords are defined, which might change the effective datatype of the image */ tstatus = 0; ffgky(fptr, TDOUBLE, "BSCALE", &bscale, NULL, &tstatus); if (tstatus) bscale = 1.0; tstatus = 0; ffgky(fptr, TDOUBLE, "BZERO", &bzero, NULL, &tstatus); if (tstatus) bzero = 0.0; if (bscale == 1.0 && bzero == 0.0) /* no scaling */ return(*status); switch (*imgtype) { case BYTE_IMG: /* 8-bit image */ min_val = 0.; max_val = 255.0; break; case SHORT_IMG: min_val = -32768.0; max_val = 32767.0; break; case LONG_IMG: min_val = -2147483648.0; max_val = 2147483647.0; break; default: /* don't have to deal with other data types */ return(*status); } if (bscale >= 0.) { min_val = bzero + bscale * min_val; max_val = bzero + bscale * max_val; } else { max_val = bzero + bscale * min_val; min_val = bzero + bscale * max_val; } if (bzero < 2147483648.) /* don't exceed range of 32-bit integer */ lngzero = (long) bzero; lngscale = (long) bscale; if ((bzero != 2147483648.) && /* special value that exceeds integer range */ (lngzero != bzero || lngscale != bscale)) { /* not integers? */ /* floating point scaled values; just decide on required precision */ if (*imgtype == BYTE_IMG || *imgtype == SHORT_IMG) *imgtype = FLOAT_IMG; else *imgtype = DOUBLE_IMG; /* In all the remaining cases, BSCALE and BZERO are integers, and not equal to 1 and 0, respectively. */ } else if ((min_val == -128.) && (max_val == 127.)) { *imgtype = SBYTE_IMG; } else if ((min_val >= -32768.0) && (max_val <= 32767.0)) { *imgtype = SHORT_IMG; } else if ((min_val >= 0.0) && (max_val <= 65535.0)) { *imgtype = USHORT_IMG; } else if ((min_val >= -2147483648.0) && (max_val <= 2147483647.0)) { *imgtype = LONG_IMG; } else if ((min_val >= 0.0) && (max_val < 4294967296.0)) { *imgtype = ULONG_IMG; } else { /* exceeds the range of a 32-bit integer */ *imgtype = DOUBLE_IMG; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgidm( fitsfile *fptr, /* I - FITS file pointer */ int *naxis , /* O - image dimension (NAXIS value) */ int *status) /* IO - error status */ /* Get the dimension of the image (= NAXIS keyword for normal image, or ZNAXIS for a compressed image) */ { if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { ffgky(fptr, TINT, "NAXIS", naxis, NULL, status); } else if ((fptr->Fptr)->compressimg) { /* this is a binary table containing a compressed image */ ffgky(fptr, TINT, "ZNAXIS", naxis, NULL, status); } else { *status = NOT_IMAGE; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgisz( fitsfile *fptr, /* I - FITS file pointer */ int nlen, /* I - number of axes to return */ long *naxes, /* O - size of image dimensions */ int *status) /* IO - error status */ /* Get the size of the image dimensions (= NAXISn keywords for normal image, or ZNAXISn for a compressed image) */ { int ii, naxis; char keyroot[FLEN_KEYWORD], keyname[FLEN_KEYWORD]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { strcpy(keyroot, "NAXIS"); } else if ((fptr->Fptr)->compressimg) { /* this is a binary table containing a compressed image */ strcpy(keyroot, "ZNAXIS"); } else { return(*status = NOT_IMAGE); } /* initialize to 1 */ for (ii = 0; ii < nlen; ii++) naxes[ii] = 1; /* get number of dimensions */ fits_get_img_dim(fptr, &naxis, status); naxis = minvalue(naxis, nlen); for (ii = 0; ii < naxis; ii++) { ffkeyn(keyroot, ii + 1, keyname, status); ffgkyj(fptr, keyname, naxes + ii, NULL, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgiszll( fitsfile *fptr, /* I - FITS file pointer */ int nlen, /* I - number of axes to return */ LONGLONG *naxes, /* O - size of image dimensions */ int *status) /* IO - error status */ /* Get the size of the image dimensions (= NAXISn keywords for normal image, or ZNAXISn for a compressed image) */ { int ii, naxis; char keyroot[FLEN_KEYWORD], keyname[FLEN_KEYWORD]; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); if ((fptr->Fptr)->hdutype == IMAGE_HDU) { strcpy(keyroot, "NAXIS"); } else if ((fptr->Fptr)->compressimg) { /* this is a binary table containing a compressed image */ strcpy(keyroot, "ZNAXIS"); } else { return(*status = NOT_IMAGE); } /* initialize to 1 */ for (ii = 0; ii < nlen; ii++) naxes[ii] = 1; /* get number of dimensions */ fits_get_img_dim(fptr, &naxis, status); naxis = minvalue(naxis, nlen); for (ii = 0; ii < naxis; ii++) { ffkeyn(keyroot, ii + 1, keyname, status); ffgkyjj(fptr, keyname, naxes + ii, NULL, status); } return(*status); }/*--------------------------------------------------------------------------*/ int ffmahd(fitsfile *fptr, /* I - FITS file pointer */ int hdunum, /* I - number of the HDU to move to */ int *exttype, /* O - type of extension, 0, 1, or 2 */ int *status) /* IO - error status */ /* Move to Absolute Header Data unit. Move to the specified HDU and read the header to initialize the table structure. Note that extnum is one based, so the primary array is extnum = 1. */ { int moveto, tstatus; char message[FLEN_ERRMSG]; LONGLONG *ptr; if (*status > 0) return(*status); else if (hdunum < 1 ) return(*status = BAD_HDU_NUM); else if (hdunum >= (fptr->Fptr)->MAXHDU ) { /* allocate more space for the headstart array */ ptr = (LONGLONG*) realloc( (fptr->Fptr)->headstart, (hdunum + 1001) * sizeof(LONGLONG) ); if (ptr == NULL) return (*status = MEMORY_ALLOCATION); else { (fptr->Fptr)->MAXHDU = hdunum + 1000; (fptr->Fptr)->headstart = ptr; } } /* set logical HDU position to the actual position, in case they differ */ fptr->HDUposition = (fptr->Fptr)->curhdu; while( ((fptr->Fptr)->curhdu) + 1 != hdunum) /* at the correct HDU? */ { /* move directly to the extension if we know that it exists, otherwise move to the highest known extension. */ moveto = minvalue(hdunum - 1, ((fptr->Fptr)->maxhdu) + 1); /* test if HDU exists */ if ((fptr->Fptr)->headstart[moveto] < (fptr->Fptr)->logfilesize ) { if (ffchdu(fptr, status) <= 0) /* close out the current HDU */ { if (ffgext(fptr, moveto, exttype, status) > 0) { /* failed to get the requested extension */ tstatus = 0; ffrhdu(fptr, exttype, &tstatus); /* restore the CHDU */ } } } else *status = END_OF_FILE; if (*status > 0) { if (*status != END_OF_FILE) { /* don't clutter up the message stack in the common case of */ /* simply hitting the end of file (often an expected error) */ sprintf(message, "Failed to move to HDU number %d (ffmahd).", hdunum); ffpmsg(message); } return(*status); } } /* return the type of HDU; tile compressed images which are stored */ /* in a binary table will return exttype = IMAGE_HDU, not BINARY_TBL */ if (exttype != NULL) ffghdt(fptr, exttype, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmrhd(fitsfile *fptr, /* I - FITS file pointer */ int hdumov, /* I - rel. no. of HDUs to move by (+ or -) */ int *exttype, /* O - type of extension, 0, 1, or 2 */ int *status) /* IO - error status */ /* Move a Relative number of Header Data units. Offset to the specified extension and read the header to initialize the HDU structure. */ { int extnum; if (*status > 0) return(*status); extnum = fptr->HDUposition + 1 + hdumov; /* the absolute HDU number */ ffmahd(fptr, extnum, exttype, status); /* move to the HDU */ return(*status); } /*--------------------------------------------------------------------------*/ int ffmnhd(fitsfile *fptr, /* I - FITS file pointer */ int exttype, /* I - desired extension type */ char *hduname, /* I - desired EXTNAME value for the HDU */ int hduver, /* I - desired EXTVERS value for the HDU */ int *status) /* IO - error status */ /* Move to the next HDU with a given extension type (IMAGE_HDU, ASCII_TBL, BINARY_TBL, or ANY_HDU), extension name (EXTNAME or HDUNAME keyword), and EXTVERS keyword values. If hduvers = 0, then move to the first HDU with the given type and name regardless of EXTVERS value. If no matching HDU is found in the file, then the current open HDU will remain unchanged. */ { char extname[FLEN_VALUE]; int ii, hdutype, alttype, extnum, tstatus, match, exact; long extver; if (*status > 0) return(*status); extnum = fptr->HDUposition + 1; /* save the current HDU number */ for (ii=1; 1; ii++) /* loop until EOF */ { tstatus = 0; if (ffmahd(fptr, ii, &hdutype, &tstatus)) /* move to next HDU */ { ffmahd(fptr, extnum, 0, status); /* restore file position */ return(*status = BAD_HDU_NUM); /* couldn't find desired HDU */ } alttype = -1; if (fits_is_compressed_image(fptr, status)) alttype = BINARY_TBL; /* matching type? */ if (exttype == ANY_HDU || hdutype == exttype || hdutype == alttype) { if (ffgkys(fptr, "EXTNAME", extname, 0, &tstatus) > 0) /* name */ { tstatus = 0; /* look for HDUNAME, since EXTNAME didn't exist */ ffgkys(fptr, "HDUNAME", extname, 0, &tstatus); } else { /* check if EXTNAME is the name we are looking for. */ /* If not, try reading the HDUNAME keyword. */ ffcmps(extname, hduname, CASEINSEN, &match, &exact); if (!exact) ffgkys(fptr, "HDUNAME", extname, 0, &tstatus); } if (tstatus <= 0) { ffcmps(extname, hduname, CASEINSEN, &match, &exact); if (exact) /* names match? */ { if (hduver) /* need to check if version numbers match? */ { if (ffgkyj(fptr, "EXTVER", &extver, 0, &tstatus) > 0) extver = 1; /* assume default EXTVER value */ if ( (int) extver == hduver) { return(*status); /* found matching name and vers */ } } else { return(*status); /* found matching name */ } } } } } } /*--------------------------------------------------------------------------*/ int ffthdu(fitsfile *fptr, /* I - FITS file pointer */ int *nhdu, /* O - number of HDUs in the file */ int *status) /* IO - error status */ /* Return the number of HDUs that currently exist in the file. */ { int ii, extnum, tstatus; if (*status > 0) return(*status); extnum = fptr->HDUposition + 1; /* save the current HDU number */ *nhdu = extnum - 1; /* if the CHDU is empty or not completely defined, just return */ if ((fptr->Fptr)->datastart == DATA_UNDEFINED) return(*status); tstatus = 0; /* loop until EOF */ for (ii=extnum; ffmahd(fptr, ii, 0, &tstatus) <= 0; ii++) { *nhdu = ii; } ffmahd(fptr, extnum, 0, status); /* restore orig file position */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgext(fitsfile *fptr, /* I - FITS file pointer */ int hdunum, /* I - no. of HDU to move get (0 based) */ int *exttype, /* O - type of extension, 0, 1, or 2 */ int *status) /* IO - error status */ /* Get Extension. Move to the specified extension and initialize the HDU structure. */ { int xcurhdu, xmaxhdu; LONGLONG xheadend; if (*status > 0) return(*status); if (ffmbyt(fptr, (fptr->Fptr)->headstart[hdunum], REPORT_EOF, status) <= 0) { /* temporarily save current values, in case of error */ xcurhdu = (fptr->Fptr)->curhdu; xmaxhdu = (fptr->Fptr)->maxhdu; xheadend = (fptr->Fptr)->headend; /* set new parameter values */ (fptr->Fptr)->curhdu = hdunum; fptr->HDUposition = hdunum; (fptr->Fptr)->maxhdu = maxvalue((fptr->Fptr)->maxhdu, hdunum); (fptr->Fptr)->headend = (fptr->Fptr)->logfilesize; /* set max size */ if (ffrhdu(fptr, exttype, status) > 0) { /* failed to get the new HDU, so restore previous values */ (fptr->Fptr)->curhdu = xcurhdu; fptr->HDUposition = xcurhdu; (fptr->Fptr)->maxhdu = xmaxhdu; (fptr->Fptr)->headend = xheadend; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffiblk(fitsfile *fptr, /* I - FITS file pointer */ long nblock, /* I - no. of blocks to insert */ int headdata, /* I - insert where? 0=header, 1=data */ /* -1=beginning of file */ int *status) /* IO - error status */ /* insert 2880-byte blocks at the end of the current header or data unit */ { int tstatus, savehdu, typhdu; LONGLONG insertpt, jpoint; long ii, nshift; char charfill; char buff1[2880], buff2[2880]; char *inbuff, *outbuff, *tmpbuff; char card[FLEN_CARD]; if (*status > 0 || nblock <= 0) return(*status); tstatus = *status; if (headdata == 0 || (fptr->Fptr)->hdutype == ASCII_TBL) charfill = 32; /* headers and ASCII tables have space (32) fill */ else charfill = 0; /* images and binary tables have zero fill */ if (headdata == 0) insertpt = (fptr->Fptr)->datastart; /* insert just before data, or */ else if (headdata == -1) { insertpt = 0; strcpy(card, "XTENSION= 'IMAGE ' / IMAGE extension"); } else /* at end of data, */ { insertpt = (fptr->Fptr)->datastart + (fptr->Fptr)->heapstart + (fptr->Fptr)->heapsize; insertpt = ((insertpt + 2879) / 2880) * 2880; /* start of block */ /* the following formula is wrong because the current data unit may have been extended without updating the headstart value of the following HDU. */ /* insertpt = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu + 1]; */ } inbuff = buff1; /* set pointers to input and output buffers */ outbuff = buff2; memset(outbuff, charfill, 2880); /* initialize buffer with fill */ if (nblock == 1) /* insert one block */ { if (headdata == -1) ffmrec(fptr, 1, card, status); /* change SIMPLE -> XTENSION */ ffmbyt(fptr, insertpt, REPORT_EOF, status); /* move to 1st point */ ffgbyt(fptr, 2880, inbuff, status); /* read first block of bytes */ while (*status <= 0) { ffmbyt(fptr, insertpt, REPORT_EOF, status); /* insert point */ ffpbyt(fptr, 2880, outbuff, status); /* write the output buffer */ if (*status > 0) return(*status); tmpbuff = inbuff; /* swap input and output pointers */ inbuff = outbuff; outbuff = tmpbuff; insertpt += 2880; /* increment insert point by 1 block */ ffmbyt(fptr, insertpt, REPORT_EOF, status); /* move to next block */ ffgbyt(fptr, 2880, inbuff, status); /* read block of bytes */ } *status = tstatus; /* reset status value */ ffmbyt(fptr, insertpt, IGNORE_EOF, status); /* move back to insert pt */ ffpbyt(fptr, 2880, outbuff, status); /* write the final block */ } else /* inserting more than 1 block */ { savehdu = (fptr->Fptr)->curhdu; /* save the current HDU number */ tstatus = *status; while(*status <= 0) /* find the last HDU in file */ ffmrhd(fptr, 1, &typhdu, status); if (*status == END_OF_FILE) { *status = tstatus; } ffmahd(fptr, savehdu + 1, &typhdu, status); /* move back to CHDU */ if (headdata == -1) ffmrec(fptr, 1, card, status); /* NOW change SIMPLE -> XTENSION */ /* number of 2880-byte blocks that have to be shifted down */ nshift = (long) (((fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1] - insertpt) / 2880); /* position of last block in file to be shifted */ jpoint = (fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1] - 2880; /* move all the blocks starting at end of file working backwards */ for (ii = 0; ii < nshift; ii++) { /* move to the read start position */ if (ffmbyt(fptr, jpoint, REPORT_EOF, status) > 0) return(*status); ffgbyt(fptr, 2880, inbuff,status); /* read one record */ /* move forward to the write postion */ ffmbyt(fptr, jpoint + (nblock * 2880), IGNORE_EOF, status); ffpbyt(fptr, 2880, inbuff, status); /* write the record */ jpoint -= 2880; } /* move back to the write start postion (might be EOF) */ ffmbyt(fptr, insertpt, IGNORE_EOF, status); for (ii = 0; ii < nblock; ii++) /* insert correct fill value */ ffpbyt(fptr, 2880, outbuff, status); } if (headdata == 0) /* update data start address */ (fptr->Fptr)->datastart += ((LONGLONG)nblock * 2880); /* update following HDU addresses */ for (ii = (fptr->Fptr)->curhdu; ii <= (fptr->Fptr)->maxhdu; ii++) (fptr->Fptr)->headstart[ii + 1] += ((LONGLONG)nblock * 2880); return(*status); } /*--------------------------------------------------------------------------*/ int ffgkcl(char *tcard) /* Return the type classification of the input header record TYP_STRUC_KEY: SIMPLE, BITPIX, NAXIS, NAXISn, EXTEND, BLOCKED, GROUPS, PCOUNT, GCOUNT, END XTENSION, TFIELDS, TTYPEn, TBCOLn, TFORMn, THEAP, and the first 4 COMMENT keywords in the primary array that define the FITS format. TYP_CMPRS_KEY: The experimental keywords used in the compressed image format ZIMAGE, ZCMPTYPE, ZNAMEn, ZVALn, ZTILEn, ZBITPIX, ZNAXISn, ZSCALE, ZZERO, ZBLANK, EXTNAME = 'COMPRESSED_IMAGE' ZSIMPLE, ZTENSION, ZEXTEND, ZBLOCKED, ZPCOUNT, ZGCOUNT TYP_SCAL_KEY: BSCALE, BZERO, TSCALn, TZEROn TYP_NULL_KEY: BLANK, TNULLn TYP_DIM_KEY: TDIMn TYP_RANG_KEY: TLMINn, TLMAXn, TDMINn, TDMAXn, DATAMIN, DATAMAX TYP_UNIT_KEY: BUNIT, TUNITn TYP_DISP_KEY: TDISPn TYP_HDUID_KEY: EXTNAME, EXTVER, EXTLEVEL, HDUNAME, HDUVER, HDULEVEL TYP_CKSUM_KEY CHECKSUM, DATASUM TYP_WCS_KEY: Primary array: WCAXES, CTYPEn, CUNITn, CRVALn, CRPIXn, CROTAn, CDELTn CDj_is, PVj_ms, LONPOLEs, LATPOLEs Pixel list: TCTYPn, TCTYns, TCUNIn, TCUNns, TCRVLn, TCRVns, TCRPXn, TCRPks, TCDn_k, TCn_ks, TPVn_m, TPn_ms, TCDLTn, TCROTn Bintable vector: jCTYPn, jCTYns, jCUNIn, jCUNns, jCRVLn, jCRVns, iCRPXn, iCRPns, jiCDn, jiCDns, jPVn_m, jPn_ms, jCDLTn, jCROTn TYP_REFSYS_KEY: EQUINOXs, EPOCH, MJD-OBSs, RADECSYS, RADESYSs TYP_COMM_KEY: COMMENT, HISTORY, (blank keyword) TYP_CONT_KEY: CONTINUE TYP_USER_KEY: all other keywords */ { char card[20], *card1, *card5; card[0] = '\0'; strncat(card, tcard, 8); /* copy the keyword name */ strcat(card, " "); /* append blanks to make at least 8 chars long */ ffupch(card); /* make sure it is in upper case */ card1 = card + 1; /* pointer to 2nd character */ card5 = card + 5; /* pointer to 6th character */ /* the strncmp function is slow, so try to be more efficient */ if (*card == 'Z') { if (FSTRNCMP (card1, "IMAGE ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "CMPTYPE", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "NAME", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_CMPRS_KEY); } else if (FSTRNCMP (card1, "VAL", 3) == 0) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_CMPRS_KEY); } else if (FSTRNCMP (card1, "TILE", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_CMPRS_KEY); } else if (FSTRNCMP (card1, "BITPIX ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "NAXIS", 5) == 0) { if ( ( *(card + 6) >= '0' && *(card + 6) <= '9' ) || (*(card + 6) == ' ') ) return (TYP_CMPRS_KEY); } else if (FSTRNCMP (card1, "SCALE ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "ZERO ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "BLANK ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "SIMPLE ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "TENSION", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "EXTEND ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "BLOCKED", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "PCOUNT ", 7) == 0) return (TYP_CMPRS_KEY); else if (FSTRNCMP (card1, "GCOUNT ", 7) == 0) return (TYP_CMPRS_KEY); } else if (*card == ' ') { return (TYP_COMM_KEY); } else if (*card == 'B') { if (FSTRNCMP (card1, "ITPIX ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "LOCKED ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "LANK ", 7) == 0) return (TYP_NULL_KEY); if (FSTRNCMP (card1, "SCALE ", 7) == 0) return (TYP_SCAL_KEY); if (FSTRNCMP (card1, "ZERO ", 7) == 0) return (TYP_SCAL_KEY); if (FSTRNCMP (card1, "UNIT ", 7) == 0) return (TYP_UNIT_KEY); } else if (*card == 'C') { if (FSTRNCMP (card1, "OMMENT",6) == 0) { /* new comment string starting Oct 2001 */ if (FSTRNCMP (tcard, "COMMENT and Astrophysics', volume 376, page 3", 47) == 0) return (TYP_STRUC_KEY); /* original COMMENT strings from 1993 - 2001 */ if (FSTRNCMP (tcard, "COMMENT FITS (Flexible Image Transport System", 47) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (tcard, "COMMENT Astrophysics Supplement Series v44/p3", 47) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (tcard, "COMMENT Contact the NASA Science Office of St", 47) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (tcard, "COMMENT FITS Definition document #100 and oth", 47) == 0) return (TYP_STRUC_KEY); if (*(card + 7) == ' ') return (TYP_COMM_KEY); else return (TYP_USER_KEY); } if (FSTRNCMP (card1, "HECKSUM", 7) == 0) return (TYP_CKSUM_KEY); if (FSTRNCMP (card1, "ONTINUE", 7) == 0) return (TYP_CONT_KEY); if (FSTRNCMP (card1, "TYPE",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "UNIT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "RVAL",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "RPIX",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "ROTA",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "RDER",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "SYER",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "DELT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (*card1 == 'D') { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } } else if (*card == 'D') { if (FSTRNCMP (card1, "ATASUM ", 7) == 0) return (TYP_CKSUM_KEY); if (FSTRNCMP (card1, "ATAMIN ", 7) == 0) return (TYP_RANG_KEY); if (FSTRNCMP (card1, "ATAMAX ", 7) == 0) return (TYP_RANG_KEY); if (FSTRNCMP (card1, "ATE-OBS", 7) == 0) return (TYP_REFSYS_KEY); } else if (*card == 'E') { if (FSTRNCMP (card1, "XTEND ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "ND ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "XTNAME ", 7) == 0) { /* check for special compressed image value */ if (FSTRNCMP(tcard, "EXTNAME = 'COMPRESSED_IMAGE'", 28) == 0) return (TYP_CMPRS_KEY); else return (TYP_HDUID_KEY); } if (FSTRNCMP (card1, "XTVER ", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "XTLEVEL", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "QUINOX", 6) == 0) return (TYP_REFSYS_KEY); if (FSTRNCMP (card1, "QUI",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_REFSYS_KEY); } if (FSTRNCMP (card1, "POCH ", 7) == 0) return (TYP_REFSYS_KEY); } else if (*card == 'G') { if (FSTRNCMP (card1, "COUNT ", 7) == 0) return (TYP_STRUC_KEY); if (FSTRNCMP (card1, "ROUPS ", 7) == 0) return (TYP_STRUC_KEY); } else if (*card == 'H') { if (FSTRNCMP (card1, "DUNAME ", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "DUVER ", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "DULEVEL", 7) == 0) return (TYP_HDUID_KEY); if (FSTRNCMP (card1, "ISTORY",6) == 0) { if (*(card + 7) == ' ') return (TYP_COMM_KEY); else return (TYP_USER_KEY); } } else if (*card == 'L') { if (FSTRNCMP (card1, "ONPOLE",6) == 0) return (TYP_WCS_KEY); if (FSTRNCMP (card1, "ATPOLE",6) == 0) return (TYP_WCS_KEY); if (FSTRNCMP (card1, "ONP",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "ATP",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } } else if (*card == 'M') { if (FSTRNCMP (card1, "JD-OBS ", 7) == 0) return (TYP_REFSYS_KEY); if (FSTRNCMP (card1, "JDOB",4) == 0) { if (*(card+5) >= '0' && *(card+5) <= '9') return (TYP_REFSYS_KEY); } } else if (*card == 'N') { if (FSTRNCMP (card1, "AXIS", 4) == 0) { if ((*card5 >= '0' && *card5 <= '9') || (*card5 == ' ')) return (TYP_STRUC_KEY); } } else if (*card == 'P') { if (FSTRNCMP (card1, "COUNT ", 7) == 0) return (TYP_STRUC_KEY); if (*card1 == 'C') { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (*card1 == 'V') { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (*card1 == 'S') { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } } else if (*card == 'R') { if (FSTRNCMP (card1, "ADECSYS", 7) == 0) return (TYP_REFSYS_KEY); if (FSTRNCMP (card1, "ADESYS", 6) == 0) return (TYP_REFSYS_KEY); if (FSTRNCMP (card1, "ADE",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_REFSYS_KEY); } } else if (*card == 'S') { if (FSTRNCMP (card1, "IMPLE ", 7) == 0) return (TYP_STRUC_KEY); } else if (*card == 'T') { if (FSTRNCMP (card1, "TYPE", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_STRUC_KEY); } else if (FSTRNCMP (card1, "FORM", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_STRUC_KEY); } else if (FSTRNCMP (card1, "BCOL", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_STRUC_KEY); } else if (FSTRNCMP (card1, "FIELDS ", 7) == 0) return (TYP_STRUC_KEY); else if (FSTRNCMP (card1, "HEAP ", 7) == 0) return (TYP_STRUC_KEY); else if (FSTRNCMP (card1, "NULL", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_NULL_KEY); } else if (FSTRNCMP (card1, "DIM", 3) == 0) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_DIM_KEY); } else if (FSTRNCMP (card1, "UNIT", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_UNIT_KEY); } else if (FSTRNCMP (card1, "DISP", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_DISP_KEY); } else if (FSTRNCMP (card1, "SCAL", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_SCAL_KEY); } else if (FSTRNCMP (card1, "ZERO", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_SCAL_KEY); } else if (FSTRNCMP (card1, "LMIN", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_RANG_KEY); } else if (FSTRNCMP (card1, "LMAX", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_RANG_KEY); } else if (FSTRNCMP (card1, "DMIN", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_RANG_KEY); } else if (FSTRNCMP (card1, "DMAX", 4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_RANG_KEY); } else if (FSTRNCMP (card1, "CTYP",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CTY",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CUNI",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CUN",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRVL",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRV",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRPX",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRP",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CROT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CDLT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CDE",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRD",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CSY",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "WCS",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "C",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "P",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "V",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "S",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } } else if (*card == 'X') { if (FSTRNCMP (card1, "TENSION", 7) == 0) return (TYP_STRUC_KEY); } else if (*card == 'W') { if (FSTRNCMP (card1, "CSAXES", 6) == 0) return (TYP_WCS_KEY); if (FSTRNCMP (card1, "CSNAME", 6) == 0) return (TYP_WCS_KEY); if (FSTRNCMP (card1, "CAX", 3) == 0) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CSN", 3) == 0) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_WCS_KEY); } } else if (*card >= '0' && *card <= '9') { if (*card1 == 'C') { if (FSTRNCMP (card1, "CTYP",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CTY",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CUNI",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CUN",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRVL",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRV",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRPX",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRP",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CROT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CDLT",4) == 0) { if (*card5 >= '0' && *card5 <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CDE",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CRD",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "CSY",3) == 0) { if (*(card+4) >= '0' && *(card+4) <= '9') return (TYP_WCS_KEY); } } else if (FSTRNCMP (card1, "V",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (FSTRNCMP (card1, "S",1) == 0) { if (*(card + 2) >= '0' && *(card + 2) <= '9') return (TYP_WCS_KEY); } else if (*card1 >= '0' && *card1 <= '9') { /* 2 digits at beginning of keyword */ if ( (*(card + 2) == 'P') && (*(card + 3) == 'C') ) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_WCS_KEY); /* ijPCn keyword */ } else if ( (*(card + 2) == 'C') && (*(card + 3) == 'D') ) { if (*(card + 4) >= '0' && *(card + 4) <= '9') return (TYP_WCS_KEY); /* ijCDn keyword */ } } } return (TYP_USER_KEY); /* by default all others are user keywords */ } /*--------------------------------------------------------------------------*/ int ffdtyp(char *cval, /* I - formatted string representation of the value */ char *dtype, /* O - datatype code: C, L, F, I, or X */ int *status) /* IO - error status */ /* determine implicit datatype of input string. This assumes that the string conforms to the FITS standard for keyword values, so may not detect all invalid formats. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); else if (cval[0] == '\'') *dtype = 'C'; /* character string starts with a quote */ else if (cval[0] == 'T' || cval[0] == 'F') *dtype = 'L'; /* logical = T or F character */ else if (cval[0] == '(') *dtype = 'X'; /* complex datatype "(1.2, -3.4)" */ else if (strchr(cval,'.')) *dtype = 'F'; /* float usualy contains a decimal point */ else if (strchr(cval,'E') || strchr(cval,'D') ) *dtype = 'F'; /* exponential contains a E or D */ else *dtype = 'I'; /* if none of the above assume it is integer */ return(*status); } /*--------------------------------------------------------------------------*/ int ffc2x(char *cval, /* I - formatted string representation of the value */ char *dtype, /* O - datatype code: C, L, F, I or X */ /* Only one of the following will be defined, depending on datatype */ long *ival, /* O - integer value */ int *lval, /* O - logical value */ char *sval, /* O - string value */ double *dval, /* O - double value */ int *status) /* IO - error status */ /* high level routine to convert formatted character string to its intrinsic data type */ { ffdtyp(cval, dtype, status); /* determine the datatype */ if (*dtype == 'I') ffc2ii(cval, ival, status); else if (*dtype == 'F') ffc2dd(cval, dval, status); else if (*dtype == 'L') ffc2ll(cval, lval, status); else ffc2s(cval, sval, status); /* C and X formats */ return(*status); } /*--------------------------------------------------------------------------*/ int ffc2xx(char *cval, /* I - formatted string representation of the value */ char *dtype, /* O - datatype code: C, L, F, I or X */ /* Only one of the following will be defined, depending on datatype */ LONGLONG *ival, /* O - integer value */ int *lval, /* O - logical value */ char *sval, /* O - string value */ double *dval, /* O - double value */ int *status) /* IO - error status */ /* high level routine to convert formatted character string to its intrinsic data type */ { ffdtyp(cval, dtype, status); /* determine the datatype */ if (*dtype == 'I') ffc2jj(cval, ival, status); else if (*dtype == 'F') ffc2dd(cval, dval, status); else if (*dtype == 'L') ffc2ll(cval, lval, status); else ffc2s(cval, sval, status); /* C and X formats */ return(*status); } /*--------------------------------------------------------------------------*/ int ffc2i(char *cval, /* I - string representation of the value */ long *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to an integer value, doing implicit datatype conversion if necessary. */ { char dtype, sval[81], msg[81]; int lval; double dval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ /* convert the keyword to its native datatype */ ffc2x(cval, &dtype, ival, &lval, sval, &dval, status); if (dtype == 'X' ) { *status = BAD_INTKEY; } else if (dtype == 'C') { /* try reading the string as a number */ if (ffc2dd(sval, &dval, status) <= 0) { if (dval > (double) LONG_MAX || dval < (double) LONG_MIN) *status = NUM_OVERFLOW; else *ival = (long) dval; } } else if (dtype == 'F') { if (dval > (double) LONG_MAX || dval < (double) LONG_MIN) *status = NUM_OVERFLOW; else *ival = (long) dval; } else if (dtype == 'L') { *ival = (long) lval; } if (*status > 0) { *ival = 0; strcpy(msg,"Error in ffc2i evaluating string as an integer: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2j(char *cval, /* I - string representation of the value */ LONGLONG *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to a LONGLONG integer value, doing implicit datatype conversion if necessary. */ { char dtype, sval[81], msg[81]; int lval; double dval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ /* convert the keyword to its native datatype */ ffc2xx(cval, &dtype, ival, &lval, sval, &dval, status); if (dtype == 'X' ) { *status = BAD_INTKEY; } else if (dtype == 'C') { /* try reading the string as a number */ if (ffc2dd(sval, &dval, status) <= 0) { if (dval > (double) LONGLONG_MAX || dval < (double) LONGLONG_MIN) *status = NUM_OVERFLOW; else *ival = (LONGLONG) dval; } } else if (dtype == 'F') { if (dval > (double) LONGLONG_MAX || dval < (double) LONGLONG_MIN) *status = NUM_OVERFLOW; else *ival = (LONGLONG) dval; } else if (dtype == 'L') { *ival = (LONGLONG) lval; } if (*status > 0) { *ival = 0; strcpy(msg,"Error in ffc2j evaluating string as a long integer: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2l(char *cval, /* I - string representation of the value */ int *lval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to a logical value, doing implicit datatype conversion if necessary */ { char dtype, sval[81], msg[81]; long ival; double dval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ /* convert the keyword to its native datatype */ ffc2x(cval, &dtype, &ival, lval, sval, &dval, status); if (dtype == 'C' || dtype == 'X' ) *status = BAD_LOGICALKEY; if (*status > 0) { *lval = 0; strcpy(msg,"Error in ffc2l evaluating string as a logical: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } if (dtype == 'I') { if (ival) *lval = 1; else *lval = 0; } else if (dtype == 'F') { if (dval) *lval = 1; else *lval = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2r(char *cval, /* I - string representation of the value */ float *fval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to a real float value, doing implicit datatype conversion if necessary */ { char dtype, sval[81], msg[81]; int lval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ ffdtyp(cval, &dtype, status); /* determine the datatype */ if (dtype == 'I' || dtype == 'F') ffc2rr(cval, fval, status); else if (dtype == 'L') { ffc2ll(cval, &lval, status); *fval = (float) lval; } else if (dtype == 'C') { /* try reading the string as a number */ ffc2s(cval, sval, status); ffc2rr(sval, fval, status); } else *status = BAD_FLOATKEY; if (*status > 0) { *fval = 0.; strcpy(msg,"Error in ffc2r evaluating string as a float: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2d(char *cval, /* I - string representation of the value */ double *dval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert formatted string to a double value, doing implicit datatype conversion if necessary */ { char dtype, sval[81], msg[81]; int lval; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == '\0') return(*status = VALUE_UNDEFINED); /* null value string */ ffdtyp(cval, &dtype, status); /* determine the datatype */ if (dtype == 'I' || dtype == 'F') ffc2dd(cval, dval, status); else if (dtype == 'L') { ffc2ll(cval, &lval, status); *dval = (double) lval; } else if (dtype == 'C') { /* try reading the string as a number */ ffc2s(cval, sval, status); ffc2dd(sval, dval, status); } else *status = BAD_DOUBLEKEY; if (*status > 0) { *dval = 0.; strcpy(msg,"Error in ffc2d evaluating string as a double: "); strncat(msg,cval,30); ffpmsg(msg); return(*status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2ii(char *cval, /* I - string representation of the value */ long *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert null-terminated formatted string to an integer value */ { char *loc, msg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); errno = 0; *ival = 0; *ival = strtol(cval, &loc, 10); /* read the string as an integer */ /* check for read error, or junk following the integer */ if (*loc != '\0' && *loc != ' ' ) *status = BAD_C2I; if (errno == ERANGE) { strcpy(msg,"Range Error in ffc2ii converting string to long int: "); strncat(msg,cval,25); ffpmsg(msg); *status = NUM_OVERFLOW; errno = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2jj(char *cval, /* I - string representation of the value */ LONGLONG *ival, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert null-terminated formatted string to an long long integer value */ { char *loc, msg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); errno = 0; *ival = 0; #if defined(_MSC_VER) /* Microsoft Visual C++ 6.0 does not have the strtoll function */ *ival = _atoi64(cval); loc = cval; while (*loc == ' ') loc++; /* skip spaces */ if (*loc == '-') loc++; /* skip minus sign */ if (*loc == '+') loc++; /* skip plus sign */ while (isdigit(*loc)) loc++; /* skip digits */ #elif (USE_LL_SUFFIX == 1) *ival = strtoll(cval, &loc, 10); /* read the string as an integer */ #else *ival = strtol(cval, &loc, 10); /* read the string as an integer */ #endif /* check for read error, or junk following the integer */ if (*loc != '\0' && *loc != ' ' ) *status = BAD_C2I; if (errno == ERANGE) { strcpy(msg,"Range Error in ffc2jj converting string to longlong int: "); strncat(msg,cval,25); ffpmsg(msg); *status = NUM_OVERFLOW; errno = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2ll(char *cval, /* I - string representation of the value: T or F */ int *lval, /* O - numerical value of the input string: 1 or 0 */ int *status) /* IO - error status */ /* convert null-terminated formatted string to a logical value */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (cval[0] == 'T') *lval = 1; else *lval = 0; /* any character besides T is considered false */ return(*status); } /*--------------------------------------------------------------------------*/ int ffc2s(char *instr, /* I - null terminated quoted input string */ char *outstr, /* O - null terminated output string without quotes */ int *status) /* IO - error status */ /* convert an input quoted string to an unquoted string by removing the leading and trailing quote character. Also, replace any pairs of single quote characters with just a single quote character (FITS used a pair of single quotes to represent a literal quote character within the string). */ { int jj; size_t len, ii; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (instr[0] != '\'') { strcpy(outstr, instr); /* no leading quote, so return input string */ return(*status); } len = strlen(instr); for (ii=1, jj=0; ii < len; ii++, jj++) { if (instr[ii] == '\'') /* is this the closing quote? */ { if (instr[ii+1] == '\'') /* 2 successive quotes? */ ii++; /* copy only one of the quotes */ else break; /* found the closing quote, so exit this loop */ } outstr[jj] = instr[ii]; /* copy the next character to the output */ } outstr[jj] = '\0'; /* terminate the output string */ if (ii == len) { ffpmsg("This string value has no closing quote (ffc2s):"); ffpmsg(instr); return(*status = 205); } for (jj--; jj >= 0; jj--) /* replace trailing blanks with nulls */ { if (outstr[jj] == ' ') outstr[jj] = 0; else break; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2rr(char *cval, /* I - string representation of the value */ float *fval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert null-terminated formatted string to a float value */ { char *loc, msg[81]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); errno = 0; *fval = 0.; *fval = (float) strtod(cval, &loc); /* read the string as an float */ /* check for read error, or junk following the value */ if (*loc != '\0' && *loc != ' ' ) { strcpy(msg,"Error in ffc2rr converting string to float: "); strncat(msg,cval,30); ffpmsg(msg); *status = BAD_C2F; } if (errno == ERANGE) { strcpy(msg,"Error in ffc2rr converting string to float: "); strncat(msg,cval,30); ffpmsg(msg); *status = NUM_OVERFLOW; errno = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffc2dd(char *cval, /* I - string representation of the value */ double *dval, /* O - numerical value of the input string */ int *status) /* IO - error status */ /* convert null-terminated formatted string to a double value */ { char msg[81], tval[73], *loc; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(tval, cval); loc = strchr(tval, 'D'); if (loc) /* The C language does not support a 'D' */ *loc = 'E'; /* exponent so replace any D's with E's. */ errno = 0; *dval = 0.; *dval = strtod(tval, &loc); /* read the string as an double */ /* check for read error, or junk following the value */ if (*loc != '\0' && *loc != ' ' ) { strcpy(msg,"Error in ffc2dd converting string to double: "); strncat(msg,cval,30); ffpmsg(msg); *status = BAD_C2D; } if (errno == ERANGE) { strcpy(msg,"Error in ffc2dd converting string to double: "); strncat(msg,cval,30); ffpmsg(msg); *status = NUM_OVERFLOW; errno = 0; } return(*status); } indi-0.5/src/cfitsio/histo.c0000644000175000017500000012322210610474375013643 0ustar jrjr/* Globally defined histogram parameters */ #include #include #include #include #include "fitsio2.h" typedef struct { /* Structure holding all the histogramming information */ union { /* the iterator work functions (ffwritehist, ffcalchist) */ char *b; /* need to do their job... passed via *userPointer. */ short *i; int *j; float *r; double *d; } hist; fitsfile *tblptr; int haxis, hcolnum[4], himagetype; long haxis1, haxis2, haxis3, haxis4; float amin1, amin2, amin3, amin4; float maxbin1, maxbin2, maxbin3, maxbin4; float binsize1, binsize2, binsize3, binsize4; int wtrecip, wtcolnum; float weight; char *rowselector; } histType; /*--------------------------------------------------------------------------*/ int ffbins(char *binspec, /* I - binning specification */ int *imagetype, /* O - image type, TINT or TSHORT */ int *histaxis, /* O - no. of axes in the histogram */ char colname[4][FLEN_VALUE], /* column name for axis */ double *minin, /* minimum value for each axis */ double *maxin, /* maximum value for each axis */ double *binsizein, /* size of bins on each axis */ char minname[4][FLEN_VALUE], /* keyword name for min */ char maxname[4][FLEN_VALUE], /* keyword name for max */ char binname[4][FLEN_VALUE], /* keyword name for binsize */ double *wt, /* weighting factor */ char *wtname, /* keyword or column name for weight */ int *recip, /* the reciprocal of the weight? */ int *status) { /* Parse the input binning specification string, returning the binning parameters. Supports up to 4 dimensions. The binspec string has one of these forms: bin binsize - 2D histogram with binsize on each axis bin xcol - 1D histogram on column xcol bin (xcol, ycol) = binsize - 2D histogram with binsize on each axis bin x=min:max:size, y=min:max:size, z..., t... bin x=:max, y=::size bin x=size, y=min::size most other reasonable combinations are supported. */ int ii, slen, defaulttype; char *ptr, tmpname[30], *file_expr = NULL; double dummy; if (*status > 0) return(*status); /* set the default values */ *histaxis = 2; *imagetype = TINT; defaulttype = 1; *wt = 1.; *recip = 0; *wtname = '\0'; /* set default values */ for (ii = 0; ii < 4; ii++) { *colname[ii] = '\0'; *minname[ii] = '\0'; *maxname[ii] = '\0'; *binname[ii] = '\0'; minin[ii] = DOUBLENULLVALUE; /* undefined values */ maxin[ii] = DOUBLENULLVALUE; binsizein[ii] = DOUBLENULLVALUE; } ptr = binspec + 3; /* skip over 'bin' */ if (*ptr == 'i' ) /* bini */ { *imagetype = TSHORT; defaulttype = 0; ptr++; } else if (*ptr == 'j' ) /* binj; same as default */ { defaulttype = 0; ptr ++; } else if (*ptr == 'r' ) /* binr */ { *imagetype = TFLOAT; defaulttype = 0; ptr ++; } else if (*ptr == 'd' ) /* bind */ { *imagetype = TDOUBLE; defaulttype = 0; ptr ++; } else if (*ptr == 'b' ) /* binb */ { *imagetype = TBYTE; defaulttype = 0; ptr ++; } if (*ptr == '\0') /* use all defaults for other parameters */ return(*status); else if (*ptr != ' ') /* must be at least one blank */ { ffpmsg("binning specification syntax error:"); ffpmsg(binspec); return(*status = URL_PARSE_ERROR); } while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == '\0') /* no other parameters; use defaults */ return(*status); /* Check if need to import expression from a file */ if( *ptr=='@' ) { if( ffimport_file( ptr+1, &file_expr, status ) ) return(*status); ptr = file_expr; while (*ptr == ' ') ptr++; /* skip leading white space... again */ } if (*ptr == '(' ) { /* this must be the opening parenthesis around a list of column */ /* names, optionally followed by a '=' and the binning spec. */ for (ii = 0; ii < 4; ii++) { ptr++; /* skip over the '(', ',', or ' ') */ while (*ptr == ' ') /* skip over blanks */ ptr++; slen = strcspn(ptr, " ,)"); strncat(colname[ii], ptr, slen); /* copy 1st column name */ ptr += slen; while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == ')' ) /* end of the list of names */ { *histaxis = ii + 1; break; } } if (ii == 4) /* too many names in the list , or missing ')' */ { ffpmsg( "binning specification has too many column names or is missing closing ')':"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } ptr++; /* skip over the closing parenthesis */ while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == '\0') { if( file_expr ) free( file_expr ); return(*status); /* parsed the entire string */ } else if (*ptr != '=') /* must be an equals sign now*/ { ffpmsg("illegal binning specification in URL:"); ffpmsg(" an equals sign '=' must follow the column names"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } ptr++; /* skip over the equals sign */ while (*ptr == ' ') /* skip over blanks */ ptr++; /* get the single range specification for all the columns */ ffbinr(&ptr, tmpname, minin, maxin, binsizein, minname[0], maxname[0], binname[0], status); if (*status > 0) { ffpmsg("illegal binning specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status); } for (ii = 1; ii < *histaxis; ii++) { minin[ii] = minin[0]; maxin[ii] = maxin[0]; binsizein[ii] = binsizein[0]; strcpy(minname[ii], minname[0]); strcpy(maxname[ii], maxname[0]); strcpy(binname[ii], binname[0]); } while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == ';') goto getweight; /* a weighting factor is specified */ if (*ptr != '\0') /* must have reached end of string */ { ffpmsg("illegal syntax after binning range specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } return(*status); } /* end of case with list of column names in ( ) */ /* if we've reached this point, then the binning specification */ /* must be of the form: XCOL = min:max:binsize, YCOL = ... */ /* where the column name followed by '=' are optional. */ /* If the column name is not specified, then use the default name */ for (ii = 0; ii < 4; ii++) /* allow up to 4 histogram dimensions */ { ffbinr(&ptr, colname[ii], &minin[ii], &maxin[ii], &binsizein[ii], minname[ii], maxname[ii], binname[ii], status); if (*status > 0) { ffpmsg("illegal syntax in binning range specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status); } if (*ptr == '\0' || *ptr == ';') break; /* reached the end of the string */ if (*ptr == ' ') { while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr == '\0' || *ptr == ';') break; /* reached the end of the string */ if (*ptr == ',') ptr++; /* comma separates the next column specification */ } else if (*ptr == ',') { ptr++; /* comma separates the next column specification */ } else { ffpmsg("illegal characters following binning specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status = URL_PARSE_ERROR); } } if (ii == 4) { /* there are yet more characters in the string */ ffpmsg("illegal binning specification in URL:"); ffpmsg("apparently greater than 4 histogram dimensions"); ffpmsg(binspec); return(*status = URL_PARSE_ERROR); } else *histaxis = ii + 1; /* special case: if a single number was entered it should be */ /* interpreted as the binning factor for the default X and Y axes */ if (*histaxis == 1 && *colname[0] == '\0' && minin[0] == DOUBLENULLVALUE && maxin[0] == DOUBLENULLVALUE) { *histaxis = 2; binsizein[1] = binsizein[0]; } getweight: if (*ptr == ';') /* looks like a weighting factor is given */ { ptr++; while (*ptr == ' ') /* skip over blanks */ ptr++; recip = 0; if (*ptr == '/') { *recip = 1; /* the reciprocal of the weight is entered */ ptr++; while (*ptr == ' ') /* skip over blanks */ ptr++; } /* parse the weight as though it were a binrange. */ /* either a column name or a numerical value will be returned */ ffbinr(&ptr, wtname, &dummy, &dummy, wt, tmpname, tmpname, tmpname, status); if (*status > 0) { ffpmsg("illegal binning weight specification in URL:"); ffpmsg(binspec); if( file_expr ) free( file_expr ); return(*status); } /* creat a float datatype histogram by default, if weight */ /* factor is not = 1.0 */ if (defaulttype && *wt != 1.0) *imagetype = TFLOAT; } while (*ptr == ' ') /* skip over blanks */ ptr++; if (*ptr != '\0') /* should have reached the end of string */ { ffpmsg("illegal syntax after binning weight specification in URL:"); ffpmsg(binspec); *status = URL_PARSE_ERROR; } if( file_expr ) free( file_expr ); return(*status); } /*--------------------------------------------------------------------------*/ int ffbinr(char **ptr, char *colname, double *minin, double *maxin, double *binsizein, char *minname, char *maxname, char *binname, int *status) /* Parse the input binning range specification string, returning the column name, histogram min and max values, and bin size. */ { int slen, isanumber; char token[FLEN_VALUE]; if (*status > 0) return(*status); slen = fits_get_token(ptr, " ,=:;", token, &isanumber); /* get 1st token */ if (slen == 0 && (**ptr == '\0' || **ptr == ',' || **ptr == ';') ) return(*status); /* a null range string */ if (!isanumber && **ptr != ':') { /* this looks like the column name */ if (token[0] == '#' && isdigit((int) token[1]) ) { /* omit the leading '#' in the column number */ strcpy(colname, token+1); } else strcpy(colname, token); while (**ptr == ' ') /* skip over blanks */ (*ptr)++; if (**ptr != '=') return(*status); /* reached the end */ (*ptr)++; /* skip over the = sign */ while (**ptr == ' ') /* skip over blanks */ (*ptr)++; slen = fits_get_token(ptr, " ,:;", token, &isanumber); /* get token */ } if (**ptr != ':') { /* this is the first token, and since it is not followed by */ /* a ':' this must be the binsize token */ if (!isanumber) strcpy(binname, token); else *binsizein = strtod(token, NULL); return(*status); /* reached the end */ } else { /* the token contains the min value */ if (slen) { if (!isanumber) strcpy(minname, token); else *minin = strtod(token, NULL); } } (*ptr)++; /* skip the colon between the min and max values */ slen = fits_get_token(ptr, " ,:;", token, &isanumber); /* get token */ /* the token contains the max value */ if (slen) { if (!isanumber) strcpy(maxname, token); else *maxin = strtod(token, NULL); } if (**ptr != ':') return(*status); /* reached the end; no binsize token */ (*ptr)++; /* skip the colon between the max and binsize values */ slen = fits_get_token(ptr, " ,:;", token, &isanumber); /* get token */ /* the token contains the binsize value */ if (slen) { if (!isanumber) strcpy(binname, token); else *binsizein = strtod(token, NULL); } return(*status); } /*--------------------------------------------------------------------------*/ int ffhist(fitsfile **fptr, /* IO - pointer to table with X and Y cols; */ /* on output, points to histogram image */ char *outfile, /* I - name for the output histogram file */ int imagetype, /* I - datatype for image: TINT, TSHORT, etc */ int naxis, /* I - number of axes in the histogram image */ char colname[4][FLEN_VALUE], /* I - column names */ double *minin, /* I - minimum histogram value, for each axis */ double *maxin, /* I - maximum histogram value, for each axis */ double *binsizein, /* I - bin size along each axis */ char minname[4][FLEN_VALUE], /* I - optional keywords for min */ char maxname[4][FLEN_VALUE], /* I - optional keywords for max */ char binname[4][FLEN_VALUE], /* I - optional keywords for binsize */ double weightin, /* I - binning weighting factor */ char wtcol[FLEN_VALUE], /* I - optional keyword or col for weight*/ int recip, /* I - use reciprocal of the weight? */ char *selectrow, /* I - optional array (length = no. of */ /* rows in the table). If the element is true */ /* then the corresponding row of the table will*/ /* be included in the histogram, otherwise the */ /* row will be skipped. Ingnored if *selectrow*/ /* is equal to NULL. */ int *status) { int ii, datatype, repeat, imin, imax, ibin, bitpix, tstatus, use_datamax = 0; long haxes[4]; fitsfile *histptr; char errmsg[FLEN_ERRMSG], keyname[FLEN_KEYWORD], card[FLEN_CARD]; tcolumn *colptr; iteratorCol imagepars[1]; int n_cols = 1, nkeys; long offset = 0; long n_per_loop = -1; /* force whole array to be passed at one time */ histType histData; /* Structure holding histogram info for iterator */ float amin[4], amax[4], binsize[4], maxbin[4]; float datamin = FLOATNULLVALUE, datamax = FLOATNULLVALUE; char svalue[FLEN_VALUE]; double dvalue; char cpref[4][FLEN_VALUE]; char *cptr; if (*status > 0) return(*status); if (naxis > 4) { ffpmsg("histogram has more than 4 dimensions"); return(*status = BAD_DIMEN); } /* reset position to the correct HDU if necessary */ if ((*fptr)->HDUposition != ((*fptr)->Fptr)->curhdu) ffmahd(*fptr, ((*fptr)->HDUposition) + 1, NULL, status); histData.tblptr = *fptr; histData.himagetype = imagetype; histData.haxis = naxis; histData.rowselector = selectrow; if (imagetype == TBYTE) bitpix = BYTE_IMG; else if (imagetype == TSHORT) bitpix = SHORT_IMG; else if (imagetype == TINT) bitpix = LONG_IMG; else if (imagetype == TFLOAT) bitpix = FLOAT_IMG; else if (imagetype == TDOUBLE) bitpix = DOUBLE_IMG; else return(*status = BAD_DATATYPE); /* The CPREF keyword, if it exists, gives the preferred columns. */ /* Otherwise, assume "X", "Y", "Z", and "T" */ tstatus = 0; ffgky(*fptr, TSTRING, "CPREF", cpref[0], NULL, &tstatus); if (!tstatus) { /* Preferred column names are given; separate them */ cptr = cpref[0]; /* the first preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[1], cptr); cptr = cpref[1]; /* the second preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[2], cptr); cptr = cpref[2]; /* the third preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[3], cptr); } } } } for (ii = 0; ii < naxis; ii++) { /* get the min, max, and binsize values from keywords, if specified */ if (*minname[ii]) { if (ffgky(*fptr, TDOUBLE, minname[ii], &minin[ii], NULL, status) ) { ffpmsg("error reading histogramming minimum keyword"); ffpmsg(minname[ii]); return(*status); } } if (*maxname[ii]) { if (ffgky(*fptr, TDOUBLE, maxname[ii], &maxin[ii], NULL, status) ) { ffpmsg("error reading histogramming maximum keyword"); ffpmsg(maxname[ii]); return(*status); } } if (*binname[ii]) { if (ffgky(*fptr, TDOUBLE, binname[ii], &binsizein[ii], NULL, status) ) { ffpmsg("error reading histogramming binsize keyword"); ffpmsg(binname[ii]); return(*status); } } if (binsizein[ii] == 0.) { ffpmsg("error: histogram binsize = 0"); return(*status = ZERO_SCALE); } if (*colname[ii] == '\0') { strcpy(colname[ii], cpref[ii]); /* try using the preferred column */ if (*colname[ii] == '\0') { if (ii == 0) strcpy(colname[ii], "X"); else if (ii == 1) strcpy(colname[ii], "Y"); else if (ii == 2) strcpy(colname[ii], "Z"); else if (ii == 3) strcpy(colname[ii], "T"); } } /* get the column number in the table */ if (ffgcno(*fptr, CASEINSEN, colname[ii], histData.hcolnum+ii, status) > 0) { strcpy(errmsg, "column for histogram axis doesn't exist: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status); } colptr = ((*fptr)->Fptr)->tableptr; colptr += (histData.hcolnum[ii] - 1); repeat = (int) colptr->trepeat; /* vector repeat factor of the column */ if (repeat > 1) { strcpy(errmsg, "Can't bin a vector column: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status = BAD_DATATYPE); } /* get the datatype of the column */ fits_get_coltype(*fptr, histData.hcolnum[ii], &datatype, NULL, NULL, status); if (datatype < 0 || datatype == TSTRING) { strcpy(errmsg, "Inappropriate datatype; can't bin this column: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status = BAD_DATATYPE); } /* use TLMINn and TLMAXn keyword values if min and max were not given */ /* else use actual data min and max if TLMINn and TLMAXn don't exist */ if (minin[ii] == DOUBLENULLVALUE) { ffkeyn("TLMIN", histData.hcolnum[ii], keyname, status); if (ffgky(*fptr, TFLOAT, keyname, amin+ii, NULL, status) > 0) { /* use actual data minimum value for the histogram minimum */ *status = 0; if (fits_get_col_minmax(*fptr, histData.hcolnum[ii], amin+ii, &datamax, status) > 0) { strcpy(errmsg, "Error calculating datamin and datamax for column: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status); } } } else { amin[ii] = (float) minin[ii]; } if (maxin[ii] == DOUBLENULLVALUE) { ffkeyn("TLMAX", histData.hcolnum[ii], keyname, status); if (ffgky(*fptr, TFLOAT, keyname, &amax[ii], NULL, status) > 0) { *status = 0; if(datamax != FLOATNULLVALUE) /* already computed max value */ { amax[ii] = datamax; } else { /* use actual data maximum value for the histogram maximum */ if (fits_get_col_minmax(*fptr, histData.hcolnum[ii], &datamin, &amax[ii], status) > 0) { strcpy(errmsg, "Error calculating datamin and datamax for column: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status); } } } use_datamax = 1; /* flag that the max was determined by the data values */ /* and not specifically set by the calling program */ } else { amax[ii] = (float) maxin[ii]; } /* use TDBINn keyword or else 1 if bin size is not given */ if (binsizein[ii] == DOUBLENULLVALUE) { tstatus = 0; ffkeyn("TDBIN", histData.hcolnum[ii], keyname, &tstatus); if (ffgky(*fptr, TDOUBLE, keyname, binsizein + ii, NULL, &tstatus) > 0) { /* make at least 10 bins */ binsizein[ii] = (amax[ii] - amin[ii]) / 10. ; if (binsizein[ii] > 1.) binsizein[ii] = 1.; /* use default bin size */ } } if ( (amin[ii] > amax[ii] && binsizein[ii] > 0. ) || (amin[ii] < amax[ii] && binsizein[ii] < 0. ) ) binsize[ii] = (float) -binsizein[ii]; /* reverse the sign of binsize */ else binsize[ii] = (float) binsizein[ii]; /* binsize has the correct sign */ ibin = (int) binsize[ii]; imin = (int) amin[ii]; imax = (int) amax[ii]; /* Determine the range and number of bins in the histogram. This */ /* depends on whether the input columns are integer or floats, so */ /* treat each case separately. */ if (datatype <= TLONG && (float) imin == amin[ii] && (float) imax == amax[ii] && (float) ibin == binsize[ii] ) { /* This is an integer column and integer limits were entered. */ /* Shift the lower and upper histogramming limits by 0.5, so that */ /* the values fall in the center of the bin, not on the edge. */ haxes[ii] = (imax - imin) / ibin + 1; /* last bin may only */ /* be partially full */ maxbin[ii] = (float) (haxes[ii] + 1.); /* add 1. instead of .5 to avoid roundoff */ if (amin[ii] < amax[ii]) { amin[ii] = (float) (amin[ii] - 0.5); amax[ii] = (float) (amax[ii] + 0.5); } else { amin[ii] = (float) (amin[ii] + 0.5); amax[ii] = (float) (amax[ii] - 0.5); } } else if (use_datamax) { /* Either the column datatype and/or the limits are floating point, */ /* and the histogram limits are being defined by the min and max */ /* values of the array. Add 1 to the number of histogram bins to */ /* make sure that pixels that are equal to the maximum or are */ /* in the last partial bin are included. */ maxbin[ii] = (amax[ii] - amin[ii]) / binsize[ii]; haxes[ii] = (long) (maxbin[ii] + 1); } else { /* float datatype column and/or limits, and the maximum value to */ /* include in the histogram is specified by the calling program. */ /* The lower limit is inclusive, but upper limit is exclusive */ maxbin[ii] = (amax[ii] - amin[ii]) / binsize[ii]; haxes[ii] = (long) maxbin[ii]; if (amin[ii] < amax[ii]) { if (amin[ii] + (haxes[ii] * binsize[ii]) < amax[ii]) haxes[ii]++; /* need to include another partial bin */ } else { if (amin[ii] + (haxes[ii] * binsize[ii]) > amax[ii]) haxes[ii]++; /* need to include another partial bin */ } } } /* get the histogramming weighting factor */ if (*wtcol) { /* first, look for a keyword with the weight value */ if (ffgky(*fptr, TFLOAT, wtcol, &histData.weight, NULL, status) ) { /* not a keyword, so look for column with this name */ *status = 0; /* get the column number in the table */ if (ffgcno(*fptr, CASEINSEN, wtcol, &histData.wtcolnum, status) > 0) { ffpmsg( "keyword or column for histogram weights doesn't exist: "); ffpmsg(wtcol); return(*status); } histData.weight = FLOATNULLVALUE; } } else histData.weight = (float) weightin; if (histData.weight <= 0. && histData.weight != FLOATNULLVALUE) { ffpmsg("Illegal histogramming weighting factor <= 0."); return(*status = URL_PARSE_ERROR); } if (recip && histData.weight != FLOATNULLVALUE) /* take reciprocal of weight */ histData.weight = (float) (1.0 / histData.weight); histData.wtrecip = recip; /* size of histogram is now known, so create temp output file */ if (ffinit(&histptr, outfile, status) > 0) { ffpmsg("failed to create temp output file for histogram"); return(*status); } if (ffcrim(histptr, bitpix, histData.haxis, haxes, status) > 0) { ffpmsg("failed to create primary array histogram in temp file"); ffclos(histptr, status); return(*status); } /* copy all non-structural keywords from the table to the image */ fits_get_hdrspace(*fptr, &nkeys, NULL, status); for (ii = 1; ii <= nkeys; ii++) { fits_read_record(*fptr, ii, card, status); if (fits_get_keyclass(card) >= 120) fits_write_record(histptr, card, status); } /* Set global variables with histogram parameter values. */ /* Use separate scalar variables rather than arrays because */ /* it is more efficient when computing the histogram. */ histData.amin1 = amin[0]; histData.maxbin1 = maxbin[0]; histData.binsize1 = binsize[0]; histData.haxis1 = haxes[0]; if (histData.haxis > 1) { histData.amin2 = amin[1]; histData.maxbin2 = maxbin[1]; histData.binsize2 = binsize[1]; histData.haxis2 = haxes[1]; if (histData.haxis > 2) { histData.amin3 = amin[2]; histData.maxbin3 = maxbin[2]; histData.binsize3 = binsize[2]; histData.haxis3 = haxes[2]; if (histData.haxis > 3) { histData.amin4 = amin[3]; histData.maxbin4 = maxbin[3]; histData.binsize4 = binsize[3]; histData.haxis4 = haxes[3]; } } } /* define parameters of image for the iterator function */ fits_iter_set_file(imagepars, histptr); /* pointer to image */ fits_iter_set_datatype(imagepars, imagetype); /* image datatype */ fits_iter_set_iotype(imagepars, OutputCol); /* image is output */ /* call the iterator function to write out the histogram image */ if (fits_iterate_data(n_cols, imagepars, offset, n_per_loop, ffwritehisto, (void*)&histData, status) ) return(*status); /* write the World Coordinate System (WCS) keywords */ /* create default values if WCS keywords are not present in the table */ for (ii = 0; ii < histData.haxis; ii++) { /* CTYPEn */ tstatus = 0; ffkeyn("TCTYP", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); if (tstatus) { /* just use column name as the type */ tstatus = 0; ffkeyn("TTYPE", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); } if (!tstatus) { ffkeyn("CTYPE", ii + 1, keyname, &tstatus); ffpky(histptr, TSTRING, keyname, svalue, "Coordinate Type", &tstatus); } else tstatus = 0; /* CUNITn */ ffkeyn("TCUNI", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); if (tstatus) { /* use the column units */ tstatus = 0; ffkeyn("TUNIT", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); } if (!tstatus) { ffkeyn("CUNIT", ii + 1, keyname, &tstatus); ffpky(histptr, TSTRING, keyname, svalue, "Coordinate Units", &tstatus); } else tstatus = 0; /* CRPIXn - Reference Pixel */ ffkeyn("TCRPX", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (tstatus) { dvalue = 1.0; /* choose first pixel in new image as ref. pix. */ tstatus = 0; } else { /* calculate locate of the ref. pix. in the new image */ dvalue = (dvalue - amin[ii]) / binsize[ii] + .5; } ffkeyn("CRPIX", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Reference Pixel", &tstatus); /* CRVALn - Value at the location of the reference pixel */ ffkeyn("TCRVL", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (tstatus) { /* calculate value at ref. pix. location (at center of 1st pixel) */ dvalue = amin[ii] + binsize[ii]/2.; tstatus = 0; } ffkeyn("CRVAL", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Reference Value", &tstatus); /* CDELTn - unit size of pixels */ ffkeyn("TCDLT", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (tstatus) { dvalue = 1.0; /* use default pixel size */ tstatus = 0; } dvalue = dvalue * binsize[ii]; ffkeyn("CDELT", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Pixel size", &tstatus); /* CROTAn - Rotation angle (degrees CCW) */ /* There should only be a CROTA2 keyword, and only for 2+ D images */ if (ii == 1) { ffkeyn("TCROT", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (!tstatus && dvalue != 0.) /* only write keyword if angle != 0 */ { ffkeyn("CROTA", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Rotation angle", &tstatus); } else { /* didn't find CROTA for the 2nd axis, so look for one */ /* on the first axis */ tstatus = 0; ffkeyn("TCROT", histData.hcolnum[0], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (!tstatus && dvalue != 0.) /* only write keyword if angle != 0 */ { dvalue *= -1.; /* negate the value, because mirror image */ ffkeyn("CROTA", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Rotation angle", &tstatus); } } } } /* finally, close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = histptr; return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_col_minmax(fitsfile *fptr, int colnum, float *datamin, float *datamax, int *status) /* Simple utility routine to compute the min and max value in a column */ { int anynul; long nrows, ntodo, firstrow, ii; float array[1000], nulval; ffgky(fptr, TLONG, "NAXIS2", &nrows, NULL, status); /* no. of rows */ firstrow = 1; nulval = FLOATNULLVALUE; *datamin = 9.0E36F; *datamax = -9.0E36F; while(nrows) { ntodo = minvalue(nrows, 100); ffgcv(fptr, TFLOAT, colnum, firstrow, 1, ntodo, &nulval, array, &anynul, status); for (ii = 0; ii < ntodo; ii++) { if (array[ii] != nulval) { *datamin = minvalue(*datamin, array[ii]); *datamax = maxvalue(*datamax, array[ii]); } } nrows -= ntodo; firstrow += ntodo; } return(*status); } /*--------------------------------------------------------------------------*/ int ffwritehisto(long totaln, long pixoffset, long firstn, long nvalues, int narrays, iteratorCol *imagepars, void *userPointer) /* Interator work function that writes out the histogram. The histogram values are calculated by another work function, ffcalchisto. This work function only gets called once, and totaln = nvalues. */ { iteratorCol colpars[5]; int ii, status = 0, ncols; long rows_per_loop = 0, offset = 0; histType *histData; histData = (histType *)userPointer; /* store pointer to the histogram array, and initialize to zero */ switch( histData->himagetype ) { case TBYTE: histData->hist.b = (char * ) fits_iter_get_array(imagepars); break; case TSHORT: histData->hist.i = (short * ) fits_iter_get_array(imagepars); break; case TINT: histData->hist.j = (int * ) fits_iter_get_array(imagepars); break; case TFLOAT: histData->hist.r = (float * ) fits_iter_get_array(imagepars); break; case TDOUBLE: histData->hist.d = (double *) fits_iter_get_array(imagepars); break; } /* set the column parameters for the iterator function */ for (ii = 0; ii < histData->haxis; ii++) { fits_iter_set_by_num(&colpars[ii], histData->tblptr, histData->hcolnum[ii], TFLOAT, InputCol); } ncols = histData->haxis; if (histData->weight == FLOATNULLVALUE) { fits_iter_set_by_num(&colpars[histData->haxis], histData->tblptr, histData->wtcolnum, TFLOAT, InputCol); ncols = histData->haxis + 1; } /* call iterator function to calc the histogram pixel values */ fits_iterate_data(ncols, colpars, offset, rows_per_loop, ffcalchist, (void*)histData, &status); return(status); } /*--------------------------------------------------------------------------*/ int ffcalchist(long totalrows, long offset, long firstrow, long nrows, int ncols, iteratorCol *colpars, void *userPointer) /* Interator work function that calculates values for the 2D histogram. */ { long ii, ipix, iaxisbin; float pix, axisbin; static float *col1, *col2, *col3, *col4; /* static to preserve values */ static float *wtcol; static long incr2, incr3, incr4; static histType histData; static char *rowselect; /* Initialization procedures: execute on the first call */ if (firstrow == 1) { /* Copy input histogram data to static local variable so we */ /* don't have to constantly dereference it. */ histData = *(histType*)userPointer; rowselect = histData.rowselector; /* assign the input array pointers to local pointers */ col1 = (float *) fits_iter_get_array(&colpars[0]); if (histData.haxis > 1) { col2 = (float *) fits_iter_get_array(&colpars[1]); incr2 = histData.haxis1; if (histData.haxis > 2) { col3 = (float *) fits_iter_get_array(&colpars[2]); incr3 = incr2 * histData.haxis2; if (histData.haxis > 3) { col4 = (float *) fits_iter_get_array(&colpars[3]); incr4 = incr3 * histData.haxis3; } } } if (ncols > histData.haxis) /* then weights are give in a column */ { wtcol = (float *) fits_iter_get_array(&colpars[histData.haxis]); } } /* end of Initialization procedures */ /* Main loop: increment the histogram at position of each event */ for (ii = 1; ii <= nrows; ii++) { if (rowselect) /* if a row selector array is supplied... */ { if (*rowselect) { rowselect++; /* this row is included in the histogram */ } else { rowselect++; /* this row is excluded from the histogram */ continue; } } if (col1[ii] == FLOATNULLVALUE) /* test for null value */ continue; pix = (col1[ii] - histData.amin1) / histData.binsize1; ipix = (long) (pix + 1.); /* add 1 because the 1st pixel is the null value */ /* test if bin is within range */ if (ipix < 1 || ipix > histData.haxis1 || pix > histData.maxbin1) continue; if (histData.haxis > 1) { if (col2[ii] == FLOATNULLVALUE) continue; axisbin = (col2[ii] - histData.amin2) / histData.binsize2; iaxisbin = (long) axisbin; if (axisbin < 0. || iaxisbin >= histData.haxis2 || axisbin > histData.maxbin2) continue; ipix += (iaxisbin * incr2); if (histData.haxis > 2) { if (col3[ii] == FLOATNULLVALUE) continue; axisbin = (col3[ii] - histData.amin3) / histData.binsize3; iaxisbin = (long) axisbin; if (axisbin < 0. || iaxisbin >= histData.haxis3 || axisbin > histData.maxbin3) continue; ipix += (iaxisbin * incr3); if (histData.haxis > 3) { if (col4[ii] == FLOATNULLVALUE) continue; axisbin = (col4[ii] - histData.amin4) / histData.binsize4; iaxisbin = (long) axisbin; if (axisbin < 0. || iaxisbin >= histData.haxis4 || axisbin > histData.maxbin4) continue; ipix += (iaxisbin * incr4); } /* end of haxis > 3 case */ } /* end of haxis > 2 case */ } /* end of haxis > 1 case */ /* increment the histogram pixel */ if (histData.weight != FLOATNULLVALUE) /* constant weight factor */ { if (histData.himagetype == TINT) histData.hist.j[ipix] += (int) histData.weight; else if (histData.himagetype == TSHORT) histData.hist.i[ipix] += (short) histData.weight; else if (histData.himagetype == TFLOAT) histData.hist.r[ipix] += histData.weight; else if (histData.himagetype == TDOUBLE) histData.hist.d[ipix] += histData.weight; else if (histData.himagetype == TBYTE) histData.hist.b[ipix] += (char) histData.weight; } else if (histData.wtrecip) /* use reciprocal of the weight */ { if (histData.himagetype == TINT) histData.hist.j[ipix] += (int) (1./wtcol[ii]); else if (histData.himagetype == TSHORT) histData.hist.i[ipix] += (short) (1./wtcol[ii]); else if (histData.himagetype == TFLOAT) histData.hist.r[ipix] += (float) (1./wtcol[ii]); else if (histData.himagetype == TDOUBLE) histData.hist.d[ipix] += 1./wtcol[ii]; else if (histData.himagetype == TBYTE) histData.hist.b[ipix] += (char) (1./wtcol[ii]); } else /* no weights */ { if (histData.himagetype == TINT) histData.hist.j[ipix] += (int) wtcol[ii]; else if (histData.himagetype == TSHORT) histData.hist.i[ipix] += (short) wtcol[ii]; else if (histData.himagetype == TFLOAT) histData.hist.r[ipix] += wtcol[ii]; else if (histData.himagetype == TDOUBLE) histData.hist.d[ipix] += wtcol[ii]; else if (histData.himagetype == TBYTE) histData.hist.b[ipix] += (char) wtcol[ii]; } } /* end of main loop over all rows */ return(0); } indi-0.5/src/cfitsio/putcol.c0000644000175000017500000017674210610474375014042 0ustar jrjr/* This file, putcol.c, contains routines that write data elements to */ /* a FITS image or table. These are the generic routines. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffppx( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *firstpix, /* I - coord of first pixel to write(1 based) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of pixels to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine is simillar to ffppr, except it supports writing to large images with more than 2**31 pixels. */ { int naxis, ii; long group = 1; LONGLONG firstelem, dimsize = 1, naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (datatype == TBYTE) { ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffppri(fptr, group, firstelem, nelem, (short *) array, status); } else if (datatype == TUINT) { ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status); } else if (datatype == TINT) { ffpprk(fptr, group, firstelem, nelem, (int *) array, status); } else if (datatype == TULONG) { ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpprj(fptr, group, firstelem, nelem, (long *) array, status); } else if (datatype == TLONGLONG) { ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffppre(fptr, group, firstelem, nelem, (float *) array, status); } else if (datatype == TDOUBLE) { ffpprd(fptr, group, firstelem, nelem, (double *) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppxll( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG *firstpix, /* I - coord of first pixel to write(1 based) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of pixels to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine is simillar to ffppr, except it supports writing to large images with more than 2**31 pixels. */ { int naxis, ii; long group = 1; LONGLONG firstelem, dimsize = 1, naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (datatype == TBYTE) { ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffppri(fptr, group, firstelem, nelem, (short *) array, status); } else if (datatype == TUINT) { ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status); } else if (datatype == TINT) { ffpprk(fptr, group, firstelem, nelem, (int *) array, status); } else if (datatype == TULONG) { ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpprj(fptr, group, firstelem, nelem, (long *) array, status); } else if (datatype == TLONGLONG) { ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffppre(fptr, group, firstelem, nelem, (float *) array, status); } else if (datatype == TDOUBLE) { ffpprd(fptr, group, firstelem, nelem, (double *) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppxn( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *firstpix, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ void *nulval, /* I - pointer to the null value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine supports writing to large images with more than 2**31 pixels. */ { int naxis, ii; long group = 1; LONGLONG firstelem, dimsize = 1, naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (nulval == NULL) /* null value not defined? */ { ffppx(fptr, datatype, firstpix, nelem, array, status); return(*status); } /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (datatype == TBYTE) { ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array, *(unsigned char *) nulval, status); } else if (datatype == TSBYTE) { ffppnsb(fptr, group, firstelem, nelem, (signed char *) array, *(signed char *) nulval, status); } else if (datatype == TUSHORT) { ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array, *(unsigned short *) nulval,status); } else if (datatype == TSHORT) { ffppni(fptr, group, firstelem, nelem, (short *) array, *(short *) nulval, status); } else if (datatype == TUINT) { ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array, *(unsigned int *) nulval, status); } else if (datatype == TINT) { ffppnk(fptr, group, firstelem, nelem, (int *) array, *(int *) nulval, status); } else if (datatype == TULONG) { ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array, *(unsigned long *) nulval,status); } else if (datatype == TLONG) { ffppnj(fptr, group, firstelem, nelem, (long *) array, *(long *) nulval, status); } else if (datatype == TLONGLONG) { ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array, *(LONGLONG *) nulval, status); } else if (datatype == TFLOAT) { ffppne(fptr, group, firstelem, nelem, (float *) array, *(float *) nulval, status); } else if (datatype == TDOUBLE) { ffppnd(fptr, group, firstelem, nelem, (double *) array, *(double *) nulval, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppxnll( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG *firstpix, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ void *nulval, /* I - pointer to the null value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine supports writing to large images with more than 2**31 pixels. */ { int naxis, ii; long group = 1; LONGLONG firstelem, dimsize = 1, naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (nulval == NULL) /* null value not defined? */ { ffppxll(fptr, datatype, firstpix, nelem, array, status); return(*status); } /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgiszll(fptr, 9, naxes, status); firstelem = 0; for (ii=0; ii < naxis; ii++) { firstelem += ((firstpix[ii] - 1) * dimsize); dimsize *= naxes[ii]; } firstelem++; if (datatype == TBYTE) { ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array, *(unsigned char *) nulval, status); } else if (datatype == TSBYTE) { ffppnsb(fptr, group, firstelem, nelem, (signed char *) array, *(signed char *) nulval, status); } else if (datatype == TUSHORT) { ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array, *(unsigned short *) nulval,status); } else if (datatype == TSHORT) { ffppni(fptr, group, firstelem, nelem, (short *) array, *(short *) nulval, status); } else if (datatype == TUINT) { ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array, *(unsigned int *) nulval, status); } else if (datatype == TINT) { ffppnk(fptr, group, firstelem, nelem, (int *) array, *(int *) nulval, status); } else if (datatype == TULONG) { ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array, *(unsigned long *) nulval,status); } else if (datatype == TLONG) { ffppnj(fptr, group, firstelem, nelem, (long *) array, *(long *) nulval, status); } else if (datatype == TLONGLONG) { ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array, *(LONGLONG *) nulval, status); } else if (datatype == TFLOAT) { ffppne(fptr, group, firstelem, nelem, (float *) array, *(float *) nulval, status); } else if (datatype == TDOUBLE) { ffppnd(fptr, group, firstelem, nelem, (double *) array, *(double *) nulval, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppr( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long group = 1; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TBYTE) { ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffppri(fptr, group, firstelem, nelem, (short *) array, status); } else if (datatype == TUINT) { ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status); } else if (datatype == TINT) { ffpprk(fptr, group, firstelem, nelem, (int *) array, status); } else if (datatype == TULONG) { ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpprj(fptr, group, firstelem, nelem, (long *) array, status); } else if (datatype == TLONGLONG) { ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffppre(fptr, group, firstelem, nelem, (float *) array, status); } else if (datatype == TDOUBLE) { ffpprd(fptr, group, firstelem, nelem, (double *) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffppn( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ void *array, /* I - array of values that are written */ void *nulval, /* I - pointer to the null value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long group = 1; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (nulval == NULL) /* null value not defined? */ { ffppr(fptr, datatype, firstelem, nelem, array, status); return(*status); } if (datatype == TBYTE) { ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array, *(unsigned char *) nulval, status); } else if (datatype == TSBYTE) { ffppnsb(fptr, group, firstelem, nelem, (signed char *) array, *(signed char *) nulval, status); } else if (datatype == TUSHORT) { ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array, *(unsigned short *) nulval,status); } else if (datatype == TSHORT) { ffppni(fptr, group, firstelem, nelem, (short *) array, *(short *) nulval, status); } else if (datatype == TUINT) { ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array, *(unsigned int *) nulval, status); } else if (datatype == TINT) { ffppnk(fptr, group, firstelem, nelem, (int *) array, *(int *) nulval, status); } else if (datatype == TULONG) { ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array, *(unsigned long *) nulval,status); } else if (datatype == TLONG) { ffppnj(fptr, group, firstelem, nelem, (long *) array, *(long *) nulval, status); } else if (datatype == TLONGLONG) { ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array, *(LONGLONG *) nulval, status); } else if (datatype == TFLOAT) { ffppne(fptr, group, firstelem, nelem, (float *) array, *(float *) nulval, status); } else if (datatype == TDOUBLE) { ffppnd(fptr, group, firstelem, nelem, (double *) array, *(double *) nulval, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffpss( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc , /* I - 'top right corner' of the subsection */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write a section of values to the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). This routine supports writing to large images with more than 2**31 pixels. */ { int naxis; long naxes[9]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgisz(fptr, 9, naxes, status); if (datatype == TBYTE) { ffpssb(fptr, 1, naxis, naxes, blc, trc, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpsssb(fptr, 1, naxis, naxes, blc, trc, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpssui(fptr, 1, naxis, naxes, blc, trc, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffpssi(fptr, 1, naxis, naxes, blc, trc, (short *) array, status); } else if (datatype == TUINT) { ffpssuk(fptr, 1, naxis, naxes, blc, trc, (unsigned int *) array, status); } else if (datatype == TINT) { ffpssk(fptr, 1, naxis, naxes, blc, trc, (int *) array, status); } else if (datatype == TULONG) { ffpssuj(fptr, 1, naxis, naxes, blc, trc, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpssj(fptr, 1, naxis, naxes, blc, trc, (long *) array, status); } else if (datatype == TLONGLONG) { ffpssjj(fptr, 1, naxis, naxes, blc, trc, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffpsse(fptr, 1, naxis, naxes, blc, trc, (float *) array, status); } else if (datatype == TDOUBLE) { ffpssd(fptr, 1, naxis, naxes, blc, trc, (double *) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffpcl( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of elements to write */ void *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to a table column. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS column is not the same as the array being written). */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TBIT) { ffpclx(fptr, colnum, firstrow, (long) firstelem, (long) nelem, (char *) array, status); } else if (datatype == TBYTE) { ffpclb(fptr, colnum, firstrow, firstelem, nelem, (unsigned char *) array, status); } else if (datatype == TSBYTE) { ffpclsb(fptr, colnum, firstrow, firstelem, nelem, (signed char *) array, status); } else if (datatype == TUSHORT) { ffpclui(fptr, colnum, firstrow, firstelem, nelem, (unsigned short *) array, status); } else if (datatype == TSHORT) { ffpcli(fptr, colnum, firstrow, firstelem, nelem, (short *) array, status); } else if (datatype == TUINT) { ffpcluk(fptr, colnum, firstrow, firstelem, nelem, (unsigned int *) array, status); } else if (datatype == TINT) { ffpclk(fptr, colnum, firstrow, firstelem, nelem, (int *) array, status); } else if (datatype == TULONG) { ffpcluj(fptr, colnum, firstrow, firstelem, nelem, (unsigned long *) array, status); } else if (datatype == TLONG) { ffpclj(fptr, colnum, firstrow, firstelem, nelem, (long *) array, status); } else if (datatype == TLONGLONG) { ffpcljj(fptr, colnum, firstrow, firstelem, nelem, (LONGLONG *) array, status); } else if (datatype == TFLOAT) { ffpcle(fptr, colnum, firstrow, firstelem, nelem, (float *) array, status); } else if (datatype == TDOUBLE) { ffpcld(fptr, colnum, firstrow, firstelem, nelem, (double *) array, status); } else if (datatype == TCOMPLEX) { ffpcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, (float *) array, status); } else if (datatype == TDBLCOMPLEX) { ffpcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, (double *) array, status); } else if (datatype == TLOGICAL) { ffpcll(fptr, colnum, firstrow, firstelem, nelem, (char *) array, status); } else if (datatype == TSTRING) { ffpcls(fptr, colnum, firstrow, firstelem, nelem, (char **) array, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffpcn( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of elements to write */ void *array, /* I - array of values that are written */ void *nulval, /* I - pointer to the null value */ int *status) /* IO - error status */ /* Write an array of values to a table column. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS column is not the same as the array being written). */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (nulval == NULL) /* null value not defined? */ { ffpcl(fptr, datatype, colnum, firstrow, firstelem, nelem, array, status); return(*status); } if (datatype == TBYTE) { ffpcnb(fptr, colnum, firstrow, firstelem, nelem, (unsigned char *) array, *(unsigned char *) nulval, status); } else if (datatype == TSBYTE) { ffpcnsb(fptr, colnum, firstrow, firstelem, nelem, (signed char *) array, *(signed char *) nulval, status); } else if (datatype == TUSHORT) { ffpcnui(fptr, colnum, firstrow, firstelem, nelem, (unsigned short *) array, *(unsigned short *) nulval, status); } else if (datatype == TSHORT) { ffpcni(fptr, colnum, firstrow, firstelem, nelem, (short *) array, *(unsigned short *) nulval, status); } else if (datatype == TUINT) { ffpcnuk(fptr, colnum, firstrow, firstelem, nelem, (unsigned int *) array, *(unsigned int *) nulval, status); } else if (datatype == TINT) { ffpcnk(fptr, colnum, firstrow, firstelem, nelem, (int *) array, *(int *) nulval, status); } else if (datatype == TULONG) { ffpcnuj(fptr, colnum, firstrow, firstelem, nelem, (unsigned long *) array, *(unsigned long *) nulval, status); } else if (datatype == TLONG) { ffpcnj(fptr, colnum, firstrow, firstelem, nelem, (long *) array, *(long *) nulval, status); } else if (datatype == TLONGLONG) { ffpcnjj(fptr, colnum, firstrow, firstelem, nelem, (LONGLONG *) array, *(LONGLONG *) nulval, status); } else if (datatype == TFLOAT) { ffpcne(fptr, colnum, firstrow, firstelem, nelem, (float *) array, *(float *) nulval, status); } else if (datatype == TDOUBLE) { ffpcnd(fptr, colnum, firstrow, firstelem, nelem, (double *) array, *(double *) nulval, status); } else if (datatype == TCOMPLEX) { ffpcne(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, (float *) array, *(float *) nulval, status); } else if (datatype == TDBLCOMPLEX) { ffpcnd(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, (double *) array, *(double *) nulval, status); } else if (datatype == TLOGICAL) { ffpcnl(fptr, colnum, firstrow, firstelem, nelem, (char *) array, *(char *) nulval, status); } else if (datatype == TSTRING) { ffpcns(fptr, colnum, firstrow, firstelem, nelem, (char **) array, (char *) nulval, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int fits_iter_set_by_name(iteratorCol *col, /* I - iterator col structure */ fitsfile *fptr, /* I - FITS file pointer */ char *colname, /* I - column name */ int datatype, /* I - column datatype */ int iotype) /* I - InputCol, InputOutputCol, or OutputCol */ /* set all the parameters for an iterator column, by column name */ { col->fptr = fptr; strcpy(col->colname, colname); col->colnum = 0; /* set column number undefined since name is given */ col->datatype = datatype; col->iotype = iotype; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_by_num(iteratorCol *col, /* I - iterator column structure */ fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - column number */ int datatype, /* I - column datatype */ int iotype) /* I - InputCol, InputOutputCol, or OutputCol */ /* set all the parameters for an iterator column, by column number */ { col->fptr = fptr; col->colnum = colnum; col->datatype = datatype; col->iotype = iotype; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_file(iteratorCol *col, /* I - iterator column structure */ fitsfile *fptr) /* I - FITS file pointer */ /* set iterator column parameter */ { col->fptr = fptr; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_colname(iteratorCol *col, /* I - iterator col structure */ char *colname) /* I - column name */ /* set iterator column parameter */ { strcpy(col->colname, colname); col->colnum = 0; /* set column number undefined since name is given */ return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_colnum(iteratorCol *col, /* I - iterator column structure */ int colnum) /* I - column number */ /* set iterator column parameter */ { col->colnum = colnum; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_datatype(iteratorCol *col, /* I - iterator col structure */ int datatype) /* I - column datatype */ /* set iterator column parameter */ { col->datatype = datatype; return(0); } /*--------------------------------------------------------------------------*/ int fits_iter_set_iotype(iteratorCol *col, /* I - iterator column structure */ int iotype) /* I - InputCol, InputOutputCol, or OutputCol */ /* set iterator column parameter */ { col->iotype = iotype; return(0); } /*--------------------------------------------------------------------------*/ fitsfile * fits_iter_get_file(iteratorCol *col) /* I -iterator col structure */ /* get iterator column parameter */ { return(col->fptr); } /*--------------------------------------------------------------------------*/ char * fits_iter_get_colname(iteratorCol *col) /* I -iterator col structure */ /* get iterator column parameter */ { return(col->colname); } /*--------------------------------------------------------------------------*/ int fits_iter_get_colnum(iteratorCol *col) /* I - iterator column structure */ /* get iterator column parameter */ { return(col->colnum); } /*--------------------------------------------------------------------------*/ int fits_iter_get_datatype(iteratorCol *col) /* I - iterator col structure */ /* get iterator column parameter */ { return(col->datatype); } /*--------------------------------------------------------------------------*/ int fits_iter_get_iotype(iteratorCol *col) /* I - iterator column structure */ /* get iterator column parameter */ { return(col->iotype); } /*--------------------------------------------------------------------------*/ void * fits_iter_get_array(iteratorCol *col) /* I - iterator col structure */ /* get iterator column parameter */ { return(col->array); } /*--------------------------------------------------------------------------*/ long fits_iter_get_tlmin(iteratorCol *col) /* I - iterator column structure */ /* get iterator column parameter */ { return(col->tlmin); } /*--------------------------------------------------------------------------*/ long fits_iter_get_tlmax(iteratorCol *col) /* I - iterator column structure */ /* get iterator column parameter */ { return(col->tlmax); } /*--------------------------------------------------------------------------*/ long fits_iter_get_repeat(iteratorCol *col) /* I - iterator col structure */ /* get iterator column parameter */ { return(col->repeat); } /*--------------------------------------------------------------------------*/ char * fits_iter_get_tunit(iteratorCol *col) /* I - iterator col structure */ /* get iterator column parameter */ { return(col->tunit); } /*--------------------------------------------------------------------------*/ char * fits_iter_get_tdisp(iteratorCol *col) /* I -iterator col structure */ /* get iterator column parameter */ { return(col->tdisp); } /*--------------------------------------------------------------------------*/ int ffiter(int n_cols, iteratorCol *cols, long offset, long n_per_loop, int (*work_fn)(long total_n, long offset, long first_n, long n_values, int n_cols, iteratorCol *cols, void *userPointer), void *userPointer, int *status) /* The iterator function. This function will pass the specified columns from a FITS table or pixels from a FITS image to the user-supplied function. Depending on the size of the table or image, only a subset of the rows or pixels may be passed to the function on each call, in which case the function will be called multiple times until all the rows or pixels have been processed. */ { typedef struct /* structure to store the column null value */ { int nullsize; /* length of the null value, in bytes */ union { /* default null value for the column */ char *stringnull; unsigned char charnull; signed char scharnull; int intnull; short shortnull; long longnull; unsigned int uintnull; unsigned short ushortnull; unsigned long ulongnull; float floatnull; double doublenull; LONGLONG longlongnull; } null; } colNulls; void *dataptr, *defaultnull; colNulls *col; int ii, jj, tstatus, naxis, bitpix; int typecode, hdutype, jtype, type, anynul, nfiles, nbytes; long totaln, nleft, frow, felement, n_optimum, i_optimum, ntodo; long rept = 0, rowrept, width, tnull, naxes[9] = {1,1,1,1,1,1,1,1,1}, groups; double zeros = 0.; char message[FLEN_ERRMSG], keyname[FLEN_KEYWORD], nullstr[FLEN_VALUE]; char **stringptr, *nullptr, *cptr; if (*status > 0) return(*status); if (n_cols < 0 || n_cols > 999 ) { ffpmsg("Illegal number of columms (ffiter)"); return(*status = BAD_COL_NUM); /* negative number of columns */ } col = calloc(n_cols, sizeof(colNulls) ); /* memory for the null values */ /*------------------------------------------------------------*/ /* Make sure column numbers and datatypes are in legal range */ /* and column numbers and datatypes are legal. */ /* Also fill in other parameters in the column structure. */ /*------------------------------------------------------------*/ ffghdt(cols[0].fptr, &hdutype, status); /* type of first HDU */ for (jj = 0; jj < n_cols; jj++) { /* check that output datatype code value is legal */ type = cols[jj].datatype; /* Allow variable length arrays for InputCol and InputOutputCol columns, but not for OutputCol columns. Variable length arrays have a negative type code value. */ if ((cols[jj].iotype != OutputCol) && (type<0)) { type*=-1; } if (type != 0 && type != TBYTE && type != TSBYTE && type != TLOGICAL && type != TSTRING && type != TSHORT && type != TINT && type != TLONG && type != TFLOAT && type != TDOUBLE && type != TCOMPLEX && type != TULONG && type != TUSHORT && type != TDBLCOMPLEX && type != TLONGLONG ) { if (type < 0) { sprintf(message, "Variable length array not allowed for output column number %d (ffiter)", jj + 1); } else { sprintf(message, "Illegal datatype for column number %d: %d (ffiter)", jj + 1, cols[jj].datatype); } ffpmsg(message); return(*status = BAD_DATATYPE); } /* initialize TLMINn, TLMAXn, column name, and display format */ cols[jj].tlmin = 0; cols[jj].tlmax = 0; cols[jj].tunit[0] = '\0'; cols[jj].tdisp[0] = '\0'; ffghdt(cols[jj].fptr, &jtype, status); /* get HDU type */ if (hdutype == IMAGE_HDU) { if (jtype != IMAGE_HDU) { sprintf(message, "File %d not positioned to an image extension (ffiter)", jj + 1); return(*status = NOT_IMAGE); } /* since this is an image, set a dummy column number = 0 */ cols[jj].colnum = 0; strcpy(cols[jj].colname, "IMAGE"); /* dummy name for images */ tstatus = 0; ffgkys(cols[jj].fptr, "BUNIT", cols[jj].tunit, 0, &tstatus); } else { if (jtype == IMAGE_HDU) { sprintf(message, "File %d not positioned to a table extension (ffiter)", jj + 1); return(*status = NOT_TABLE); } if (cols[jj].colnum < 1) { /* find the column number for the named column */ if (ffgcno(cols[jj].fptr, CASEINSEN, cols[jj].colname, &cols[jj].colnum, status) ) { sprintf(message, "Column '%s' not found for column number %d (ffiter)", cols[jj].colname, jj + 1); ffpmsg(message); return(*status); } } if (cols[jj].colnum < 1 || cols[jj].colnum > ((cols[jj].fptr)->Fptr)->tfield) { sprintf(message, "Column %d has illegal table position number: %d (ffiter)", jj + 1, cols[jj].colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } /* look for column description keywords and update structure */ tstatus = 0; ffkeyn("TLMIN", cols[jj].colnum, keyname, &tstatus); ffgkyj(cols[jj].fptr, keyname, &cols[jj].tlmin, 0, &tstatus); tstatus = 0; ffkeyn("TLMAX", cols[jj].colnum, keyname, &tstatus); ffgkyj(cols[jj].fptr, keyname, &cols[jj].tlmax, 0, &tstatus); tstatus = 0; ffkeyn("TTYPE", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, cols[jj].colname, 0, &tstatus); if (tstatus) cols[jj].colname[0] = '\0'; tstatus = 0; ffkeyn("TUNIT", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, cols[jj].tunit, 0, &tstatus); tstatus = 0; ffkeyn("TDISP", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, cols[jj].tdisp, 0, &tstatus); } } /*-----------------------------------------------------------------*/ /* use the first file to set the total number of values to process */ /*-----------------------------------------------------------------*/ offset = maxvalue(offset, 0L); /* make sure offset is legal */ if (hdutype == IMAGE_HDU) /* get total number of pixels in the image */ { fits_get_img_dim(cols[0].fptr, &naxis, status); fits_get_img_size(cols[0].fptr, 9, naxes, status); tstatus = 0; ffgkyj(cols[0].fptr, "GROUPS", &groups, NULL, &tstatus); if (!tstatus && groups && (naxis > 1) && (naxes[0] == 0) ) { /* this is a random groups file, with NAXIS1 = 0 */ /* Use GCOUNT, the number of groups, as the first multiplier */ /* to calculate the total number of pixels in all the groups. */ ffgkyj(cols[0].fptr, "GCOUNT", &totaln, NULL, status); } else { totaln = naxes[0]; } for (ii = 1; ii < naxis; ii++) totaln *= naxes[ii]; frow = 1; felement = 1 + offset; } else /* get total number or rows in the table */ { ffgkyj(cols[0].fptr, "NAXIS2", &totaln, 0, status); frow = 1 + offset; felement = 1; } /* adjust total by the input starting offset value */ totaln -= offset; totaln = maxvalue(totaln, 0L); /* don't allow negative number */ /*------------------------------------------------------------------*/ /* Determine number of values to pass to work function on each loop */ /*------------------------------------------------------------------*/ if (n_per_loop == 0) { /* Determine optimum number of values for each iteration. */ /* Look at all the fitsfile pointers to determine the number */ /* of unique files. */ nfiles = 1; ffgrsz(cols[0].fptr, &n_optimum, status); for (jj = 1; jj < n_cols; jj++) { for (ii = 0; ii < jj; ii++) { if (cols[ii].fptr == cols[jj].fptr) break; } if (ii == jj) /* this is a new file */ { nfiles++; ffgrsz(cols[jj].fptr, &i_optimum, status); n_optimum = minvalue(n_optimum, i_optimum); } } n_optimum = n_optimum / nfiles; n_optimum = maxvalue(n_optimum, 1); } else if (n_per_loop < 0) /* must pass all the values at one time */ { n_optimum = totaln; } else /* calling routine specified how many values to pass at a time */ { n_optimum = minvalue(n_per_loop, totaln); } /*--------------------------------------*/ /* allocate work arrays for each column */ /* and determine the null pixel value */ /*--------------------------------------*/ for (jj = 0; jj < n_cols; jj++) { /* get image or column datatype and vector length */ if (hdutype == IMAGE_HDU) /* get total number of pixels in the image */ { fits_get_img_type(cols[jj].fptr, &bitpix, status); switch(bitpix) { case BYTE_IMG: typecode = TBYTE; break; case SHORT_IMG: typecode = TSHORT; break; case LONG_IMG: typecode = TLONG; break; case FLOAT_IMG: typecode = TFLOAT; break; case DOUBLE_IMG: typecode = TDOUBLE; break; case LONGLONG_IMG: typecode = TLONGLONG; break; } } else { if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept, &width, status) > 0) goto cleanup; if (typecode < 0) { /* if any variable length arrays, then the */ n_optimum = 1; /* must process the table 1 row at a time */ /* Allow variable length arrays for InputCol and InputOutputCol columns, but not for OutputCol columns. Variable length arrays have a negative type code value. */ if (cols[jj].iotype == OutputCol) { sprintf(message, "Variable length array not allowed for output column number %d (ffiter)", jj + 1); ffpmsg(message); return(*status = BAD_DATATYPE); } } } /* special case where sizeof(long) = 8: use TINT instead of TLONG */ if (abs(typecode) == TLONG && sizeof(long) == 8 && sizeof(int) == 4) { if(typecode<0) { typecode = -TINT; } else { typecode = TINT; } } /* Special case: interprete 'X' column as 'B' */ if (abs(typecode) == TBIT) { typecode = typecode / TBIT * TBYTE; rept = (rept + 7) / 8; } if (cols[jj].datatype == 0) /* output datatype not specified? */ { /* special case if sizeof(long) = 8: use TINT instead of TLONG */ if (abs(typecode) == TLONG && sizeof(long) == 8 && sizeof(int) == 4) cols[jj].datatype = TINT; else cols[jj].datatype = abs(typecode); } /* calc total number of elements to do on each iteration */ if (hdutype == IMAGE_HDU || cols[jj].datatype == TSTRING) { ntodo = n_optimum; cols[jj].repeat = 1; /* get the BLANK keyword value, if it exists */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tstatus = 0; ffgkyj(cols[jj].fptr, "BLANK", &tnull, 0, &tstatus); if (tstatus) { tnull = 0L; /* no null values */ } } } else { if (typecode < 0) { /* get max size of the variable length vector; dont't trust the value given by the TFORM keyword */ rept = 1; for (ii = 0; ii < totaln; ii++) { ffgdes(cols[jj].fptr, cols[jj].colnum, frow + ii, &rowrept, NULL, status); rept = maxvalue(rept, rowrept); } } ntodo = n_optimum * rept; /* vector columns */ cols[jj].repeat = rept; /* get the TNULL keyword value, if it exists */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tstatus = 0; if (hdutype == ASCII_TBL) /* TNULLn value is a string */ { ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, nullstr, 0, &tstatus); if (tstatus) { tnull = 0L; /* keyword doesn't exist; no null values */ } else { cptr = nullstr; while (*cptr == ' ') /* skip over leading blanks */ cptr++; if (*cptr == '\0') /* TNULLn is all blanks? */ tnull = LONG_MIN; else { /* attempt to read TNULLn string as an integer */ ffc2ii(nullstr, &tnull, &tstatus); if (tstatus) tnull = LONG_MIN; /* choose smallest value */ } /* to represent nulls */ } } else /* Binary table; TNULLn value is an integer */ { ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus); ffgkyj(cols[jj].fptr, keyname, &tnull, 0, &tstatus); if (tstatus) { tnull = 0L; /* keyword doesn't exist; no null values */ } else if (tnull == 0) { /* worst possible case: a value of 0 is used to */ /* represent nulls in the FITS file. We have to */ /* use a non-zero null value here (zero is used to */ /* mean there are no null values in the array) so we */ /* will use the smallest possible integer instead. */ tnull = LONG_MIN; /* choose smallest possible value */ } } } } /* Note that the data array starts with 2nd element; */ /* 1st element of the array gives the null data value */ switch (cols[jj].datatype) { case TBYTE: cols[jj].array = calloc(ntodo + 1, sizeof(char)); col[jj].nullsize = sizeof(char); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tnull = minvalue(tnull, 255); tnull = maxvalue(tnull, 0); col[jj].null.charnull = (unsigned char) tnull; } else { col[jj].null.charnull = (unsigned char) 255; /* use 255 as null */ } break; case TSBYTE: cols[jj].array = calloc(ntodo + 1, sizeof(char)); col[jj].nullsize = sizeof(char); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tnull = minvalue(tnull, 127); tnull = maxvalue(tnull, -128); col[jj].null.scharnull = (signed char) tnull; } else { col[jj].null.scharnull = (signed char) -128; /* use -128 null */ } break; case TSHORT: cols[jj].array = calloc(ntodo + 1, sizeof(short)); col[jj].nullsize = sizeof(short); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tnull = minvalue(tnull, SHRT_MAX); tnull = maxvalue(tnull, SHRT_MIN); col[jj].null.shortnull = (short) tnull; } else { col[jj].null.shortnull = SHRT_MIN; /* use minimum as null */ } break; case TUSHORT: cols[jj].array = calloc(ntodo + 1, sizeof(unsigned short)); col[jj].nullsize = sizeof(unsigned short); /* bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tnull = minvalue(tnull, USHRT_MAX); tnull = maxvalue(tnull, 0); /* don't allow negative value */ col[jj].null.ushortnull = (unsigned short) tnull; } else { col[jj].null.ushortnull = USHRT_MAX; /* use maximum null */ } break; case TINT: cols[jj].array = calloc(sizeof(int), ntodo + 1); col[jj].nullsize = sizeof(int); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tnull = minvalue(tnull, INT_MAX); tnull = maxvalue(tnull, INT_MIN); col[jj].null.intnull = (int) tnull; } else { col[jj].null.intnull = INT_MIN; /* use minimum as null */ } break; case TUINT: cols[jj].array = calloc(ntodo + 1, sizeof(unsigned int)); col[jj].nullsize = sizeof(unsigned int); /* bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { tnull = minvalue(tnull, INT32_MAX); tnull = maxvalue(tnull, 0); col[jj].null.uintnull = (unsigned int) tnull; } else { col[jj].null.intnull = UINT_MAX; /* use maximum as null */ } break; case TLONG: cols[jj].array = calloc(ntodo + 1, sizeof(long)); col[jj].nullsize = sizeof(long); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { col[jj].null.longnull = tnull; } else { col[jj].null.longnull = LONG_MIN; /* use minimum as null */ } break; case TULONG: cols[jj].array = calloc(ntodo + 1, sizeof(unsigned long)); col[jj].nullsize = sizeof(unsigned long); /* bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { if (tnull < 0) /* can't use a negative null value */ col[jj].null.ulongnull = LONG_MAX; else col[jj].null.ulongnull = (unsigned long) tnull; } else { col[jj].null.ulongnull = LONG_MAX; /* use maximum as null */ } break; case TFLOAT: cols[jj].array = calloc(ntodo + 1, sizeof(float)); col[jj].nullsize = sizeof(float); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { col[jj].null.floatnull = (float) tnull; } else { col[jj].null.floatnull = FLOATNULLVALUE; /* special value */ } break; case TCOMPLEX: cols[jj].array = calloc((ntodo * 2) + 1, sizeof(float)); col[jj].nullsize = sizeof(float); /* number of bytes per value */ col[jj].null.floatnull = FLOATNULLVALUE; /* special value */ break; case TDOUBLE: cols[jj].array = calloc(ntodo + 1, sizeof(double)); col[jj].nullsize = sizeof(double); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG) { col[jj].null.doublenull = (double) tnull; } else { col[jj].null.doublenull = DOUBLENULLVALUE; /* special value */ } break; case TDBLCOMPLEX: cols[jj].array = calloc((ntodo * 2) + 1, sizeof(double)); col[jj].nullsize = sizeof(double); /* number of bytes per value */ col[jj].null.doublenull = DOUBLENULLVALUE; /* special value */ break; case TSTRING: /* allocate array of pointers to all the strings */ if( hdutype==ASCII_TBL ) rept = width; stringptr = calloc((ntodo + 1) , sizeof(stringptr)); cols[jj].array = stringptr; col[jj].nullsize = rept + 1; /* number of bytes per value */ if (stringptr) { /* allocate string to store the null string value */ col[jj].null.stringnull = calloc(rept + 1, sizeof(char) ); col[jj].null.stringnull[1] = 1; /* to make sure string != 0 */ /* allocate big block for the array of table column strings */ stringptr[0] = calloc((ntodo + 1) * (rept + 1), sizeof(char) ); if (stringptr[0]) { for (ii = 1; ii <= ntodo; ii++) { /* pointer to each string */ stringptr[ii] = stringptr[ii - 1] + (rept + 1); } /* get the TNULL keyword value, if it exists */ tstatus = 0; ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus); ffgkys(cols[jj].fptr, keyname, nullstr, 0, &tstatus); if (!tstatus) strncat(col[jj].null.stringnull, nullstr, rept); } else { ffpmsg("ffiter failed to allocate memory arrays"); *status = MEMORY_ALLOCATION; /* memory allocation failed */ goto cleanup; } } break; case TLOGICAL: cols[jj].array = calloc(ntodo + 1, sizeof(char)); col[jj].nullsize = sizeof(char); /* number of bytes per value */ /* use value = 2 to flag null values in logical columns */ col[jj].null.charnull = 2; break; case TLONGLONG: cols[jj].array = calloc(ntodo + 1, sizeof(LONGLONG)); col[jj].nullsize = sizeof(LONGLONG); /* number of bytes per value */ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG || abs(typecode) == TLONGLONG) { col[jj].null.longlongnull = tnull; } else { col[jj].null.longlongnull = LONGLONG_MIN; /* use minimum as null */ } break; default: sprintf(message, "Column %d datatype currently not supported: %d: (ffiter)", jj + 1, cols[jj].datatype); ffpmsg(message); *status = BAD_DATATYPE; goto cleanup; } /* end of switch block */ /* check that all the arrays were allocated successfully */ if (!cols[jj].array) { ffpmsg("ffiter failed to allocate memory arrays"); *status = MEMORY_ALLOCATION; /* memory allocation failed */ goto cleanup; } } /*--------------------------------------------------*/ /* main loop while there are values left to process */ /*--------------------------------------------------*/ nleft = totaln; while (nleft) { ntodo = minvalue(nleft, n_optimum); /* no. of values for this loop */ /* read input columns from FITS file(s) */ for (jj = 0; jj < n_cols; jj++) { if (cols[jj].iotype != OutputCol) { if (cols[jj].datatype == TSTRING) { stringptr = cols[jj].array; dataptr = stringptr + 1; defaultnull = col[jj].null.stringnull; /* ptr to the null value */ } else { dataptr = (char *) cols[jj].array + col[jj].nullsize; defaultnull = &col[jj].null.charnull; /* ptr to the null value */ } if (hdutype == IMAGE_HDU) { if (ffgpv(cols[jj].fptr, cols[jj].datatype, felement, cols[jj].repeat * ntodo, defaultnull, dataptr, &anynul, status) > 0) { break; } } else { if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0) goto cleanup; if (typecode<0) { /* get size of the variable length vector */ ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status); } if (ffgcv(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow, felement, cols[jj].repeat * ntodo, defaultnull, dataptr, &anynul, status) > 0) { break; } } /* copy the appropriate null value into first array element */ if (anynul) /* are there any nulls in the data? */ { if (cols[jj].datatype == TSTRING) { stringptr = cols[jj].array; memcpy(*stringptr, col[jj].null.stringnull, col[jj].nullsize); } else { memcpy(cols[jj].array, defaultnull, col[jj].nullsize); } } else /* no null values so copy zero into first element */ { if (cols[jj].datatype == TSTRING) { stringptr = cols[jj].array; memset(*stringptr, 0, col[jj].nullsize); } else { memset(cols[jj].array, 0, col[jj].nullsize); } } } } if (*status > 0) break; /* looks like an error occurred; quit immediately */ /* call work function */ if (hdutype == IMAGE_HDU) *status = work_fn(totaln, offset, felement, ntodo, n_cols, cols, userPointer); else *status = work_fn(totaln, offset, frow, ntodo, n_cols, cols, userPointer); if (*status > 0 || *status < -1 ) break; /* looks like an error occurred; quit immediately */ /* write output columns before quiting if status = -1 */ tstatus = 0; for (jj = 0; jj < n_cols; jj++) { if (cols[jj].iotype != InputCol) { if (cols[jj].datatype == TSTRING) { stringptr = cols[jj].array; dataptr = stringptr + 1; nullptr = *stringptr; nbytes = 2; } else { dataptr = (char *) cols[jj].array + col[jj].nullsize; nullptr = (char *) cols[jj].array; nbytes = col[jj].nullsize; } if (memcmp(nullptr, &zeros, nbytes) ) { /* null value flag not zero; must check for and write nulls */ if (hdutype == IMAGE_HDU) { if (ffppn(cols[jj].fptr, cols[jj].datatype, felement, cols[jj].repeat * ntodo, dataptr, nullptr, &tstatus) > 0) break; } else { if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0) goto cleanup; if (typecode<0) /* variable length array colum */ { ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status); } if (ffpcn(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow, felement, cols[jj].repeat * ntodo, dataptr, nullptr, &tstatus) > 0) break; } } else { /* no null values; just write the array */ if (hdutype == IMAGE_HDU) { if (ffppr(cols[jj].fptr, cols[jj].datatype, felement, cols[jj].repeat * ntodo, dataptr, &tstatus) > 0) break; } else { if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0) goto cleanup; if (typecode<0) /* variable length array column */ { ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status); } if (ffpcl(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow, felement, cols[jj].repeat * ntodo, dataptr, &tstatus) > 0) break; } } } } if (*status == 0) *status = tstatus; /* propagate any error status from the writes */ if (*status) break; /* exit on any error */ nleft -= ntodo; if (hdutype == IMAGE_HDU) felement += ntodo; else frow += ntodo; } cleanup: /*----------------------------------*/ /* free work arrays for the columns */ /*----------------------------------*/ for (jj = 0; jj < n_cols; jj++) { if (cols[jj].datatype == TSTRING) { if (cols[jj].array) { stringptr = cols[jj].array; free(*stringptr); /* free the block of strings */ free(col[jj].null.stringnull); /* free the null string */ } } free(cols[jj].array); /* memory for the array of values from the col */ } free(col); /* the structure containing the null values */ return(*status); } indi-0.5/src/cfitsio/getcoli.c0000644000175000017500000021610310610474374014143 0ustar jrjr/* This file, getcoli.c, contains routines that read data elements from */ /* a FITS image or table, with short datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvi( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ short nulval, /* I - value for undefined pixels */ short *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; short nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TSHORT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcli(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfi( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ short *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TSHORT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcli(fptr, 2, row, firstelem, nelem, 1, 2, 0, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2di(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ short nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3di(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3di(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ short nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; LONGLONG nfits, narray; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}; LONGLONG lpixel[3]; short nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TSHORT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgcli(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgcli(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvi(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ short nulval, /* I - value to set undefined pixels */ short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; short nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvi is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TSHORT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvi: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgcli(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfi(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ short *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; short nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvi is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TSHORT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvi: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgcli(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpi( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ short *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgcli(fptr, 1, row, firstelem, nelem, 1, 1, 0, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvi(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ short nulval, /* I - value for null pixels */ short *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfi(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ short *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { short dummy = 0; ffgcli(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcli( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ short nulval, /* I - value for null pixels if nultyp = 1 */ short *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TSHORT) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, &array[next], status); if (convert) fffi2i2(&array[next], ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8i2( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1i2((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4i2((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4i2((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8i2((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstri2((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgcli).", dtemp+1, dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgcli).", dtemp+1, dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1i2(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (short) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2i2(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { memcpy(output, input, ntodo * sizeof(short) ); } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4i2(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8i2(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4i2(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (zero > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8i2(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (zero > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstri2(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } indi-0.5/src/cfitsio/getcols.c0000644000175000017500000007004410610474375014160 0ustar jrjr/* This file, getcols.c, contains routines that read data elements from */ /* a FITS image or table, with a character string datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include /* stddef.h is apparently needed to define size_t */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgcvs( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of strings to read */ char *nulval, /* I - string for null pixels */ char **array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of string values from a column in the current FITS HDU. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = null in which case no checks for undefined pixels will be made. */ { char cdummy[2]; ffgcls(fptr, colnum, firstrow, firstelem, nelem, 1, nulval, array, cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfs( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of strings to read */ char **array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of string values from a column in the current FITS HDU. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { char dummy[2]; ffgcls(fptr, colnum, firstrow, firstelem, nelem, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcls( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of strings to read */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ char *nulval, /* I - value for null pixels if nultyp = 1 */ char **array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of string values from a column in the current FITS HDU. Returns a formated string value, regardless of the datatype of the column */ { int tcode, hdutype, tstatus, scaled, intcol, dwidth, nulwidth, ll, dlen; long ii, jj; tcolumn *colptr; char message[FLEN_ERRMSG], *carray, keyname[FLEN_KEYWORD]; char cform[20], dispfmt[20], tmpstr[400], *flgarray, tmpnull[80]; unsigned char byteval; float *earray; double *darray, tscale = 1.0; LONGLONG *llarray; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* rescan header if data structure is undefined */ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) return(*status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { sprintf(message, "Specified column number is out of range: %d", colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = abs(colptr->tdatatype); if (tcode == TSTRING) { /* simply call the string column reading routine */ ffgcls2(fptr, colnum, firstrow, firstelem, nelem, nultyp, nulval, array, nularray, anynul, status); } else if (tcode == TLOGICAL) { /* allocate memory for the array of logical values */ carray = (char *) malloc((size_t) nelem); /* call the logical column reading routine */ ffgcll(fptr, colnum, firstrow, firstelem, nelem, nultyp, *nulval, carray, nularray, anynul, status); if (*status <= 0) { /* convert logical values to "T", "F", or "N" (Null) */ for (ii = 0; ii < nelem; ii++) { if (carray[ii] == 1) strcpy(array[ii], "T"); else if (carray[ii] == 0) strcpy(array[ii], "F"); else /* undefined values = 2 */ strcpy(array[ii],"N"); } } free(carray); /* free the memory */ } else if (tcode == TCOMPLEX) { /* allocate memory for the array of double values */ earray = (float *) calloc((size_t) (nelem * 2), sizeof(float) ); ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, FLOATNULLVALUE, earray, nularray, anynul, status); if (*status <= 0) { /* determine the format for the output strings */ ffgcdw(fptr, colnum, &dwidth, status); dwidth = (dwidth - 3) / 2; /* use the TDISPn keyword if it exists */ ffkeyn("TDISP", colnum, keyname, status); tstatus = 0; cform[0] = '\0'; if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0) { /* convert the Fortran style format to a C style format */ ffcdsp(dispfmt, cform); } if (!cform[0]) strcpy(cform, "%14.6E"); /* write the formated string for each value: "(real,imag)" */ jj = 0; for (ii = 0; ii < nelem; ii++) { strcpy(array[ii], "("); /* test for null value */ if (earray[jj] == FLOATNULLVALUE) { strcpy(tmpstr, "NULL"); if (nultyp == 2) nularray[ii] = 1; } else sprintf(tmpstr, cform, earray[jj]); strncat(array[ii], tmpstr, dwidth); strcat(array[ii], ","); jj++; /* test for null value */ if (earray[jj] == FLOATNULLVALUE) { strcpy(tmpstr, "NULL"); if (nultyp == 2) nularray[ii] = 1; } else sprintf(tmpstr, cform, earray[jj]); strncat(array[ii], tmpstr, dwidth); strcat(array[ii], ")"); jj++; } } free(earray); /* free the memory */ } else if (tcode == TDBLCOMPLEX) { /* allocate memory for the array of double values */ darray = (double *) calloc((size_t) (nelem * 2), sizeof(double) ); ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2, 1, 1, DOUBLENULLVALUE, darray, nularray, anynul, status); if (*status <= 0) { /* determine the format for the output strings */ ffgcdw(fptr, colnum, &dwidth, status); dwidth = (dwidth - 3) / 2; /* use the TDISPn keyword if it exists */ ffkeyn("TDISP", colnum, keyname, status); tstatus = 0; cform[0] = '\0'; if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0) { /* convert the Fortran style format to a C style format */ ffcdsp(dispfmt, cform); } if (!cform[0]) strcpy(cform, "%23.15E"); /* write the formated string for each value: "(real,imag)" */ jj = 0; for (ii = 0; ii < nelem; ii++) { strcpy(array[ii], "("); /* test for null value */ if (darray[jj] == DOUBLENULLVALUE) { strcpy(tmpstr, "NULL"); if (nultyp == 2) nularray[ii] = 1; } else sprintf(tmpstr, cform, darray[jj]); strncat(array[ii], tmpstr, dwidth); strcat(array[ii], ","); jj++; /* test for null value */ if (darray[jj] == DOUBLENULLVALUE) { strcpy(tmpstr, "NULL"); if (nultyp == 2) nularray[ii] = 1; } else sprintf(tmpstr, cform, darray[jj]); strncat(array[ii], tmpstr, dwidth); strcat(array[ii], ")"); jj++; } } free(darray); /* free the memory */ } else if (tcode == TLONGLONG) { /* allocate memory for the array of LONGLONG values */ llarray = (LONGLONG *) calloc((size_t) nelem, sizeof(LONGLONG) ); flgarray = (char *) calloc((size_t) nelem, sizeof(char) ); dwidth = 20; /* max width of displayed long long integer value */ if (ffgcfjj(fptr, colnum, firstrow, firstelem, nelem, llarray, flgarray, anynul, status) > 0) { free(flgarray); free(llarray); return(*status); } /* write the formated string for each value */ if (nulval) { strcpy(tmpnull, nulval); nulwidth = strlen(nulval); } else { strcpy(tmpnull, " "); nulwidth = 1; } for (ii = 0; ii < nelem; ii++) { if ( flgarray[ii] ) { *array[ii] = '\0'; if (dwidth < nulwidth) strncat(array[ii], tmpnull, dwidth); else sprintf(array[ii],"%*s",dwidth,tmpnull); if (nultyp == 2) nularray[ii] = 1; } else { #if defined(_MSC_VER) /* Microsoft Visual C++ 6.0 uses '%I64d' syntax for 8-byte integers */ sprintf(tmpstr, "%20I64d", llarray[ii]); #elif (USE_LL_SUFFIX == 1) sprintf(tmpstr, "%20lld", llarray[ii]); #else sprintf(tmpstr, "%20ld", llarray[ii]); #endif *array[ii] = '\0'; strncat(array[ii], tmpstr, 20); } } free(flgarray); free(llarray); /* free the memory */ } else { /* allocate memory for the array of double values */ darray = (double *) calloc((size_t) nelem, sizeof(double) ); /* read all other numeric type columns as doubles */ if (ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, nultyp, DOUBLENULLVALUE, darray, nularray, anynul, status) > 0) { free(darray); return(*status); } /* determine the format for the output strings */ ffgcdw(fptr, colnum, &dwidth, status); /* check if column is scaled */ ffkeyn("TSCAL", colnum, keyname, status); tstatus = 0; scaled = 0; if (ffgkyd(fptr, keyname, &tscale, NULL, &tstatus) == 0) { if (tscale != 1.0) scaled = 1; /* yes, this is a scaled column */ } intcol = 0; if (tcode <= TLONG && !scaled) intcol = 1; /* this is an unscaled integer column */ /* use the TDISPn keyword if it exists */ ffkeyn("TDISP", colnum, keyname, status); tstatus = 0; cform[0] = '\0'; if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0) { /* convert the Fortran style TDISPn to a C style format */ ffcdsp(dispfmt, cform); } if (!cform[0]) { /* no TDISPn keyword; use TFORMn instead */ ffkeyn("TFORM", colnum, keyname, status); ffgkys(fptr, keyname, dispfmt, NULL, status); if (scaled && tcode <= TSHORT) { /* scaled short integer column == float */ strcpy(cform, "%#14.6G"); } else if (scaled && tcode == TLONG) { /* scaled long integer column == double */ strcpy(cform, "%#23.15G"); } else { ffghdt(fptr, &hdutype, status); if (hdutype == ASCII_TBL) { /* convert the Fortran style TFORMn to a C style format */ ffcdsp(dispfmt, cform); } else { /* this is a binary table, need to convert the format */ if (tcode == TBIT) { /* 'X' */ strcpy(cform, "%4d"); } else if (tcode == TBYTE) { /* 'B' */ strcpy(cform, "%4d"); } else if (tcode == TSHORT) { /* 'I' */ strcpy(cform, "%6d"); } else if (tcode == TLONG) { /* 'J' */ strcpy(cform, "%11.0f"); intcol = 0; /* needed to support unsigned int */ } else if (tcode == TFLOAT) { /* 'E' */ strcpy(cform, "%#14.6G"); } else if (tcode == TDOUBLE) { /* 'D' */ strcpy(cform, "%#23.15G"); } } } } if (nulval) { strcpy(tmpnull, nulval); nulwidth = strlen(nulval); } else { strcpy(tmpnull, " "); nulwidth = 1; } /* write the formated string for each value */ for (ii = 0; ii < nelem; ii++) { if (tcode == TBIT) { byteval = (char) darray[ii]; for (ll=0; ll < 8; ll++) { if ( ((unsigned char) (byteval << ll)) >> 7 ) *(array[ii] + ll) = '1'; else *(array[ii] + ll) = '0'; } *(array[ii] + 8) = '\0'; } /* test for null value */ else if ( (nultyp == 1 && darray[ii] == DOUBLENULLVALUE) || (nultyp == 2 && nularray[ii]) ) { *array[ii] = '\0'; if (dwidth < nulwidth) strncat(array[ii], tmpnull, dwidth); else sprintf(array[ii],"%*s",dwidth,tmpnull); } else { if (intcol) sprintf(tmpstr, cform, (int) darray[ii]); else sprintf(tmpstr, cform, darray[ii]); /* fill field with '*' if number is too wide */ dlen = strlen(tmpstr); if (dlen > dwidth) { memset(tmpstr, '*', dwidth); } *array[ii] = '\0'; strncat(array[ii], tmpstr, dwidth); } } free(darray); /* free the memory */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcdw( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column (1 = 1st col) */ int *width, /* O - display width */ int *status) /* IO - error status */ /* Get Column Display Width. */ { tcolumn *colptr; char *cptr; char message[FLEN_ERRMSG], keyname[FLEN_KEYWORD], dispfmt[20]; int tcode, hdutype, tstatus, scaled; double tscale; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { sprintf(message, "Specified column number is out of range: %d", colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = abs(colptr->tdatatype); /* use the TDISPn keyword if it exists */ ffkeyn("TDISP", colnum, keyname, status); *width = 0; tstatus = 0; if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0) { /* parse TDISPn get the display width */ cptr = dispfmt; while(*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == 'A' || *cptr == 'a' || *cptr == 'I' || *cptr == 'i' || *cptr == 'O' || *cptr == 'o' || *cptr == 'Z' || *cptr == 'z' || *cptr == 'F' || *cptr == 'f' || *cptr == 'E' || *cptr == 'e' || *cptr == 'D' || *cptr == 'd' || *cptr == 'G' || *cptr == 'g') { while(!isdigit((int) *cptr) && *cptr != '\0') /* find 1st digit */ cptr++; *width = atoi(cptr); if (tcode >= TCOMPLEX) *width = (2 * (*width)) + 3; } } if (*width == 0) { /* no valid TDISPn keyword; use TFORMn instead */ ffkeyn("TFORM", colnum, keyname, status); ffgkys(fptr, keyname, dispfmt, NULL, status); /* check if column is scaled */ ffkeyn("TSCAL", colnum, keyname, status); tstatus = 0; scaled = 0; if (ffgkyd(fptr, keyname, &tscale, NULL, &tstatus) == 0) { if (tscale != 1.0) scaled = 1; /* yes, this is a scaled column */ } if (scaled && tcode <= TSHORT) { /* scaled short integer col == float; default format is 14.6G */ *width = 14; } else if (scaled && tcode == TLONG) { /* scaled long integer col == double; default format is 23.15G */ *width = 23; } else { ffghdt(fptr, &hdutype, status); /* get type of table */ if (hdutype == ASCII_TBL) { /* parse TFORMn get the display width */ cptr = dispfmt; while(!isdigit((int) *cptr) && *cptr != '\0') /* find 1st digit */ cptr++; *width = atoi(cptr); } else { /* this is a binary table */ if (tcode == TBIT) /* 'X' */ *width = 8; else if (tcode == TBYTE) /* 'B' */ *width = 4; else if (tcode == TSHORT) /* 'I' */ *width = 6; else if (tcode == TLONG) /* 'J' */ *width = 11; else if (tcode == TLONGLONG) /* 'K' */ *width = 20; else if (tcode == TFLOAT) /* 'E' */ *width = 14; else if (tcode == TDOUBLE) /* 'D' */ *width = 23; else if (tcode == TCOMPLEX) /* 'C' */ *width = 31; else if (tcode == TDBLCOMPLEX) /* 'M' */ *width = 49; else if (tcode == TLOGICAL) /* 'L' */ *width = 1; else if (tcode == TSTRING) /* 'A' */ { cptr = dispfmt; while(!isdigit((int) *cptr) && *cptr != '\0') cptr++; *width = atoi(cptr); if (*width < 1) *width = 1; /* default is at least 1 column */ } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgcls2 ( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of strings to read */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ char *nulval, /* I - value for null pixels if nultyp = 1 */ char **array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of string values from a column in the current FITS HDU. */ { double dtemp; long nullen; int tcode, maxelem, hdutype, nulcheck; long twidth, incre; long ii, jj, ntodo; LONGLONG repeat, startpos, elemnum, readptr, tnull, rowlen, rownum, remain, next; double scale, zero; char tform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ tcolumn *colptr; double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ char *buffer, *arrayptr; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (colnum < 1 || colnum > (fptr->Fptr)->tfield) { sprintf(message, "Specified column number is out of range: %d", colnum); ffpmsg(message); return(*status = BAD_COL_NUM); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode == -TSTRING) /* variable length column in a binary table? */ { /* only read a single string; ignore value of firstelem */ if (ffgcprll( fptr, colnum, firstrow, 1, 1, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); remain = 1; twidth = (long) repeat; } else if (tcode == TSTRING) { if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); remain = nelem; } else return(*status = NOT_ASCII_COL); nullen = strlen(snull); /* length of the undefined pixel string */ if (nullen == 0) nullen = 1; /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (nultyp == 1 && nulval && nulval[0] == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /* null value string in ASCII table not defined */ else if (nullen > twidth) nulcheck = 0; /* null value string is longer than width of column */ /* thus impossible for any column elements to = null */ /*---------------------------------------------------------------------*/ /* Now read the strings one at a time from the FITS column. */ /*---------------------------------------------------------------------*/ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, readptr, REPORT_EOF, status); /* move to read position */ /* read the array of strings from the FITS file into the buffer */ if (incre == twidth) ffgbyt(fptr, ntodo * twidth, cbuff, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, cbuff, status); /* copy from the buffer into the user's array of strings */ /* work backwards from last char of last string to 1st char of 1st */ buffer = ((char *) cbuff) + (ntodo * twidth) - 1; for (ii = (long) (next + ntodo - 1); ii >= next; ii--) { arrayptr = array[ii] + twidth - 1; for (jj = twidth - 1; jj > 0; jj--) /* ignore trailing blanks */ { if (*buffer == ' ') { buffer--; arrayptr--; } else break; } *(arrayptr + 1) = 0; /* write the string terminator */ for (; jj >= 0; jj--) /* copy the string itself */ { *arrayptr = *buffer; buffer--; arrayptr--; } /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (nulcheck && !strncmp(snull, array[ii], nullen) ) { *anynul = 1; /* this is a null value */ if (nultyp == 1) { if (nulval) strcpy(array[ii], nulval); else strcpy(array[ii], " "); } else nularray[ii] = 1; } } if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; sprintf(message, "Error reading elements %.0f thru %.0f of data array (ffpcls).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ next += ntodo; remain -= ntodo; if (remain) { elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ return(*status); } indi-0.5/src/cfitsio/pliocomp.c0000644000175000017500000001565410610474375014350 0ustar jrjr/* stdlib is needed for the abs function */ #include /* The following prototype code was provided by Doug Tody, NRAO, for performing conversion between pixel arrays and line lists. The compression technique is used in IRAF. */ int pl_p2li (int *pxsrc, int xs, short *lldst, int npix); int pl_l2pi (short *ll_src, int xs, int *px_dst, int npix); /* * PL_P2L -- Convert a pixel array to a line list. The length of the list is * returned as the function value. * * Translated from the SPP version using xc -f, f2c. 8Sep99 DCT. */ #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) #endif #ifndef max #define max(a,b) (((a)>(b))?(a):(b)) #endif int pl_p2li (int *pxsrc, int xs, short *lldst, int npix) /* int *pxsrc; input pixel array */ /* int xs; starting index in pxsrc (?) */ /* short *lldst; encoded line list */ /* int npix; number of pixels to convert */ { /* System generated locals */ int ret_val, i__1, i__2, i__3; /* Local variables */ static int zero, v, x1, hi, ip, dv, xe, np, op, iz, nv, pv, nz; /* Parameter adjustments */ --lldst; --pxsrc; /* Function Body */ if (! (npix <= 0)) { goto L110; } ret_val = 0; goto L100; L110: lldst[3] = -100; lldst[2] = 7; lldst[1] = 0; lldst[6] = 0; lldst[7] = 0; xe = xs + npix - 1; op = 8; zero = 0; /* Computing MAX */ i__1 = zero, i__2 = pxsrc[xs]; pv = max(i__1,i__2); x1 = xs; iz = xs; hi = 1; i__1 = xe; for (ip = xs; ip <= i__1; ++ip) { if (! (ip < xe)) { goto L130; } /* Computing MAX */ i__2 = zero, i__3 = pxsrc[ip + 1]; nv = max(i__2,i__3); if (! (nv == pv)) { goto L140; } goto L120; L140: if (! (pv == 0)) { goto L150; } pv = nv; x1 = ip + 1; goto L120; L150: goto L131; L130: if (! (pv == 0)) { goto L160; } x1 = xe + 1; L160: L131: np = ip - x1 + 1; nz = x1 - iz; if (! (pv > 0)) { goto L170; } dv = pv - hi; if (! (dv != 0)) { goto L180; } hi = pv; if (! (abs(dv) > 4095)) { goto L190; } lldst[op] = (short) ((pv & 4095) + 4096); ++op; lldst[op] = (short) (pv / 4096); ++op; goto L191; L190: if (! (dv < 0)) { goto L200; } lldst[op] = (short) (-dv + 12288); goto L201; L200: lldst[op] = (short) (dv + 8192); L201: ++op; if (! (np == 1 && nz == 0)) { goto L210; } v = lldst[op - 1]; lldst[op - 1] = (short) (v | 16384); goto L91; L210: L191: L180: L170: if (! (nz > 0)) { goto L220; } L230: if (! (nz > 0)) { goto L232; } lldst[op] = (short) min(4095,nz); ++op; /* L231: */ nz += -4095; goto L230; L232: if (! (np == 1 && pv > 0)) { goto L240; } lldst[op - 1] = (short) (lldst[op - 1] + 20481); goto L91; L240: L220: L250: if (! (np > 0)) { goto L252; } lldst[op] = (short) (min(4095,np) + 16384); ++op; /* L251: */ np += -4095; goto L250; L252: L91: x1 = ip + 1; iz = x1; pv = nv; L120: ; } /* L121: */ lldst[4] = (short) ((op - 1) % 32768); lldst[5] = (short) ((op - 1) / 32768); ret_val = op - 1; goto L100; L100: return ret_val; } /* plp2li_ */ /* * PL_L2PI -- Translate a PLIO line list into an integer pixel array. * The number of pixels output (always npix) is returned as the function * value. * * Translated from the SPP version using xc -f, f2c. 8Sep99 DCT. */ int pl_l2pi (short *ll_src, int xs, int *px_dst, int npix) /* short *ll_src; encoded line list */ /* int xs; starting index in ll_src */ /* int *px_dst; output pixel array */ /* int npix; number of pixels to convert */ { /* System generated locals */ int ret_val, i__1, i__2; /* Local variables */ static int data, sw0001, otop, i__, lllen, i1, i2, x1, x2, ip, xe, np, op, pv, opcode, llfirt; static int skipwd; /* Parameter adjustments */ --px_dst; --ll_src; /* Function Body */ if (! (ll_src[3] > 0)) { goto L110; } lllen = ll_src[3]; llfirt = 4; goto L111; L110: lllen = (ll_src[5] << 15) + ll_src[4]; llfirt = ll_src[2] + 1; L111: if (! (npix <= 0 || lllen <= 0)) { goto L120; } ret_val = 0; goto L100; L120: xe = xs + npix - 1; skipwd = 0; op = 1; x1 = 1; pv = 1; i__1 = lllen; for (ip = llfirt; ip <= i__1; ++ip) { if (! skipwd) { goto L140; } skipwd = 0; goto L130; L140: opcode = ll_src[ip] / 4096; data = ll_src[ip] & 4095; sw0001 = opcode; goto L150; L160: x2 = x1 + data - 1; i1 = max(x1,xs); i2 = min(x2,xe); np = i2 - i1 + 1; if (! (np > 0)) { goto L170; } otop = op + np - 1; if (! (opcode == 4)) { goto L180; } i__2 = otop; for (i__ = op; i__ <= i__2; ++i__) { px_dst[i__] = pv; /* L190: */ } /* L191: */ goto L181; L180: i__2 = otop; for (i__ = op; i__ <= i__2; ++i__) { px_dst[i__] = 0; /* L200: */ } /* L201: */ if (! (opcode == 5 && i2 == x2)) { goto L210; } px_dst[otop] = pv; L210: L181: op = otop + 1; L170: x1 = x2 + 1; goto L151; L220: pv = (ll_src[ip + 1] << 12) + data; skipwd = 1; goto L151; L230: pv += data; goto L151; L240: pv -= data; goto L151; L250: pv += data; goto L91; L260: pv -= data; L91: if (! (x1 >= xs && x1 <= xe)) { goto L270; } px_dst[op] = pv; ++op; L270: ++x1; goto L151; L150: ++sw0001; if (sw0001 < 1 || sw0001 > 8) { goto L151; } switch ((int)sw0001) { case 1: goto L160; case 2: goto L220; case 3: goto L230; case 4: goto L240; case 5: goto L160; case 6: goto L160; case 7: goto L250; case 8: goto L260; } L151: if (! (x1 > xe)) { goto L280; } goto L131; L280: L130: ; } L131: i__1 = npix; for (i__ = op; i__ <= i__1; ++i__) { px_dst[i__] = 0; /* L290: */ } /* L291: */ ret_val = npix; goto L100; L100: return ret_val; } /* pll2pi_ */ indi-0.5/src/cfitsio/eval.l0000644000175000017500000003554210605175703013461 0ustar jrjr%{ /************************************************************************/ /* */ /* CFITSIO Lexical Parser */ /* */ /* This file is one of 3 files containing code which parses an */ /* arithmetic expression and evaluates it in the context of an input */ /* FITS file table extension. The CFITSIO lexical parser is divided */ /* into the following 3 parts/files: the CFITSIO "front-end", */ /* eval_f.c, contains the interface between the user/CFITSIO and the */ /* real core of the parser; the FLEX interpreter, eval_l.c, takes the */ /* input string and parses it into tokens and identifies the FITS */ /* information required to evaluate the expression (ie, keywords and */ /* columns); and, the BISON grammar and evaluation routines, eval_y.c, */ /* receives the FLEX output and determines and performs the actual */ /* operations. The files eval_l.c and eval_y.c are produced from */ /* running flex and bison on the files eval.l and eval.y, respectively. */ /* (flex and bison are available from any GNU archive: see www.gnu.org) */ /* */ /* The grammar rules, rather than evaluating the expression in situ, */ /* builds a tree, or Nodal, structure mapping out the order of */ /* operations and expression dependencies. This "compilation" process */ /* allows for much faster processing of multiple rows. This technique */ /* was developed by Uwe Lammers of the XMM Science Analysis System, */ /* although the CFITSIO implementation is entirely code original. */ /* */ /* */ /* Modification History: */ /* */ /* Kent Blackburn c1992 Original parser code developed for the */ /* FTOOLS software package, in particular, */ /* the fselect task. */ /* Kent Blackburn c1995 BIT column support added */ /* Peter D Wilson Feb 1998 Vector column support added */ /* Peter D Wilson May 1998 Ported to CFITSIO library. User */ /* interface routines written, in essence */ /* making fselect, fcalc, and maketime */ /* capabilities available to all tools */ /* via single function calls. */ /* Peter D Wilson Jun 1998 Major rewrite of parser core, so as to */ /* create a run-time evaluation tree, */ /* inspired by the work of Uwe Lammers, */ /* resulting in a speed increase of */ /* 10-100 times. */ /* Peter D Wilson Jul 1998 gtifilter(a,b,c,d) function added */ /* Peter D Wilson Aug 1998 regfilter(a,b,c,d) function added */ /* Peter D Wilson Jul 1999 Make parser fitsfile-independent, */ /* allowing a purely vector-based usage */ /* */ /************************************************************************/ #include #include #include #ifdef sparc #include #else #include #endif #include "eval_defs.h" ParseData gParse; /* Global structure holding all parser information */ /***** Internal functions *****/ int yyGetVariable( char *varName, YYSTYPE *varVal ); static int find_variable( char *varName ); static int expr_read( char *buf, int nbytes ); /***** Definitions *****/ #define YY_NO_UNPUT /* Don't include YYUNPUT function */ #define YY_NEVER_INTERACTIVE 1 #define MAXCHR 256 #define MAXBIT 128 #define OCT_0 "000" #define OCT_1 "001" #define OCT_2 "010" #define OCT_3 "011" #define OCT_4 "100" #define OCT_5 "101" #define OCT_6 "110" #define OCT_7 "111" #define OCT_X "xxx" #define HEX_0 "0000" #define HEX_1 "0001" #define HEX_2 "0010" #define HEX_3 "0011" #define HEX_4 "0100" #define HEX_5 "0101" #define HEX_6 "0110" #define HEX_7 "0111" #define HEX_8 "1000" #define HEX_9 "1001" #define HEX_A "1010" #define HEX_B "1011" #define HEX_C "1100" #define HEX_D "1101" #define HEX_E "1110" #define HEX_F "1111" #define HEX_X "xxxx" /* MJT - 13 June 1996 read from buffer instead of stdin (as per old ftools.skel) */ #undef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( (result = expr_read( (char *) buf, max_size )) < 0 ) \ YY_FATAL_ERROR( "read() in flex scanner failed" ); %} bit ([bB][01xX]+) oct ([oO][01234567xX]+) hex ([hH][0123456789aAbBcCdDeEfFxX]+) integer [0-9]+ boolean (t|f|T|F) real ([0-9]*"."[0-9]+)|([0-9]*"."*[0-9]+[eEdD][+-]?[0-9]+)|([0-9]*".") constant ("#"[a-zA-Z0-9_]+)|("#""$"[^\n]*"$") string ([\"][^\"\n]*[\"])|([\'][^\'\n]*[\']) variable ([a-zA-Z_][a-zA-Z0-9_]*)|("$"[^$\n]*"$") function [a-zA-Z][a-zA-Z0-9]+"(" intcast ("(int)"|"(INT)") fltcast ("(float)"|"(FLOAT)"|"(double)"|"(DOUBLE)") power ("^"|"**") not ("!"|".not."|".NOT."|"not."|"NOT.") or ("||"|".or."|".OR."|"or."|"OR.") and ("&&"|".and."|".AND."|"and."|"AND.") equal ("=="|".eq."|".EQ."|"eq."|"EQ.") not_equal ("!="|".ne."|".NE."|"ne."|"NE.") greater (">"|".gt."|".GT."|"gt."|"GT.") lesser ("<"|".lt."|".LT."|"lt."|"LT.") greater_eq (">="|"=>"|".ge."|".GE."|"ge."|"GE.") lesser_eq ("<="|"=<"|".le."|".LE."|"le."|"LE.") nl \n %% [ \t]+ ; {bit} { int len; len = strlen(yytext); while (yytext[len] == ' ') len--; len = len - 1; strncpy(yylval.str,&yytext[1],len); yylval.str[len] = '\0'; return( BITSTR ); } {oct} { int len; char tmpstring[256]; char bitstring[256]; len = strlen(yytext); while (yytext[len] == ' ') len--; len = len - 1; strncpy(tmpstring,&yytext[1],len); tmpstring[len] = '\0'; bitstring[0] = '\0'; len = 0; while ( tmpstring[len] != '\0') { switch ( tmpstring[len] ) { case '0': strcat(bitstring,OCT_0); break; case '1': strcat(bitstring,OCT_1); break; case '2': strcat(bitstring,OCT_2); break; case '3': strcat(bitstring,OCT_3); break; case '4': strcat(bitstring,OCT_4); break; case '5': strcat(bitstring,OCT_5); break; case '6': strcat(bitstring,OCT_6); break; case '7': strcat(bitstring,OCT_7); break; case 'x': case 'X': strcat(bitstring,OCT_X); break; } len++; } strcpy( yylval.str, bitstring ); return( BITSTR ); } {hex} { int len; char tmpstring[256]; char bitstring[256]; len = strlen(yytext); while (yytext[len] == ' ') len--; len = len - 1; strncpy(tmpstring,&yytext[1],len); tmpstring[len] = '\0'; bitstring[0] = '\0'; len = 0; while ( tmpstring[len] != '\0') { switch ( tmpstring[len] ) { case '0': strcat(bitstring,HEX_0); break; case '1': strcat(bitstring,HEX_1); break; case '2': strcat(bitstring,HEX_2); break; case '3': strcat(bitstring,HEX_3); break; case '4': strcat(bitstring,HEX_4); break; case '5': strcat(bitstring,HEX_5); break; case '6': strcat(bitstring,HEX_6); break; case '7': strcat(bitstring,HEX_7); break; case '8': strcat(bitstring,HEX_8); break; case '9': strcat(bitstring,HEX_9); break; case 'a': case 'A': strcat(bitstring,HEX_A); break; case 'b': case 'B': strcat(bitstring,HEX_B); break; case 'c': case 'C': strcat(bitstring,HEX_C); break; case 'd': case 'D': strcat(bitstring,HEX_D); break; case 'e': case 'E': strcat(bitstring,HEX_E); break; case 'f': case 'F': strcat(bitstring,HEX_F); break; case 'x': case 'X': strcat(bitstring,HEX_X); break; } len++; } strcpy( yylval.str, bitstring ); return( BITSTR ); } {integer} { yylval.lng = atol(yytext); return( LONG ); } {boolean} { if ((yytext[0] == 't') || (yytext[0] == 'T')) yylval.log = 1; else yylval.log = 0; return( BOOLEAN ); } {real} { yylval.dbl = atof(yytext); return( DOUBLE ); } {constant} { if( !strcasecmp(yytext,"#PI") ) { yylval.dbl = (double)(4) * atan((double)(1)); return( DOUBLE ); } else if( !strcasecmp(yytext,"#E") ) { yylval.dbl = exp((double)(1)); return( DOUBLE ); } else if( !strcasecmp(yytext,"#DEG") ) { yylval.dbl = ((double)4)*atan((double)1)/((double)180); return( DOUBLE ); } else if( !strcasecmp(yytext,"#ROW") ) { return( ROWREF ); } else if( !strcasecmp(yytext,"#NULL") ) { return( NULLREF ); } else if( !strcasecmp(yytext,"#SNULL") ) { return( SNULLREF ); } else { int len; if (yytext[1] == '$') { len = strlen(yytext) - 3; yylval.str[0] = '#'; strncpy(yylval.str+1,&yytext[2],len); yylval.str[len+1] = '\0'; yytext = yylval.str; } return( (*gParse.getData)(yytext, &yylval) ); } } {string} { int len; len = strlen(yytext) - 2; strncpy(yylval.str,&yytext[1],len); yylval.str[len] = '\0'; return( STRING ); } {variable} { int len,type; if (yytext[0] == '$') { len = strlen(yytext) - 2; strncpy(yylval.str,&yytext[1],len); yylval.str[len] = '\0'; yytext = yylval.str; } type = yyGetVariable(yytext, &yylval); return( type ); } {function} { char *fname; int len=0; fname = &yylval.str[0]; while( (fname[len]=toupper(yytext[len])) ) len++; if( FSTRCMP(fname,"BOX(")==0 || FSTRCMP(fname,"CIRCLE(")==0 || FSTRCMP(fname,"ELLIPSE(")==0 || FSTRCMP(fname,"NEAR(")==0 || FSTRCMP(fname,"ISNULL(")==0 ) /* Return type is always boolean */ return( BFUNCTION ); else if( FSTRCMP(fname,"GTIFILTER(")==0 ) return( GTIFILTER ); else if( FSTRCMP(fname,"REGFILTER(")==0 ) return( REGFILTER ); else return( FUNCTION ); } {intcast} { return( INTCAST ); } {fltcast} { return( FLTCAST ); } {power} { return( POWER ); } {not} { return( NOT ); } {or} { return( OR ); } {and} { return( AND ); } {equal} { return( EQ ); } {not_equal} { return( NE ); } {greater} { return( GT ); } {lesser} { return( LT ); } {greater_eq} { return( GTE ); } {lesser_eq} { return( LTE ); } {nl} { return( '\n' ); } . { return( yytext[0] ); } %% int yywrap() { /* MJT -- 13 June 1996 Supplied for compatibility with pre-2.5.1 versions of flex which do not recognize %option noyywrap */ return(1); } /* expr_read is lifted from old ftools.skel. Now we can use any version of flex with no .skel file necessary! MJT - 13 June 1996 keep a memory of how many bytes have been read previously, so that an unlimited-sized buffer can be supported. PDW - 28 Feb 1998 */ static int expr_read(char *buf, int nbytes) { int n; n = 0; if( !gParse.is_eobuf ) { do { buf[n++] = gParse.expr[gParse.index++]; } while ((nlng = varNum; } return( type ); } static int find_variable(char *varName) { int i; if( gParse.nCols ) for( i=0; i c2) return(1); if (c1 == 0) return(0); s1++; s2++; } } int strncasecmp(const char *s1, const char *s2, size_t n) { char c1, c2; for (; n-- ;) { c1 = toupper( *s1 ); c2 = toupper( *s2 ); if (c1 < c2) return(-1); if (c1 > c2) return(1); if (c1 == 0) return(0); s1++; s2++; } return(0); } #endif indi-0.5/src/cfitsio/ricecomp.h0000644000175000017500000000461510610474402014316 0ustar jrjr/* @(#) buffer.h 1.1 98/07/21 12:34:27 */ /* buffer.h: structure for compression to buffer rather than to a file, including * bit I/O buffer * * R. White, 19 June 1998 */ typedef unsigned char Buffer_t; typedef struct { int bitbuffer; /* bit buffer */ int bits_to_go; /* bits to go in buffer */ Buffer_t *start; /* start of buffer */ Buffer_t *current; /* current position in buffer */ Buffer_t *end; /* end of buffer */ } Buffer; #define buffree(mf) (free(mf->start), free(mf)) #define bufused(mf) (mf->current - mf->start) #define bufreset(mf) (mf->current = mf->start) /* * getcbuf, putcbuf macros for character IO to buffer * putcbuf returns EOF on end of buffer, else returns 0 */ #define getcbuf(mf) ((mf->current >= mf->end) ? EOF : *(mf->current)++) #define putcbuf(c,mf) \ ((mf->current >= mf->end) ? \ EOF :\ ((*(mf->current)++ = c), 0)) /* * bufalloc sets up buffer of length n */ /* not needed by CFITSIO static Buffer *bufalloc(int n) { Buffer *mf; mf = (Buffer *) malloc(sizeof(Buffer)); if (mf == (Buffer *)NULL) return((Buffer *)NULL); mf->start = (Buffer_t *) malloc(n*sizeof(Buffer_t)); if (mf->start == (Buffer_t *)NULL) { free(mf); return((Buffer *)NULL); } mf->bits_to_go = 8; mf->end = mf->start + n; mf->current = mf->start; return(mf); } */ /* * bufrealloc extends buffer (or truncates it) by * reallocating memory */ /* not needed by CFITSIO static int bufrealloc(Buffer *mf, int n) { int len; len = mf->current - mf->start; * silently throw away data if buffer is already longer than n * if (len>n) len = n; if (len<0) len = 0; mf->start = (Buffer_t *) realloc(mf->start, n*sizeof(Buffer_t)); if (mf->start == (Buffer_t *)NULL) return(0); mf->end = mf->start + n; mf->current = mf->start + len; return(n); } */ /* * bufdump dumps contents of buffer to outfile and resets * it to be empty. Returns number of bytes written. * * Note we don't write out the bit buffer -- you must call * done_outputing_bits() first to ensure that the bit buffer * is written out. I do it this way to allow incremental * buffer dumps while bit IO is still going on. */ /* not needed by CFITSIO static int bufdump(FILE *outfile, Buffer *buffer) { int ndump; ndump = bufused(buffer); if (fwrite(buffer->start, 1, ndump, outfile) != ndump) { fprintf(stderr, "bufdump: error in write\n"); exit(1); } bufreset(buffer); return(ndump); } */ indi-0.5/src/cfitsio/eval_defs.h0000644000175000017500000001010410610474402014433 0ustar jrjr#include #include #include #include #if defined(__sgi) || defined(__hpux) #include #endif #ifdef sparc #include #endif #include "fitsio2.h" #ifndef FFBISON #include "eval_tab.h" #endif #define MAXDIMS 5 #define MAXSUBS 10 #define MAXVARNAME 80 #define CONST_OP -1000 #define pERROR -1 typedef struct { char name[MAXVARNAME+1]; int type; long nelem; int naxis; long naxes[MAXDIMS]; char *undef; void *data; } DataInfo; typedef struct { long nelem; int naxis; long naxes[MAXDIMS]; char *undef; union { double dbl; long lng; char log; char str[256]; double *dblptr; long *lngptr; char *logptr; char **strptr; void *ptr; } data; } lval; typedef struct Node { int operation; void (*DoOp)(struct Node *this); int nSubNodes; int SubNodes[MAXSUBS]; int type; lval value; } Node; typedef struct { fitsfile *def_fptr; int (*getData)( char *dataName, void *dataValue ); int (*loadData)( int varNum, long fRow, long nRows, void *data, char *undef ); int compressed; int timeCol; int parCol; int valCol; char *expr; int index; int is_eobuf; Node *Nodes; int nNodes; int nNodesAlloc; int resultNode; long firstRow; long nRows; int nCols; iteratorCol *colData; DataInfo *varData; PixelFilter *pixFilter; long firstDataRow; long nDataRows; long totalRows; int datatype; int hdutype; int status; } ParseData; typedef enum { rnd_fct = 1001, sum_fct, nelem_fct, sin_fct, cos_fct, tan_fct, asin_fct, acos_fct, atan_fct, sinh_fct, cosh_fct, tanh_fct, exp_fct, log_fct, log10_fct, sqrt_fct, abs_fct, atan2_fct, ceil_fct, floor_fct, round_fct, min1_fct, min2_fct, max1_fct, max2_fct, near_fct, circle_fct, box_fct, elps_fct, isnull_fct, defnull_fct, gtifilt_fct, regfilt_fct, ifthenelse_fct, row_fct, null_fct, median_fct, average_fct, stddev_fct, nonnull_fct, angsep_fct, gasrnd_fct, poirnd_fct } funcOp; extern ParseData gParse; #ifdef __cplusplus extern "C" { #endif int ffparse(void); int fflex(void); void ffrestart(FILE*); void Evaluate_Parser( long firstRow, long nRows ); #ifdef __cplusplus } #endif indi-0.5/src/cfitsio/quantize.c0000644000175000017500000006052510610474375014363 0ustar jrjr/* The following code was written by Richard White at STScI and made available for use in CFITSIO in July 1999. */ # include # include # include #include "fitsio2.h" /* nearest integer function */ # define NINT(x) ((x >= 0.) ? (int) (x + 0.5) : (int) (x - 0.5)) # define SORT_CUTOFF 100 /* used by xMedian */ # define NELEM 5 /* used by xMedian */ #define NULL_VALUE -2147483647 /* value used to represent undefined pixels */ #define N_RESERVED_VALUES 1 /* number of reserved values, starting with */ /* and including NULL_VALUE. These values */ /* may not be used to represent the quantized */ /* and scaled floating point pixel values */ /* factor to convert from median deviation to rms */ # define MEDIAN_TO_RMS 1.4826 /* more than this many standard deviations from the mean is an outlier */ # define SIGMA_CLIP 5. # define NITER 3 /* number of sigma-clipping iterations */ static float xMedian (float [], int); static void InsertionSort (float x[], int); static int FqCompare (const void *, const void *); static void FqMean (float [], int, double *, double *); /*---------------------------------------------------------------------------*/ /* this routine used to be called 'quantize' (WDP) */ int fits_quantize_float (float fdata[], int nx, float in_null_value, int noise_bits, int idata[], double *bscale, double *bzero, int *iminval, int *imaxval) { /* arguments: float fdata[] i: array of image pixels to be compressed int nx i: length of fdata array float in_null_value i: value used to represent undefined pixels in fdata int noise_bits i: quantization level (number of bits) int idata[] o: values of fdata after applying bzero and bscale double bscale o: scale factor double bzero o: zero offset int iminval o: minimum quantized value that is returned int imaxval o: maximum quantized value that is returned The function value will be one if the input fdata were copied to idata; in this case the parameters bscale and bzero can be used to convert back to nearly the original floating point values: fdata ~= idata * bscale + bzero. If the function value is zero, the data were not copied to idata. */ float *diff; /* difference array */ int ndiff; /* size of diff array */ int intflag; /* true if data are really integer */ int i, j, iter; /* loop indices */ int anynulls = 0; /* set if fdata contains any null values */ int nshift, itemp; int first_nonnull = 0; double mean, stdev; /* mean and RMS of differences */ double minval = 0., maxval = 0.; /* min & max of fdata */ double delta; /* bscale, 1 in idata = delta in fdata */ double zeropt; /* bzero */ double median; /* median of diff array */ double temp; if (nx <= 1) { *bscale = 1.; *bzero = 0.; return (0); } *iminval = INT32_MAX; *imaxval = INT32_MIN; /* Check to see if data are "floating point integer." */ /* This also catches the case where all the pixels are null */ /* Since idata and fdata may point to the same memory location, */ /* we cannot write to idata unless we are sure we don't need */ /* the corresponding float value any more */ intflag = 1; /* initial value */ for (i = 0; i < nx; i++) { if (fdata[i] == in_null_value) { anynulls = 1; } else if (fdata[i] > INT32_MAX || fdata[i] < NULL_VALUE + N_RESERVED_VALUES) { intflag = 0; /* not integer */ break; } else { itemp = (int)(fdata[i] + 0.5); if (itemp != fdata[i]) { intflag = 0; /* not integer */ break; } } } if (intflag) { /* data are "floating point integer" */ for (i = 0; i < nx; i++) { if (fdata[i] == in_null_value) { idata[i] = NULL_VALUE; anynulls = 1; } else { idata[i] = (int)(fdata[i] + 0.5); *iminval = minvalue(idata[i], *iminval); *imaxval = maxvalue(idata[i], *imaxval); } } } if (intflag) { /* data are "floating point integer" */ if (anynulls) { /* Shift the range of values so they lie close to NULL_VALUE. */ /* This will make the compression more efficient. */ /* Maximum allowed shift is 2^31 - 1 = 2147483646 */ /* Can't use 2147483647 because OSF says this is not a legal number */ if (*iminval >= 0) { nshift = -(NULL_VALUE + 1) - N_RESERVED_VALUES; } else { nshift = *iminval - NULL_VALUE - N_RESERVED_VALUES; } for (i = 0; i < nx; i++) { if (idata[i] != NULL_VALUE) { idata[i] -= nshift; } } *iminval = *iminval - nshift; *imaxval = *imaxval - nshift; *bscale = 1.; *bzero = (double) nshift; } else { /* there were no null values, so no need to shift the range */ *bscale = 1.; *bzero = 0.; } return (1); } /* data are not "floating point integer"; need to quantize them */ /* find first non-null pixel, and initialize min and max values */ for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { minval = fdata[i]; maxval = fdata[i]; first_nonnull = i; break; } } /* allocate temporary buffer for differences */ ndiff = nx - first_nonnull - 1; if ((diff = (float *) malloc (ndiff * sizeof (float))) == NULL) { ffpmsg("Out of memory in 'fits_quantize_float'."); return (0); } /* calc ABS difference between successive non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = (float) (fabs (fdata[i] - fdata[j])); j = i; ndiff++; minval = minvalue(minval, fdata[i]); maxval = maxvalue(maxval, fdata[i]); } } /* check if there were any null values */ if (ndiff + 1 == nx) anynulls = 0; else anynulls = 1; /* use median of absolute deviations */ median = xMedian (diff, ndiff); stdev = median * MEDIAN_TO_RMS; /* substitute sigma-clipping if median is zero */ if (stdev == 0.0) { /* calculate differences between non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = fdata[i] - fdata[j]; j = i; ndiff++; } } FqMean (diff, ndiff, &mean, &stdev); for (iter = 0; iter < NITER; iter++) { j = 0; for (i = 0; i < ndiff; i++) { if (fabs (diff[i] - mean) < SIGMA_CLIP * stdev) { if (j < i) diff[j] = diff[i]; j++; } } if (j == ndiff) break; ndiff = j; FqMean (diff, ndiff, &mean, &stdev); } } free (diff); delta = stdev / pow (2., (double)noise_bits); if (delta == 0. && ndiff > 0) return (0); /* Zero variance in differences! Don't quantize. */ /* check that the range of quantized levels is not > range of int */ if ((maxval - minval) / delta > 2. * 2147483647. - N_RESERVED_VALUES ) return (0); /* don't quantize */ if (!anynulls) { /* don't have to check for nulls */ /* return all positive values, if possible since some */ /* compression algorithms either only work for positive integers, */ /* or are more efficient. */ if ((maxval - minval) / delta < 2147483647. - N_RESERVED_VALUES ) { zeropt = minval; } else { /* center the quantized levels around zero */ zeropt = (minval + maxval) / 2.; } for (i = 0; i < nx; i++) { temp = (fdata[i] - zeropt) / delta; idata[i] = NINT (temp); } } else { /* data contains null values; shift the range to be */ /* close to the value used to represent null values */ zeropt = minval - delta * (NULL_VALUE + N_RESERVED_VALUES); for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { temp = (fdata[i] - zeropt) / delta; idata[i] = NINT (temp); } else idata[i] = NULL_VALUE; } } /* calc min and max values */ temp = (minval - zeropt) / delta; *iminval = NINT (temp); temp = (maxval - zeropt) / delta; *imaxval = NINT (temp); *bscale = delta; *bzero = zeropt; return (1); /* yes, data have been quantized */ } /*---------------------------------------------------------------------------*/ int fits_quantize_double (double fdata[], int nx, double in_null_value, int noise_bits, int idata[], double *bscale, double *bzero, int *iminval, int *imaxval) { /* arguments: double fdata[] i: array of image pixels to be compressed int nx i: length of fdata array double in_null_value i: value used to represent undefined pixels in fdata int noise_bits i: quantization level (number of bits) int idata[] o: values of fdata after applying bzero and bscale double bscale o: scale factor double bzero o: zero offset int imaxval o: maximum quantized value that is returned int iminval o: minimum quantized value that is returned The function value will be one if the input fdata were copied to idata; in this case the parameters bscale and bzero can be used to convert back to nearly the original floating point values: fdata ~= idata * bscale + bzero. If the function value is zero, the data were not copied to idata. */ float *diff; /* difference array */ int ndiff; /* size of diff array */ int intflag; /* true if data are really integer */ int i, j, iter; /* loop indices */ int anynulls = 0; /* set if fdata contains any null values */ int nshift, itemp; int first_nonnull = 0; double mean, stdev; /* mean and RMS of differences */ double minval = 0., maxval = 0.; /* min & max of fdata */ double delta; /* bscale, 1 in idata = delta in fdata */ double zeropt; /* bzero */ double median; /* median of diff array */ double temp; if (nx <= 1) { *bscale = 1.; *bzero = 0.; return (0); } *iminval = INT32_MAX; *imaxval = INT32_MIN; /* Check to see if data are "floating point integer." */ /* This also catches the case where all the pixels are null */ /* Since idata and fdata may point to the same memory location, */ /* we cannot write to idata unless we are sure we don't need */ /* the corresponding float value any more */ intflag = 1; /* initial value */ for (i = 0; i < nx; i++) { if (fdata[i] == in_null_value) { anynulls = 1; } else if (fdata[i] > INT32_MAX || fdata[i] < NULL_VALUE + N_RESERVED_VALUES) { intflag = 0; /* not integer */ break; } else { itemp = (int)(fdata[i] + 0.5); if (itemp != fdata[i]) { intflag = 0; /* not integer */ break; } } } if (intflag) { /* data are "floating point integer" */ for (i = 0; i < nx; i++) { if (fdata[i] == in_null_value) { idata[i] = NULL_VALUE; anynulls = 1; } else { idata[i] = (int)(fdata[i] + 0.5); *iminval = minvalue(idata[i], *iminval); *imaxval = maxvalue(idata[i], *imaxval); } } } if (intflag) { /* data are "floating point integer" */ if (anynulls) { /* Shift the range of values so they lie close to NULL_VALUE. */ /* This will make the compression more efficient. */ /* Maximum allowed shift is 2^31 - 1 = 2147483646 */ /* Can't use 2147483647 because OSF says this is not a legal number */ if (*iminval >= 0) { nshift = -(NULL_VALUE +1) - N_RESERVED_VALUES; } else { nshift = *iminval - NULL_VALUE - N_RESERVED_VALUES; } for (i = 0; i < nx; i++) { if (idata[i] != NULL_VALUE) { idata[i] -= nshift; } } *iminval = *iminval - nshift; *imaxval = *imaxval - nshift; *bscale = 1.; *bzero = (double) nshift; } else { /* there were no null values, so no need to shift the range */ *bscale = 1.; *bzero = 0.; } return (1); } /* data are not "floating point integer"; need to quantize them */ /* find first non-null pixel, and initialize min and max values */ for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { minval = fdata[i]; maxval = fdata[i]; first_nonnull = i; break; } } /* allocate temporary buffer for differences */ ndiff = nx - first_nonnull - 1; if ((diff = (float *) malloc (ndiff * sizeof (float))) == NULL) { ffpmsg("Out of memory in 'fits_quantize_double'."); return (0); } /* calc ABS difference between successive non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = (float) (fabs (fdata[i] - fdata[j])); j = i; ndiff++; minval = minvalue(minval, fdata[i]); maxval = maxvalue(maxval, fdata[i]); } } /* check if there were any null values */ if (ndiff + 1 == nx) anynulls = 0; else anynulls = 1; /* use median of absolute deviations */ median = xMedian (diff, ndiff); stdev = median * MEDIAN_TO_RMS; /* substitute sigma-clipping if median is zero */ if (stdev == 0.0) { /* calculate differences between non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = (float) (fdata[i] - fdata[j]); j = i; ndiff++; } } FqMean (diff, ndiff, &mean, &stdev); for (iter = 0; iter < NITER; iter++) { j = 0; for (i = 0; i < ndiff; i++) { if (fabs (diff[i] - mean) < SIGMA_CLIP * stdev) { if (j < i) diff[j] = diff[i]; j++; } } if (j == ndiff) break; ndiff = j; FqMean (diff, ndiff, &mean, &stdev); } } free (diff); delta = stdev / pow (2., (double)noise_bits); if (delta == 0. && ndiff > 0) return (0); /* Zero variance in differences! Don't quantize. */ /* check that the range of quantized levels is not > range of int */ if ((maxval - minval) / delta > 2. * 2147483647 - N_RESERVED_VALUES ) return (0); /* don't quantize */ if (!anynulls) { /* don't have to check for nulls */ /* center the quantized levels around zero */ zeropt = (minval + maxval) / 2.; for (i = 0; i < nx; i++) { temp = (fdata[i] - zeropt) / delta; idata[i] = NINT (temp); } } else { /* data contains null values; shift the range to be */ /* close to the value used to represent null values */ zeropt = minval - delta * (NULL_VALUE + N_RESERVED_VALUES); for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { temp = (fdata[i] - zeropt) / delta; idata[i] = NINT (temp); } else idata[i] = NULL_VALUE; } } /* calc min and max values */ temp = (minval - zeropt) / delta; *iminval = NINT (temp); temp = (maxval - zeropt) / delta; *imaxval = NINT (temp); *bscale = delta; *bzero = zeropt; return (1); /* yes, data have been quantized */ } /*---------------------------------------------------------------------------*/ int fits_rms_float (float fdata[], int nx, float in_null_value, double *rms, int *status) { /* Compute the background RMS (noise) in an array of image pixels. arguments: float fdata[] i: array of image pixels int nx i: length of fdata array float in_null_value i: value used to represent undefined pixels in fdata double rms o: computed RMS value */ float *diff; /* difference array */ int ndiff; /* size of diff array */ int i, j, iter; /* loop indices */ int first_nonnull = 0; double mean, stdev; /* mean and RMS of differences */ double median; /* median of diff array */ if (*status) return (*status); if (nx <= 1) { *rms = 0; return (0); } /* find first non-null pixel, and initialize min and max values */ for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { first_nonnull = i; break; } } /* allocate temporary buffer for differences */ ndiff = nx - first_nonnull - 1; if ((diff = (float *) malloc (ndiff * sizeof (float))) == NULL) { ffpmsg("Out of memory in 'fits_float_rms'."); *status = 113; /* memory allocation error */ return (0); } /* calc ABS difference between successive non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = (float) (fabs (fdata[i] - fdata[j])); j = i; ndiff++; } } /* use median of absolute deviations */ median = xMedian (diff, ndiff); stdev = median * MEDIAN_TO_RMS; /* substitute sigma-clipping if median is zero */ if (stdev == 0.0) { /* calculate differences between non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = fdata[i] - fdata[j]; j = i; ndiff++; } } FqMean (diff, ndiff, &mean, &stdev); for (iter = 0; iter < NITER; iter++) { j = 0; for (i = 0; i < ndiff; i++) { if (fabs (diff[i] - mean) < SIGMA_CLIP * stdev) { if (j < i) diff[j] = diff[i]; j++; } } if (j == ndiff) break; ndiff = j; FqMean (diff, ndiff, &mean, &stdev); } } free (diff); *rms = stdev; return (0); } /*---------------------------------------------------------------------------*/ int fits_rms_short (short fdata[], int nx, short in_null_value, double *rms, int *status) { /* Compute the background RMS (noise) in an array of image pixels. arguments: short fdata[] i: array of image pixels int nx i: length of fdata array short in_null_value i: value used to represent undefined pixels in fdata double rms o: computed RMS value */ float *diff; /* difference array */ int ndiff; /* size of diff array */ int i, j, iter; /* loop indices */ int first_nonnull = 0; double mean, stdev; /* mean and RMS of differences */ double median; /* median of diff array */ if (*status) return (*status); if (nx <= 1) { *rms = 0; return (0); } /* find first non-null pixel, and initialize min and max values */ for (i = 0; i < nx; i++) { if (fdata[i] != in_null_value) { first_nonnull = i; break; } } /* allocate temporary buffer for differences */ ndiff = nx - first_nonnull - 1; if ((diff = (float *) malloc (ndiff * sizeof (float))) == NULL) { ffpmsg("Out of memory in 'fits_float_rms'."); *status = 113; /* memory allocation error */ return (0); } /* calc ABS difference between successive non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = (float) (abs (fdata[i] - fdata[j])); j = i; ndiff++; } } /* use median of absolute deviations */ median = xMedian (diff, ndiff); stdev = median * MEDIAN_TO_RMS; /* substitute sigma-clipping if median is zero */ if (stdev == 0.0) { /* calculate differences between non-null pixels */ j = first_nonnull; ndiff = 0; for (i = j + 1 ; i < nx; i++) { if (fdata[i] != in_null_value) { diff[ndiff] = (float) (fdata[i] - fdata[j]); j = i; ndiff++; } } FqMean (diff, ndiff, &mean, &stdev); for (iter = 0; iter < NITER; iter++) { j = 0; for (i = 0; i < ndiff; i++) { if (fabs (diff[i] - mean) < SIGMA_CLIP * stdev) { if (j < i) diff[j] = diff[i]; j++; } } if (j == ndiff) break; ndiff = j; FqMean (diff, ndiff, &mean, &stdev); } } free (diff); *rms = stdev; return (0); } /*---------------------------------------------------------------------------*/ /* This computes the mean and standard deviation. */ static void FqMean (float diff[], int ndiff, double *mean, double *stdev) { int i; double sum, sumsq; double m; /* mean */ double xn; /* = ndiff */ double temp; if (ndiff < 2) { if (ndiff < 1) *mean = 0.; else *mean = diff[0]; *stdev = 0.; return; } xn = (double)ndiff; sum = 0.; sumsq = 0.; for (i = 0; i < ndiff; i++) { sum += diff[i]; sumsq += (diff[i] * diff[i]); } m = sum / xn; *mean = m; temp = (sumsq / xn - m*m) * xn; if (temp <= 0) *stdev = 0.; else *stdev = sqrt (temp / (xn-1.)); } /*---------------------------------------------------------------------------*/ /* This returns an approximation to the median. The input array will be clobbered. */ static float xMedian (float x[], int n) { /* arguments: float x[] io: the array (will be scrambled and possibly modified) int n i: number of elements in x (modified locally) */ int i, j; int next_n; int npix; int done; float median = 0.; if (n < 1) { ffpmsg("xMedian: no data"); return (0.); } if (n == 1) return (x[0]); if (n == 2) return ((float) ((x[0] + x[1]) / 2.)); done = 0; while (!done) { if (n < SORT_CUTOFF) { qsort (x, n, sizeof (float), FqCompare); if (n / 2 * 2 == n) median = (float) ((x[n/2-1] + x[n/2]) / 2.); else median = x[n/2]; return (median); } /* ignore trailing groups of less than three elements */ next_n = (n + NELEM-3) / NELEM; for (j = 0; j < next_n; j++) { i = j * NELEM; npix = minvalue (NELEM, n - j*NELEM); InsertionSort (&x[i], npix); switch (npix) { case 1: median = x[i]; break; case 2: median = (float) ((x[i] + x[i+1]) / 2.); break; case 3: median = x[i+1]; break; case 4: median = (float) ((x[i+1] + x[i+2]) / 2.); break; case 5: /* NELEM = 5 */ median = x[i+2]; break; default: ffpmsg("npix should be 1..5"); } x[j] = median; } if (next_n <= 1) done = 1; else n = next_n; } return (x[0]); } /*---------------------------------------------------------------------------*/ static void InsertionSort (float x[], int n) { float a; int i, j; for (j = 1; j < n; j++) { a = x[j]; i = j - 1; while (i >= 0 && x[i] > a) { x[i+1] = x[i]; i--; } x[i+1] = a; } } /*---------------------------------------------------------------------------*/ static int FqCompare (const void *vp, const void *vq) { const float *p = vp; const float *q = vq; if (*p > *q) return (1); else if (*p < *q) return (-1); else return (0); } indi-0.5/src/cfitsio/buffers.c0000644000175000017500000015211710610474374014155 0ustar jrjr/* This file, buffers.c, contains the core set of FITSIO routines */ /* that use or manage the internal set of IO buffers. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" static char iobuffer[NIOBUF][IOBUFLEN]; /* initialize to zero by default */ static FITSfile *bufptr[NIOBUF]; /* initialize to zero by default */ static long bufrecnum[NIOBUF]; /* initialize to zero by default */ static int dirty[NIOBUF], ageindex[NIOBUF]; /* ages get initialized in ffwhbf */ /*--------------------------------------------------------------------------*/ int ffmbyt(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG bytepos, /* I - byte position in file to move to */ int err_mode, /* I - 1=ignore error, 0 = return error */ int *status) /* IO - error status */ { /* Move to the input byte location in the file. When writing to a file, a move may sometimes be made to a position beyond the current EOF. The err_mode parameter determines whether such conditions should be returned as an error or simply ignored. */ long record; if (*status > 0) return(*status); if (bytepos < 0) return(*status = NEG_FILE_POS); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); record = (long) (bytepos / IOBUFLEN); /* zero-indexed record number */ /* if this is not the current record, then load it */ if ( ((fptr->Fptr)->curbuf < 0) || (record != bufrecnum[(fptr->Fptr)->curbuf])) ffldrc(fptr, record, err_mode, status); if (*status <= 0) (fptr->Fptr)->bytepos = bytepos; /* save new file position */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpbyt(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG nbytes, /* I - number of bytes to write */ void *buffer, /* I - buffer containing the bytes to write */ int *status) /* IO - error status */ /* put (write) the buffer of bytes to the output FITS file, starting at the current file position. Write large blocks of data directly to disk; write smaller segments to intermediate IO buffers to improve efficiency. */ { int ii, nbuff; LONGLONG filepos; long recstart, recend; long ntodo, bufpos, nspace, nwrite; char *cptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); cptr = (char *)buffer; ntodo = (long) nbytes; if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */ { /* so reload the last one that was used */ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status); } if (nbytes >= MINDIRECT) { /* write large blocks of data directly to disk instead of via buffers */ /* first, fill up the current IO buffer before flushing it to disk */ nbuff = (fptr->Fptr)->curbuf; /* current IO buffer number */ filepos = (fptr->Fptr)->bytepos; /* save the write starting position */ recstart = bufrecnum[nbuff]; /* starting record */ recend = (long) ((filepos + nbytes - 1) / IOBUFLEN); /* ending record */ /* bufpos is the starting position within the IO buffer */ bufpos = (long) (filepos - ((LONGLONG)recstart * IOBUFLEN)); nspace = IOBUFLEN - bufpos; /* amount of space left in the buffer */ if (nspace) { /* fill up the IO buffer */ memcpy(iobuffer[nbuff] + bufpos, cptr, nspace); ntodo -= nspace; /* decrement remaining number of bytes */ cptr += nspace; /* increment user buffer pointer */ filepos += nspace; /* increment file position pointer */ dirty[nbuff] = TRUE; /* mark record as having been modified */ } for (ii = 0; ii < NIOBUF; ii++) /* flush any affected buffers to disk */ { if (bufptr[ii] == fptr->Fptr && bufrecnum[ii] >= recstart && bufrecnum[ii] <= recend ) { if (dirty[ii]) /* flush modified buffer to disk */ ffbfwt(ii, status); bufptr[ii] = NULL; /* disassociate buffer from the file */ } } /* move to the correct write position */ if ((fptr->Fptr)->io_pos != filepos) ffseek(fptr->Fptr, filepos); nwrite = ((ntodo - 1) / IOBUFLEN) * IOBUFLEN; /* don't write last buff */ ffwrite(fptr->Fptr, nwrite, cptr, status); /* write the data */ ntodo -= nwrite; /* decrement remaining number of bytes */ cptr += nwrite; /* increment user buffer pointer */ (fptr->Fptr)->io_pos = filepos + nwrite; /* update the file position */ if ((fptr->Fptr)->io_pos >= (fptr->Fptr)->filesize) /* at the EOF? */ { (fptr->Fptr)->filesize = (fptr->Fptr)->io_pos; /* increment file size */ /* initialize the current buffer with the correct fill value */ if ((fptr->Fptr)->hdutype == ASCII_TBL) memset(iobuffer[nbuff], 32, IOBUFLEN); /* blank fill */ else memset(iobuffer[nbuff], 0, IOBUFLEN); /* zero fill */ } else { /* read next record */ ffread(fptr->Fptr, IOBUFLEN, iobuffer[nbuff], status); (fptr->Fptr)->io_pos += IOBUFLEN; } /* copy remaining bytes from user buffer into current IO buffer */ memcpy(iobuffer[nbuff], cptr, ntodo); dirty[nbuff] = TRUE; /* mark record as having been modified */ bufrecnum[nbuff] = recend; /* record number */ bufptr[nbuff] = fptr->Fptr; /* file pointer associated with IO buffer */ (fptr->Fptr)->logfilesize = maxvalue((fptr->Fptr)->logfilesize, (LONGLONG)(recend + 1) * IOBUFLEN); (fptr->Fptr)->bytepos = filepos + nwrite + ntodo; } else { /* bufpos is the starting position in IO buffer */ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)bufrecnum[(fptr->Fptr)->curbuf] * IOBUFLEN)); nspace = IOBUFLEN - bufpos; /* amount of space left in the buffer */ while (ntodo) { nwrite = minvalue(ntodo, nspace); /* copy bytes from user's buffer to the IO buffer */ memcpy(iobuffer[(fptr->Fptr)->curbuf] + bufpos, cptr, nwrite); ntodo -= nwrite; /* decrement remaining number of bytes */ cptr += nwrite; (fptr->Fptr)->bytepos += nwrite; /* increment file position pointer */ dirty[(fptr->Fptr)->curbuf] = TRUE; /* mark record as modified */ if (ntodo) /* load next record into a buffer */ { ffldrc(fptr, (long) ((fptr->Fptr)->bytepos / IOBUFLEN), IGNORE_EOF, status); bufpos = 0; nspace = IOBUFLEN; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffpbytoff(fitsfile *fptr, /* I - FITS file pointer */ long gsize, /* I - size of each group of bytes */ long ngroups, /* I - number of groups to write */ long offset, /* I - size of gap between groups */ void *buffer, /* I - buffer to be written */ int *status) /* IO - error status */ /* put (write) the buffer of bytes to the output FITS file, with an offset between each group of bytes. This function combines ffmbyt and ffpbyt for increased efficiency. */ { int bcurrent; long ii, bufpos, nspace, nwrite, record; char *cptr, *ioptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */ { /* so reload the last one that was used */ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status); } cptr = (char *)buffer; bcurrent = (fptr->Fptr)->curbuf; /* number of the current IO buffer */ record = bufrecnum[bcurrent]; /* zero-indexed record number */ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)record * IOBUFLEN)); /* start pos */ nspace = IOBUFLEN - bufpos; /* amount of space left in buffer */ ioptr = iobuffer[bcurrent] + bufpos; for (ii = 1; ii < ngroups; ii++) /* write all but the last group */ { /* copy bytes from user's buffer to the IO buffer */ nwrite = minvalue(gsize, nspace); memcpy(ioptr, cptr, nwrite); cptr += nwrite; /* increment buffer pointer */ if (nwrite < gsize) /* entire group did not fit */ { dirty[bcurrent] = TRUE; /* mark record as having been modified */ record++; ffldrc(fptr, record, IGNORE_EOF, status); /* load next record */ bcurrent = (fptr->Fptr)->curbuf; ioptr = iobuffer[bcurrent]; nwrite = gsize - nwrite; memcpy(ioptr, cptr, nwrite); cptr += nwrite; /* increment buffer pointer */ ioptr += (offset + nwrite); /* increment IO buffer pointer */ nspace = IOBUFLEN - offset - nwrite; /* amount of space left */ } else { ioptr += (offset + nwrite); /* increment IO bufer pointer */ nspace -= (offset + nwrite); } if (nspace <= 0) /* beyond current record? */ { dirty[bcurrent] = TRUE; record += ((IOBUFLEN - nspace) / IOBUFLEN); /* new record number */ ffldrc(fptr, record, IGNORE_EOF, status); bcurrent = (fptr->Fptr)->curbuf; bufpos = (-nspace) % IOBUFLEN; /* starting buffer pos */ nspace = IOBUFLEN - bufpos; ioptr = iobuffer[bcurrent] + bufpos; } } /* now write the last group */ nwrite = minvalue(gsize, nspace); memcpy(ioptr, cptr, nwrite); cptr += nwrite; /* increment buffer pointer */ if (nwrite < gsize) /* entire group did not fit */ { dirty[bcurrent] = TRUE; /* mark record as having been modified */ record++; ffldrc(fptr, record, IGNORE_EOF, status); /* load next record */ bcurrent = (fptr->Fptr)->curbuf; ioptr = iobuffer[bcurrent]; nwrite = gsize - nwrite; memcpy(ioptr, cptr, nwrite); } dirty[bcurrent] = TRUE; /* mark record as having been modified */ (fptr->Fptr)->bytepos = (fptr->Fptr)->bytepos + (ngroups * gsize) + (ngroups - 1) * offset; return(*status); } /*--------------------------------------------------------------------------*/ int ffgbyt(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG nbytes, /* I - number of bytes to read */ void *buffer, /* O - buffer to read into */ int *status) /* IO - error status */ /* get (read) the requested number of bytes from the file, starting at the current file position. Read large blocks of data directly from disk; read smaller segments via intermediate IO buffers to improve efficiency. */ { int ii; LONGLONG filepos; long recstart, recend, ntodo, bufpos, nspace, nread; char *cptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); cptr = (char *)buffer; if (nbytes >= MINDIRECT) { /* read large blocks of data directly from disk instead of via buffers */ filepos = (fptr->Fptr)->bytepos; /* save the read starting position */ /* note that in this case, ffmbyt has not been called, and so */ /* bufrecnum[(fptr->Fptr)->curbuf] does not point to the intended */ /* output buffer */ recstart = (long) (filepos / IOBUFLEN); /* starting record */ recend = (long) ((filepos + nbytes - 1) / IOBUFLEN); /* ending record */ for (ii = 0; ii < NIOBUF; ii++) /* flush any affected buffers to disk */ { if (dirty[ii] && bufptr[ii] == fptr->Fptr && bufrecnum[ii] >= recstart && bufrecnum[ii] <= recend) { ffbfwt(ii, status); /* flush modified buffer to disk */ } } /* move to the correct read position */ if ((fptr->Fptr)->io_pos != filepos) ffseek(fptr->Fptr, filepos); ffread(fptr->Fptr, (long) nbytes, cptr, status); /* read the data */ (fptr->Fptr)->io_pos = filepos + nbytes; /* update the file position */ } else { /* read small chucks of data using the IO buffers for efficiency */ if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */ { /* so reload the last one that was used */ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status); } /* bufpos is the starting position in IO buffer */ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)bufrecnum[(fptr->Fptr)->curbuf] * IOBUFLEN)); nspace = IOBUFLEN - bufpos; /* amount of space left in the buffer */ ntodo = (long) nbytes; while (ntodo) { nread = minvalue(ntodo, nspace); /* copy bytes from IO buffer to user's buffer */ memcpy(cptr, iobuffer[(fptr->Fptr)->curbuf] + bufpos, nread); ntodo -= nread; /* decrement remaining number of bytes */ cptr += nread; (fptr->Fptr)->bytepos += nread; /* increment file position pointer */ if (ntodo) /* load next record into a buffer */ { ffldrc(fptr, (long) ((fptr->Fptr)->bytepos / IOBUFLEN), REPORT_EOF, status); bufpos = 0; nspace = IOBUFLEN; } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgbytoff(fitsfile *fptr, /* I - FITS file pointer */ long gsize, /* I - size of each group of bytes */ long ngroups, /* I - number of groups to read */ long offset, /* I - size of gap between groups (may be < 0) */ void *buffer, /* I - buffer to be filled */ int *status) /* IO - error status */ /* get (read) the requested number of bytes from the file, starting at the current file position. This function combines ffmbyt and ffgbyt for increased efficiency. */ { int bcurrent; long ii, bufpos, nspace, nread, record; char *cptr, *ioptr; if (*status > 0) return(*status); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */ { /* so reload the last one that was used */ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status); } cptr = (char *)buffer; bcurrent = (fptr->Fptr)->curbuf; /* number of the current IO buffer */ record = bufrecnum[bcurrent]; /* zero-indexed record number */ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)record * IOBUFLEN)); /* start pos */ nspace = IOBUFLEN - bufpos; /* amount of space left in buffer */ ioptr = iobuffer[bcurrent] + bufpos; for (ii = 1; ii < ngroups; ii++) /* read all but the last group */ { /* copy bytes from IO buffer to the user's buffer */ nread = minvalue(gsize, nspace); memcpy(cptr, ioptr, nread); cptr += nread; /* increment buffer pointer */ if (nread < gsize) /* entire group did not fit */ { record++; ffldrc(fptr, record, REPORT_EOF, status); /* load next record */ bcurrent = (fptr->Fptr)->curbuf; ioptr = iobuffer[bcurrent]; nread = gsize - nread; memcpy(cptr, ioptr, nread); cptr += nread; /* increment buffer pointer */ ioptr += (offset + nread); /* increment IO buffer pointer */ nspace = IOBUFLEN - offset - nread; /* amount of space left */ } else { ioptr += (offset + nread); /* increment IO bufer pointer */ nspace -= (offset + nread); } if (nspace <= 0 || nspace > IOBUFLEN) /* beyond current record? */ { if (nspace <= 0) { record += ((IOBUFLEN - nspace) / IOBUFLEN); /* new record number */ bufpos = (-nspace) % IOBUFLEN; /* starting buffer pos */ } else { record -= ((nspace - 1 ) / IOBUFLEN); /* new record number */ bufpos = IOBUFLEN - (nspace % IOBUFLEN); /* starting buffer pos */ } ffldrc(fptr, record, REPORT_EOF, status); bcurrent = (fptr->Fptr)->curbuf; nspace = IOBUFLEN - bufpos; ioptr = iobuffer[bcurrent] + bufpos; } } /* now read the last group */ nread = minvalue(gsize, nspace); memcpy(cptr, ioptr, nread); cptr += nread; /* increment buffer pointer */ if (nread < gsize) /* entire group did not fit */ { record++; ffldrc(fptr, record, REPORT_EOF, status); /* load next record */ bcurrent = (fptr->Fptr)->curbuf; ioptr = iobuffer[bcurrent]; nread = gsize - nread; memcpy(cptr, ioptr, nread); } (fptr->Fptr)->bytepos = (fptr->Fptr)->bytepos + (ngroups * gsize) + (ngroups - 1) * offset; return(*status); } /*--------------------------------------------------------------------------*/ int ffldrc(fitsfile *fptr, /* I - FITS file pointer */ long record, /* I - record number to be loaded */ int err_mode, /* I - 1=ignore EOF, 0 = return EOF error */ int *status) /* IO - error status */ { /* low-level routine to load a specified record from a file into a physical buffer, if it is not already loaded. Reset all pointers to make this the new current record for that file. Update ages of all the physical buffers. */ int ibuff, nbuff; LONGLONG rstart; /* check if record is already loaded in one of the buffers */ /* search from youngest to oldest buffer for efficiency */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); for (ibuff = NIOBUF - 1; ibuff >= 0; ibuff--) { nbuff = ageindex[ibuff]; if (bufptr[nbuff] == fptr->Fptr && record == bufrecnum[nbuff]) goto updatebuf; /* use 'goto' for efficiency */ } /* record is not already loaded */ rstart = (LONGLONG)record * IOBUFLEN; if ( !err_mode && (rstart >= (fptr->Fptr)->logfilesize) ) /* EOF? */ return(*status = END_OF_FILE); if (ffwhbf(fptr, &nbuff) < 0) /* which buffer should we reuse? */ return(*status = TOO_MANY_FILES); if (dirty[nbuff]) ffbfwt(nbuff, status); /* write dirty buffer to disk */ if (rstart >= (fptr->Fptr)->filesize) /* EOF? */ { /* initialize an empty buffer with the correct fill value */ if ((fptr->Fptr)->hdutype == ASCII_TBL) memset(iobuffer[nbuff], 32, IOBUFLEN); /* blank fill */ else memset(iobuffer[nbuff], 0, IOBUFLEN); /* zero fill */ (fptr->Fptr)->logfilesize = maxvalue((fptr->Fptr)->logfilesize, rstart + IOBUFLEN); dirty[nbuff] = TRUE; /* mark record as having been modified */ } else /* not EOF, so read record from disk */ { if ((fptr->Fptr)->io_pos != rstart) ffseek(fptr->Fptr, rstart); ffread(fptr->Fptr, IOBUFLEN, iobuffer[nbuff], status); (fptr->Fptr)->io_pos = rstart + IOBUFLEN; /* set new IO position */ } bufptr[nbuff] = fptr->Fptr; /* file pointer for this buffer */ bufrecnum[nbuff] = record; /* record number contained in buffer */ updatebuf: (fptr->Fptr)->curbuf = nbuff; /* this is the current buffer for this file */ if (ibuff < 0) { /* find the current position of the buffer in the age index */ for (ibuff = 0; ibuff < NIOBUF; ibuff++) if (ageindex[ibuff] == nbuff) break; } /* increment the age of all the buffers that were younger than it */ for (ibuff++; ibuff < NIOBUF; ibuff++) ageindex[ibuff - 1] = ageindex[ibuff]; ageindex[NIOBUF - 1] = nbuff; /* this is now the youngest buffer */ return(*status); } /*--------------------------------------------------------------------------*/ int ffwhbf(fitsfile *fptr, /* I - FITS file pointer */ int *nbuff) /* O - which buffer to use */ { /* decide which buffer to (re)use to hold a new file record */ int ii, ibuff; static int ageinit = 0; if (!ageinit) /* first time thru, initialize default age of buffers */ { for (ii = 0; ii < NIOBUF; ii++) ageindex[ii] = ii; ageinit = 1; } for (ii = 0; ii < NIOBUF; ii++) { ibuff = ageindex[ii]; /* search from the oldest to youngest buffer */ if (bufptr[ibuff] == NULL || /* if buffer is empty, or */ bufptr[ibuff]->curbuf != ibuff) /* is not the current buffer */ return(*nbuff = ibuff); /* then choose this buffer */ } /* all the buffers are locked, so we have to reuse the current one */ /* If there is no current buffer (e.g., file has just been opened) */ /* then use the oldest buffer. */ if ((fptr->Fptr)->curbuf < 0) { bufptr[ageindex[0]]->curbuf = -1; /* this buffer no longer contains */ /* the current buffer of another file */ return(*nbuff = ageindex[0]); /* return oldest buffer */ } else { return(*nbuff = (fptr->Fptr)->curbuf); /* return current buffer */ } } /*--------------------------------------------------------------------------*/ int ffflus(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Flush all the data in the current FITS file to disk. This ensures that if the program subsequently dies, the disk FITS file will be closed correctly. */ { int hdunum, hdutype; if (*status > 0) return(*status); ffghdn(fptr, &hdunum); /* get the current HDU number */ if (ffchdu(fptr,status) > 0) /* close out the current HDU */ ffpmsg("ffflus could not close the current HDU."); ffflsh(fptr, FALSE, status); /* flush any modified IO buffers to disk */ if (ffgext(fptr, hdunum - 1, &hdutype, status) > 0) /* reopen HDU */ ffpmsg("ffflus could not reopen the current HDU."); return(*status); } /*--------------------------------------------------------------------------*/ int ffflsh(fitsfile *fptr, /* I - FITS file pointer */ int clearbuf, /* I - also clear buffer contents? */ int *status) /* IO - error status */ { /* flush all dirty IO buffers associated with the file to disk */ int ii; /* no need to move to a different HDU if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); */ for (ii = 0; ii < NIOBUF; ii++) { if (bufptr[ii] == fptr->Fptr) { if (dirty[ii]) /* flush modified buffer to disk */ ffbfwt(ii, status); if (clearbuf) bufptr[ii] = NULL; /* set contents of buffer as undefined */ } } if (*status != READONLY_FILE) ffflushx(fptr->Fptr); /* flush system buffers to disk */ return(*status); } /*--------------------------------------------------------------------------*/ int ffbfeof(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ { /* clear any buffers beyond the end of file */ int ii; for (ii = 0; ii < NIOBUF; ii++) { if (bufptr[ii] == fptr->Fptr) { if ( (LONGLONG) bufrecnum[ii] * IOBUFLEN >= fptr->Fptr->filesize) { bufptr[ii] = NULL; /* set contents of buffer as undefined */ } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffbfwt(int nbuff, /* I - which buffer to write */ int *status) /* IO - error status */ { /* write contents of buffer to file; If the position of the buffer is beyond the current EOF, then the file may need to be extended with fill values, and/or with the contents of some of the other i/o buffers. */ FITSfile *Fptr; int ii,ibuff; long jj, irec, minrec, nloop; LONGLONG filepos; static char zeros[IOBUFLEN]; /* initialized to zero by default */ Fptr = bufptr[nbuff]; if (!(Fptr->writemode) ) { ffpmsg("Error: trying to write to READONLY file."); dirty[nbuff] = FALSE; /* reset buffer status to prevent later probs */ *status = READONLY_FILE; return(*status); } filepos = (LONGLONG)bufrecnum[nbuff] * IOBUFLEN; if (filepos <= Fptr->filesize) { /* record is located within current file, so just write it */ /* move to the correct write position */ if (Fptr->io_pos != filepos) ffseek(Fptr, filepos); ffwrite(Fptr, IOBUFLEN, iobuffer[nbuff], status); Fptr->io_pos = filepos + IOBUFLEN; if (filepos == Fptr->filesize) /* appended new record? */ Fptr->filesize += IOBUFLEN; /* increment the file size */ dirty[nbuff] = FALSE; } else /* if record is beyond the EOF, append any other records */ /* and/or insert fill values if necessary */ { /* move to EOF */ if (Fptr->io_pos != Fptr->filesize) ffseek(Fptr, Fptr->filesize); ibuff = NIOBUF; /* initialize to impossible value */ while(ibuff != nbuff) /* repeat until requested buffer is written */ { minrec = (long) (Fptr->filesize / IOBUFLEN); /* write lowest record beyond the EOF first */ irec = bufrecnum[nbuff]; /* initially point to the requested buffer */ ibuff = nbuff; for (ii = 0; ii < NIOBUF; ii++) { if (bufptr[ii] == Fptr && bufrecnum[ii] >= minrec && bufrecnum[ii] < irec) { irec = bufrecnum[ii]; /* found a lower record */ ibuff = ii; } } filepos = (LONGLONG)irec * IOBUFLEN; /* byte offset of record in file */ /* append 1 or more fill records if necessary */ if (filepos > Fptr->filesize) { nloop = (long) ((filepos - (Fptr->filesize)) / IOBUFLEN); for (jj = 0; jj < nloop && !(*status); jj++) ffwrite(Fptr, IOBUFLEN, zeros, status); /* ffseek(Fptr, filepos); */ Fptr->filesize = filepos; /* increment the file size */ } /* write the buffer itself */ ffwrite(Fptr, IOBUFLEN, iobuffer[ibuff], status); dirty[ibuff] = FALSE; Fptr->filesize += IOBUFLEN; /* increment the file size */ } /* loop back if more buffers need to be written */ Fptr->io_pos = Fptr->filesize; /* currently positioned at EOF */ } return(*status); } /*--------------------------------------------------------------------------*/ int ffgrsz( fitsfile *fptr, /* I - FITS file pionter */ long *ndata, /* O - optimal amount of data to access */ int *status) /* IO - error status */ /* Returns an optimal value for the number of rows in a binary table or the number of pixels in an image that should be read or written at one time for maximum efficiency. Accessing more data than this may cause excessive flushing and rereading of buffers to/from disk. */ { int nfiles, typecode, bytesperpixel; long repeat, width; /* There are NIOBUF internal buffers available each IOBUFLEN bytes long. */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) if ( ffrdef(fptr, status) > 0) /* rescan header to get hdu struct */ return(*status); /* determine how many different FITS files are currently open */ nfiles = fits_get_num_files(); /* one buffer (at least) is always allocated to each open file */ if ((fptr->Fptr)->hdutype == IMAGE_HDU ) /* calc pixels per buffer size */ { /* image pixels are in column 2 of the 'table' */ ffgtcl(fptr, 2, &typecode, &repeat, &width, status); bytesperpixel = typecode / 10; *ndata = ((NIOBUF - nfiles) * IOBUFLEN) / bytesperpixel; } else /* calc number of rows that fit in buffers */ { *ndata = (long) (((NIOBUF - nfiles) * IOBUFLEN) / maxvalue(1, (fptr->Fptr)->rowlength)); *ndata = maxvalue(1, *ndata); } return(*status); } /*--------------------------------------------------------------------------*/ int fits_get_num_files(void) /* Returns the number of FITS files currently opened in CFITSIO */ { int ii, jj, unique, nfiles; /* determine how many different FITS files are currently open */ nfiles = 0; for (ii = 0; ii < NIOBUF; ii++) { if (bufptr[ii]) { unique = TRUE; for (jj = 0; jj < ii; jj++) { if (bufptr[ii] == bufptr[jj]) { unique = FALSE; break; } } if (unique) nfiles++; } } return(nfiles); } /*--------------------------------------------------------------------------*/ int ffgtbb(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstrow, /* I - starting row (1 = first row) */ LONGLONG firstchar, /* I - starting byte in row (1=first) */ LONGLONG nchars, /* I - number of bytes to read */ unsigned char *values, /* I - array of bytes to read */ int *status) /* IO - error status */ /* read a consecutive string of bytes from an ascii or binary table. This will span multiple rows of the table if nchars + firstchar is greater than the length of a row. */ { LONGLONG bytepos, endrow; if (*status > 0 || nchars <= 0) return(*status); else if (firstrow < 1) return(*status=BAD_ROW_NUM); else if (firstchar < 1) return(*status=BAD_ELEM_NUM); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); /* check that we do not exceed number of rows in the table */ endrow = ((firstchar + nchars - 2) / (fptr->Fptr)->rowlength) + firstrow; if (endrow > (fptr->Fptr)->numrows) { ffpmsg("attempt to read past end of table (ffgtbb)"); return(*status=BAD_ROW_NUM); } /* move the i/o pointer to the start of the sequence of characters */ bytepos = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * (firstrow - 1)) + firstchar - 1; ffmbyt(fptr, bytepos, REPORT_EOF, status); ffgbyt(fptr, nchars, values, status); /* read the bytes */ return(*status); } /*--------------------------------------------------------------------------*/ int ffgi1b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ unsigned char *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; if (incre == 1) /* read all the values at once (contiguous bytes) */ { if (nvals < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 1, nvals, incre - 1, values, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffgi2b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ short *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; if (incre == 2) /* read all the values at once (contiguous bytes) */ { if (nvals * 2 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 2, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 2, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 2, nvals, incre - 2, values, status); } #if BYTESWAPPED ffswap2(values, nvals); /* reverse order of bytes in each value */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffgi4b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ INT32BIT *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; if (incre == 4) /* read all the values at once (contiguous bytes) */ { if (nvals * 4 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 4, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 4, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 4, nvals, incre - 4, values, status); } #if BYTESWAPPED ffswap4(values, nvals); /* reverse order of bytes in each value */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffgi8b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ long *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! This routine reads 'nvals' 8-byte integers into 'values'. This works both on platforms that have sizeof(long) = 64, and 32, as long as 'values' has been allocated to large enough to hold 8 * nvals bytes of data. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ { LONGLONG postemp; if (incre == 8) /* read all the values at once (contiguous bytes) */ { if (nvals * 8 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 8, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 8, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 8, nvals, incre - 8, values, status); } #if BYTESWAPPED ffswap8((double *) values, nvals); /* reverse bytes in each value */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffgr4b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ float *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; #if MACHINE == VAXVMS long ii; #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) short *sptr; long ii; #endif if (incre == 4) /* read all the values at once (contiguous bytes) */ { if (nvals * 4 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 4, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 4, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 4, nvals, incre - 4, values, status); } #if MACHINE == VAXVMS ii = nvals; /* call VAX macro routine to convert */ ieevur(values, values, &ii); /* from IEEE float -> F float */ #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) ffswap2( (short *) values, nvals * 2); /* swap pairs of bytes */ /* convert from IEEE float format to VMS GFLOAT float format */ sptr = (short *) values; for (ii = 0; ii < nvals; ii++, sptr += 2) { if (!fnan(*sptr) ) /* test for NaN or underflow */ values[ii] *= 4.0; } #elif BYTESWAPPED ffswap4((INT32BIT *)values, nvals); /* reverse order of bytes in values */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffgr8b(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG byteloc, /* I - position within file to start reading */ long nvals, /* I - number of pixels to read */ long incre, /* I - byte increment between pixels */ double *values, /* O - returned array of values */ int *status) /* IO - error status */ /* get (read) the array of values from the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { LONGLONG postemp; #if MACHINE == VAXVMS long ii; #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) short *sptr; long ii; #endif if (incre == 8) /* read all the values at once (contiguous bytes) */ { if (nvals * 8 < MINDIRECT) /* read normally via IO buffers */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbyt(fptr, nvals * 8, values, status); } else /* read directly from disk, bypassing IO buffers */ { postemp = (fptr->Fptr)->bytepos; /* store current file position */ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */ ffgbyt(fptr, nvals * 8, values, status); (fptr->Fptr)->bytepos = postemp; /* reset to original position */ } } else /* have to read each value individually (not contiguous ) */ { ffmbyt(fptr, byteloc, REPORT_EOF, status); ffgbytoff(fptr, 8, nvals, incre - 8, values, status); } #if MACHINE == VAXVMS ii = nvals; /* call VAX macro routine to convert */ ieevud(values, values, &ii); /* from IEEE float -> D float */ #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) ffswap2( (short *) values, nvals * 4); /* swap pairs of bytes */ /* convert from IEEE float format to VMS GFLOAT float format */ sptr = (short *) values; for (ii = 0; ii < nvals; ii++, sptr += 4) { if (!dnan(*sptr) ) /* test for NaN or underflow */ values[ii] *= 4.0; } #elif BYTESWAPPED ffswap8(values, nvals); /* reverse order of bytes in each value */ #endif return(*status); } /*--------------------------------------------------------------------------*/ int ffptbb(fitsfile *fptr, /* I - FITS file pointer */ LONGLONG firstrow, /* I - starting row (1 = first row) */ LONGLONG firstchar, /* I - starting byte in row (1=first) */ LONGLONG nchars, /* I - number of bytes to write */ unsigned char *values, /* I - array of bytes to write */ int *status) /* IO - error status */ /* write a consecutive string of bytes to an ascii or binary table. This will span multiple rows of the table if nchars + firstchar is greater than the length of a row. */ { LONGLONG bytepos, endrow, nrows; char message[81]; if (*status > 0 || nchars <= 0) return(*status); else if (firstrow < 1) return(*status=BAD_ROW_NUM); else if (firstchar < 1) return(*status=BAD_ELEM_NUM); if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); else if ((fptr->Fptr)->datastart < 0) /* rescan header if data undefined */ ffrdef(fptr, status); endrow = ((firstchar + nchars - 2) / (fptr->Fptr)->rowlength) + firstrow; /* check if we are writing beyond the current end of table */ if (endrow > (fptr->Fptr)->numrows) { /* if there are more HDUs following the current one, or */ /* if there is a data heap, then we must insert space */ /* for the new rows. */ if ( !((fptr->Fptr)->lasthdu) || (fptr->Fptr)->heapsize > 0) { nrows = endrow - ((fptr->Fptr)->numrows); /* ffirow also updates the heap address and numrows */ if (ffirow(fptr, (fptr->Fptr)->numrows, nrows, status) > 0) { sprintf(message, "ffptbb failed to add space for %.0f new rows in table.", (double) nrows); ffpmsg(message); return(*status); } } else { /* manally update heap starting address */ (fptr->Fptr)->heapstart += ((LONGLONG)(endrow - (fptr->Fptr)->numrows) * (fptr->Fptr)->rowlength ); (fptr->Fptr)->numrows = endrow; /* update number of rows */ } } /* move the i/o pointer to the start of the sequence of characters */ bytepos = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * (firstrow - 1)) + firstchar - 1; ffmbyt(fptr, bytepos, IGNORE_EOF, status); ffpbyt(fptr, nchars, values, status); /* write the bytes */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpi1b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ unsigned char *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { if (incre == 1) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 1, nvals, incre - 1, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpi2b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ short *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { #if BYTESWAPPED ffswap2(values, nvals); /* reverse order of bytes in each value */ #endif if (incre == 2) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 2, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 2, nvals, incre - 2, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpi4b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ INT32BIT *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { #if BYTESWAPPED ffswap4(values, nvals); /* reverse order of bytes in each value */ #endif if (incre == 4) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 4, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 4, nvals, incre - 4, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpi8b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ long *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! This routine writes 'nvals' 8-byte integers from 'values'. This works both on platforms that have sizeof(long) = 64, and 32, as long as 'values' has been allocated to large enough to hold 8 * nvals bytes of data. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ { #if BYTESWAPPED ffswap8((double *) values, nvals); /* reverse bytes in each value */ #endif if (incre == 8) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 8, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 8, nvals, incre - 8, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpr4b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ float *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { #if MACHINE == VAXVMS long ii; ii = nvals; /* call VAX macro routine to convert */ ieevpr(values, values, &ii); /* from F float -> IEEE float */ #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) long ii; /* convert from VMS FFLOAT float format to IEEE float format */ for (ii = 0; ii < nvals; ii++) values[ii] *= 0.25; ffswap2( (short *) values, nvals * 2); /* swap pairs of bytes */ #elif BYTESWAPPED ffswap4((INT32BIT *) values, nvals); /* reverse order of bytes in values */ #endif if (incre == 4) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 4, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 4, nvals, incre - 4, values, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpr8b(fitsfile *fptr, /* I - FITS file pointer */ long nvals, /* I - number of pixels in the values array */ long incre, /* I - byte increment between pixels */ double *values, /* I - array of values to write */ int *status) /* IO - error status */ /* put (write) the array of values to the FITS file, doing machine dependent format conversion (e.g. byte-swapping) if necessary. */ { #if MACHINE == VAXVMS long ii; ii = nvals; /* call VAX macro routine to convert */ ieevpd(values, values, &ii); /* from D float -> IEEE float */ #elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT) long ii; /* convert from VMS GFLOAT float format to IEEE float format */ for (ii = 0; ii < nvals; ii++) values[ii] *= 0.25; ffswap2( (short *) values, nvals * 4); /* swap pairs of bytes */ #elif BYTESWAPPED ffswap8(values, nvals); /* reverse order of bytes in each value */ #endif if (incre == 8) /* write all the values at once (contiguous bytes) */ ffpbyt(fptr, nvals * 8, values, status); else /* have to write each value individually (not contiguous ) */ ffpbytoff(fptr, 8, nvals, incre - 8, values, status); return(*status); } indi-0.5/src/cfitsio/getcolui.c0000644000175000017500000021667010610474375014342 0ustar jrjr/* This file, getcolui.c, contains routines that read data elements from */ /* a FITS image or table, with unsigned short datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvui( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned short nulval, /* I - value for undefined pixels */ unsigned short *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; unsigned short nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TUSHORT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclui(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfui( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned short *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TUSHORT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclui(fptr, 2, row, firstelem, nelem, 1, 2, 0, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned short nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ unsigned short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dui(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dui(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ unsigned short nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ unsigned short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; unsigned short nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TUSHORT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclui(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclui(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned short nulval, /* I - value to set undefined pixels */ unsigned short *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; unsigned short nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvui is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TUSHORT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvui: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclui(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ unsigned short *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; int hdutype, anyf; unsigned short nulval = 0; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvi is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TUSHORT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvi: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclui(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpui( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ unsigned short *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclui(fptr, 1, row, firstelem, nelem, 1, 1, 0, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned short nulval, /* I - value for null pixels */ unsigned short *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfui(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ unsigned short *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { unsigned short dummy = 0; ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclui( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ unsigned short nulval, /* I - value for null pixels if nultyp = 1 */ unsigned short *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power = 1., dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int nulcheck; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ if (tcode == TSHORT) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) &array[next], status); fffi2u2((short *) &array[next], ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8u2( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1u2((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer, status); fffi4u2((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4u2((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8u2((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstru2((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgclui).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgclui).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int fffi1u2(unsigned char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (unsigned short) input[ii]; /* copy input */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2u2(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 32768.) { /* Instead of adding 32768, it is more efficient */ /* to just flip the sign bit with the XOR operator */ for (ii = 0; ii < ntodo; ii++) output[ii] = ( *(unsigned short *) &input[ii] ) ^ 0x8000; } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned short) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 32768.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = ( *(unsigned short *) &input[ii] ) ^ 0x8000; } } else if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else output[ii] = (unsigned short) input[ii]; /* copy input */ } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4u2(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8u2(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > USHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4u2(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8u2(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (zero > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstru2(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ unsigned short nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ unsigned short *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DUSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = USHRT_MAX; } else output[ii] = (unsigned short) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } indi-0.5/src/cfitsio/getcolk.c0000644000175000017500000021570410610474375014154 0ustar jrjr/* This file, getcolk.c, contains routines that read data elements from */ /* a FITS image or table, with 'int' data type. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffgpvk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int nulval, /* I - value for undefined pixels */ int *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; char cdummy; int nullcheck = 1; int nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_read_compressed_pixels(fptr, TINT, firstelem, nelem, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclk(fptr, 2, row, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgpfk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int *array, /* O - array of values that are returned */ char *nularray, /* O - array of null pixel flags */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any undefined pixels in the returned array will be set = 0 and the corresponding nularray value will be set = 1. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { long row; int nullcheck = 2; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_read_compressed_pixels(fptr, TINT, firstelem, nelem, nullcheck, NULL, array, nularray, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclk(fptr, 2, row, firstelem, nelem, 1, 2, 0L, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg2dk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ int nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { /* call the 3D reading routine, with the 3rd dimension = 1 */ ffg3dk(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffg3dk(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ int nulval, /* set undefined pixels equal to this */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an entire 3-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Any null values in the array will be set equal to the value of nulval, unless nulval = 0 in which case no null checking will be performed. */ { long tablerow, ii, jj; char cdummy; int nullcheck = 1; long inc[] = {1,1,1}; LONGLONG fpixel[] = {1,1,1}, nfits, narray; LONGLONG lpixel[3]; int nullvalue; if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = ncols; lpixel[1] = nrows; lpixel[2] = naxis3; nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TINT, fpixel, lpixel, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so read all at once */ ffgclk(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to read */ narray = 0; /* next pixel in output array to be filled */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* reading naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffgclk(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval, &array[narray], &cdummy, anynul, status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsvk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ int nulval, /* I - value to set undefined pixels */ int *array, /* O - array to be filled and returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dir[9]; long nelem, nultyp, ninc, numcol; LONGLONG felem, dsize[10], blcll[9], trcll[9]; int hdutype, anyf; char ldummy, msg[FLEN_ERRMSG]; int nullcheck = 1; int nullvalue; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } nullvalue = nulval; /* set local variable */ fits_read_compressed_img(fptr, TINT, blcll, trcll, inc, nullcheck, &nullvalue, array, NULL, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 1; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; dir[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { if (hdutype == IMAGE_HDU) { dir[ii] = -1; } else { sprintf(msg, "ffgsvk: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; dsize[ii] = dsize[ii] * dir[ii]; } dsize[naxis] = dsize[naxis] * dir[naxis]; if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0]*dir[0] - str[0]*dir[0]) / inc[0] + 1; ninc = incr[0] * dir[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]*dir[8]; i8 <= stp[8]*dir[8]; i8 += incr[8]) { for (i7 = str[7]*dir[7]; i7 <= stp[7]*dir[7]; i7 += incr[7]) { for (i6 = str[6]*dir[6]; i6 <= stp[6]*dir[6]; i6 += incr[6]) { for (i5 = str[5]*dir[5]; i5 <= stp[5]*dir[5]; i5 += incr[5]) { for (i4 = str[4]*dir[4]; i4 <= stp[4]*dir[4]; i4 += incr[4]) { for (i3 = str[3]*dir[3]; i3 <= stp[3]*dir[3]; i3 += incr[3]) { for (i2 = str[2]*dir[2]; i2 <= stp[2]*dir[2]; i2 += incr[2]) { for (i1 = str[1]*dir[1]; i1 <= stp[1]*dir[1]; i1 += incr[1]) { felem=str[0] + (i1 - dir[1]) * dsize[1] + (i2 - dir[2]) * dsize[2] + (i3 - dir[3]) * dsize[3] + (i4 - dir[4]) * dsize[4] + (i5 - dir[5]) * dsize[5] + (i6 - dir[6]) * dsize[6] + (i7 - dir[7]) * dsize[7] + (i8 - dir[8]) * dsize[8]; if ( ffgclk(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &ldummy, &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffgsfk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of the column to read (1 = 1st) */ int naxis, /* I - number of dimensions in the FITS array */ long *naxes, /* I - size of each dimension */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc, /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dimension */ int *array, /* O - array to be filled and returned */ char *flagval, /* O - set to 1 if corresponding value is null */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read a subsection of data values from an image or a table column. This routine is set up to handle a maximum of nine dimensions. */ { long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc; long str[9],stp[9],incr[9],dsize[10]; LONGLONG blcll[9], trcll[9]; long felem, nelem, nultyp, ninc, numcol; long nulval = 0; int hdutype, anyf; char msg[FLEN_ERRMSG]; int nullcheck = 2; if (naxis < 1 || naxis > 9) { sprintf(msg, "NAXIS = %d in call to ffgsvj is out of range", naxis); ffpmsg(msg); return(*status = BAD_DIMEN); } if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ for (ii=0; ii < naxis; ii++) { blcll[ii] = blc[ii]; trcll[ii] = trc[ii]; } fits_read_compressed_img(fptr, TINT, blcll, trcll, inc, nullcheck, NULL, array, flagval, anynul, status); return(*status); } /* if this is a primary array, then the input COLNUM parameter should be interpreted as the row number, and we will alway read the image data from column 2 (any group parameters are in column 1). */ if (ffghdt(fptr, &hdutype, status) > 0) return(*status); if (hdutype == IMAGE_HDU) { /* this is a primary array, or image extension */ if (colnum == 0) { rstr = 1; rstp = 1; } else { rstr = colnum; rstp = colnum; } rinc = 1; numcol = 2; } else { /* this is a table, so the row info is in the (naxis+1) elements */ rstr = blc[naxis]; rstp = trc[naxis]; rinc = inc[naxis]; numcol = colnum; } nultyp = 2; if (anynul) *anynul = FALSE; i0 = 0; for (ii = 0; ii < 9; ii++) { str[ii] = 1; stp[ii] = 1; incr[ii] = 1; dsize[ii] = 1; } for (ii = 0; ii < naxis; ii++) { if (trc[ii] < blc[ii]) { sprintf(msg, "ffgsvj: illegal range specified for axis %ld", ii + 1); ffpmsg(msg); return(*status = BAD_PIX_NUM); } str[ii] = blc[ii]; stp[ii] = trc[ii]; incr[ii] = inc[ii]; dsize[ii + 1] = dsize[ii] * naxes[ii]; } if (naxis == 1 && naxes[0] == 1) { /* This is not a vector column, so read all the rows at once */ nelem = (rstp - rstr) / rinc + 1; ninc = rinc; rstp = rstr; } else { /* have to read each row individually, in all dimensions */ nelem = (stp[0] - str[0]) / inc[0] + 1; ninc = incr[0]; } for (row = rstr; row <= rstp; row += rinc) { for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8]) { for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7]) { for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6]) { for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5]) { for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4]) { for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3]) { for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2]) { for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1]) { felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] + (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] + (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8]; if ( ffgclk(fptr, numcol, row, felem, nelem, ninc, nultyp, nulval, &array[i0], &flagval[i0], &anyf, status) > 0) return(*status); if (anyf && anynul) *anynul = TRUE; i0 += nelem; } } } } } } } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffggpk( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to read (1 = 1st group) */ long firstelem, /* I - first vector element to read (1 = 1st) */ long nelem, /* I - number of values to read */ int *array, /* O - array of values that are returned */ int *status) /* IO - error status */ /* Read an array of group parameters from the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). */ { long row; int idummy; char cdummy; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffgclk(fptr, 1, row, firstelem, nelem, 1, 1, 0L, array, &cdummy, &idummy, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcvk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int nulval, /* I - value for null pixels */ int *array, /* O - array of values that are read */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Any undefined pixels will be set equal to the value of 'nulval' unless nulval = 0 in which case no checks for undefined pixels will be made. */ { char cdummy; ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval, array, &cdummy, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgcfk(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ int *array, /* O - array of values that are read */ char *nularray, /* O - array of flags: 1 if null pixel; else 0 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. Automatic datatype conversion will be performed if the datatype of the column does not match the datatype of the array parameter. The output values will be scaled by the FITS TSCALn and TZEROn values if these values have been defined. Nularray will be set = 1 if the corresponding array pixel is undefined, otherwise nularray will = 0. */ { int dummy = 0; ffgclk(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy, array, nularray, anynul, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffgclk( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to read (1 = 1st col) */ LONGLONG firstrow, /* I - first row to read (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to read (1 = 1st) */ LONGLONG nelem, /* I - number of values to read */ long elemincre, /* I - pixel increment; e.g., 2 = every other */ int nultyp, /* I - null value handling code: */ /* 1: set undefined pixels = nulval */ /* 2: set nularray=1 for undefined pixels */ int nulval, /* I - value for null pixels if nultyp = 1 */ int *array, /* O - array of values that are read */ char *nularray, /* O - array of flags = 1 if nultyp = 2 */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an array of values from a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer be a virtual column in a 1 or more grouped FITS primary array or image extension. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The output array of values will be converted from the datatype of the column and will be scaled by the FITS TSCALn and TZEROn values if necessary. */ { double scale, zero, power, dtemp; int tcode, maxelem, hdutype, xcode, decimals; long twidth, incre; long ii, xwidth, ntodo; int convert, nulcheck, readcheck = 0; LONGLONG repeat, startpos, elemnum, readptr, tnull; LONGLONG rowlen, rownum, remain, next, rowincre; char tform[20]; char message[81]; char snull[20]; /* the FITS null value if reading from ASCII table */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0 || nelem == 0) /* inherit input status value if > 0 */ return(*status); /* call the 'short' or 'long' version of this routine, if possible */ if (sizeof(int) == sizeof(short)) ffgcli(fptr, colnum, firstrow, firstelem, nelem, elemincre, nultyp, (short) nulval, (short *) array, nularray, anynul, status); else if (sizeof(int) == sizeof(long)) ffgclj(fptr, colnum, firstrow, firstelem, nelem, elemincre, nultyp, (long) nulval, (long *) array, nularray, anynul, status); else { /* This is a special case: sizeof(int) is not equal to sizeof(short) or sizeof(long). This occurs on Alpha OSF systems where short = 2 bytes, int = 4 bytes, and long = 8 bytes. */ buffer = cbuff; power = 1.; if (anynul) *anynul = 0; if (nultyp == 2) memset(nularray, 0, (size_t) nelem); /* initialize nullarray */ /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (elemincre < 0) readcheck = -1; /* don't do range checking in this case */ if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, readcheck, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 ) return(*status); incre *= elemincre; /* multiply incre to just get every nth pixel */ if (tcode == TSTRING) /* setup for ASCII tables */ { /* get the number of implied decimal places if no explicit decmal point */ ffasfm(tform, &xcode, &xwidth, &decimals, status); for(ii = 0; ii < decimals; ii++) power *= 10.; } /*------------------------------------------------------------------*/ /* Decide whether to check for null values in the input FITS file: */ /*------------------------------------------------------------------*/ nulcheck = nultyp; /* by default check for null values in the FITS file */ if (nultyp == 1 && nulval == 0) nulcheck = 0; /* calling routine does not want to check for nulls */ else if (tcode%10 == 1 && /* if reading an integer column, and */ tnull == NULL_UNDEFINED) /* if a null value is not defined, */ nulcheck = 0; /* then do not check for null values. */ else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TBYTE && (tnull > 255 || tnull < 0) ) nulcheck = 0; /* Impossible null value */ else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED) nulcheck = 0; /*----------------------------------------------------------------------*/ /* If FITS column and output data array have same datatype, then we do */ /* not need to use a temporary buffer to store intermediate datatype. */ /*----------------------------------------------------------------------*/ convert = 1; if (tcode == TLONG) /* Special Case: */ { /* no type convertion required, so read */ maxelem = (int) nelem; /* data directly into output buffer. */ if (nulcheck == 0 && scale == 1. && zero == 0.) convert = 0; /* no need to scale data or find nulls */ } /*---------------------------------------------------------------------*/ /* Now read the pixels from the FITS column. If the column does not */ /* have the same datatype as the output array, then we have to read */ /* the raw values into a temporary buffer (of limited size). In */ /* the case of a vector colum read only 1 vector of values at a time */ /* then skip to the next row if more values need to be read. */ /* After reading the raw values, then call the fffXXYY routine to (1) */ /* test for undefined values, (2) convert the datatype if necessary, */ /* and (3) scale the values by the FITS TSCALn and TZEROn linear */ /* scaling parameters. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to read */ next = 0; /* next element in array to be read */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to read at one time to the number that will fit in the buffer or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); if (elemincre >= 0) { ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1)); } else { ntodo = (long) minvalue(ntodo, (elemnum/(-elemincre) +1)); } readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre)); switch (tcode) { case (TLONG): ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) &array[next], status); if (convert) fffi4int((INT32BIT *) &array[next], ntodo, scale, zero, nulcheck, (INT32BIT) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TLONGLONG): ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status); fffi8int( (LONGLONG *) buffer, ntodo, scale, zero, nulcheck, tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TBYTE): ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer, status); fffi1int((unsigned char *) buffer, ntodo, scale, zero, nulcheck, (unsigned char) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TSHORT): ffgi2b(fptr, readptr, ntodo, incre, (short *) buffer, status); fffi2int((short *) buffer, ntodo, scale, zero, nulcheck, (short) tnull, nulval, &nularray[next], anynul, &array[next], status); break; case (TFLOAT): ffgr4b(fptr, readptr, ntodo, incre, (float *) buffer, status); fffr4int((float *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TDOUBLE): ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status); fffr8int((double *) buffer, ntodo, scale, zero, nulcheck, nulval, &nularray[next], anynul, &array[next], status); break; case (TSTRING): ffmbyt(fptr, readptr, REPORT_EOF, status); if (incre == twidth) /* contiguous bytes */ ffgbyt(fptr, ntodo * twidth, buffer, status); else ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); fffstrint((char *) buffer, ntodo, scale, zero, twidth, power, nulcheck, snull, nulval, &nularray[next], anynul, &array[next], status); break; default: /* error trap for invalid column format */ sprintf(message, "Cannot read numbers from column %d which has format %s", colnum, tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous read operation */ { dtemp = (double) next; if (hdutype > 0) sprintf(message, "Error reading elements %.0f thru %.0f from column %d (ffgclk).", dtemp+1., dtemp+ntodo, colnum); else sprintf(message, "Error reading elements %.0f thru %.0f from image (ffgclk).", dtemp+1., dtemp+ntodo); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum = elemnum + (ntodo * elemincre); if (elemnum >= repeat) /* completed a row; start on later row */ { rowincre = elemnum / repeat; rownum += rowincre; elemnum = elemnum - (rowincre * repeat); } else if (elemnum < 0) /* completed a row; start on a previous row */ { rowincre = (-elemnum - 1) / repeat + 1; rownum -= rowincre; elemnum = (rowincre * repeat) + elemnum; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while reading FITS data."); *status = NUM_OVERFLOW; } } /* end of DEC Alpha special case */ return(*status); } /*--------------------------------------------------------------------------*/ int fffi1int(unsigned char *input,/* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ unsigned char tnull, /* I - value of FITS TNULLn keyword if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (int) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi2int(short *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ short tnull, /* I - value of FITS TNULLn keyword if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (int) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi4int(INT32BIT *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ INT32BIT tnull, /* I - value of FITS TNULLn keyword if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) output[ii] = (int) input[ii]; /* copy input to output */ } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffi8int(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ LONGLONG tnull, /* I - value of FITS TNULLn keyword if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to tnull. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < INT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > INT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { if (input[ii] < INT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > INT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] == tnull) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr4int(float *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr++; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 2) { if (0 != (iret = fnan(*sptr) ) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (zero > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffr8int(double *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do datatype conversion and scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to NaN. If nullcheck = 0, then no checking for nulls is performed and any null values will be transformed just like any other pixel. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { long ii; double dvalue; short *sptr, iret; if (nullcheck == 0) /* no null checking required */ { if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++) { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } else /* must check for null values */ { sptr = (short *) input; #if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS sptr += 3; /* point to MSBs */ #endif if (scale == 1. && zero == 0.) /* no scaling */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ output[ii] = 0; } else { if (input[ii] < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (input[ii] > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) input[ii]; } } } else /* must scale the data */ { for (ii = 0; ii < ntodo; ii++, sptr += 4) { if (0 != (iret = dnan(*sptr)) ) /* test for NaN or underflow */ { if (iret == 1) /* is it a NaN? */ { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } else /* it's an underflow */ { if (zero < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (zero > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) zero; } } else { dvalue = input[ii] * scale + zero; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (int) dvalue; } } } } return(*status); } /*--------------------------------------------------------------------------*/ int fffstrint(char *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ long twidth, /* I - width of each substring of chars */ double implipower, /* I - power of 10 of implied decimal */ int nullcheck, /* I - null checking code; 0 = don't check */ /* 1:set null pixels = nullval */ /* 2: if null pixel, set nullarray = 1 */ char *snull, /* I - value of FITS null string, if any */ int nullval, /* I - set null pixels, if nullcheck = 1 */ char *nullarray, /* I - bad pixel array, if nullcheck = 2 */ int *anynull, /* O - set to 1 if any pixels are null */ int *output, /* O - array of converted pixels */ int *status) /* IO - error status */ /* Copy input to output following reading of the input from a FITS file. Check for null values and do scaling if required. The nullcheck code value determines how any null values in the input array are treated. A null value is an input pixel that is equal to snull. If nullcheck= 0, then no special checking for nulls is performed. If nullcheck = 1, then the output pixel will be set = nullval if the corresponding input pixel is null. If nullcheck = 2, then if the pixel is null then the corresponding value of nullarray will be set to 1; the value of nullarray for non-null pixels will = 0. The anynull parameter will be set = 1 if any of the returned pixels are null, otherwise anynull will be returned with a value = 0; */ { int nullen; long ii; double dvalue; char *cstring, message[81]; char *cptr, *tpos; char tempstore, chrzero = '0'; double val, power; int exponent, sign, esign, decpt; nullen = strlen(snull); cptr = input; /* pointer to start of input string */ for (ii = 0; ii < ntodo; ii++) { cstring = cptr; /* temporarily insert a null terminator at end of the string */ tpos = cptr + twidth; tempstore = *tpos; *tpos = 0; /* check if null value is defined, and if the */ /* column string is identical to the null string */ if (snull[0] != ASCII_NULL_UNDEFINED && !strncmp(snull, cptr, nullen) ) { if (nullcheck) { *anynull = 1; if (nullcheck == 1) output[ii] = nullval; else nullarray[ii] = 1; } cptr += twidth; } else { /* value is not the null value, so decode it */ /* remove any embedded blank characters from the string */ decpt = 0; sign = 1; val = 0.; power = 1.; exponent = 0; esign = 1; while (*cptr == ' ') /* skip leading blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for leading sign */ { if (*cptr == '-') sign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and value */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } if (*cptr == '.') /* check for decimal point */ { decpt = 1; /* set flag to show there was a decimal point */ cptr++; while (*cptr == ' ') /* skip any blanks */ cptr++; while (*cptr >= '0' && *cptr <= '9') { val = val * 10. + *cptr - chrzero; /* accumulate the value */ power = power * 10.; cptr++; while (*cptr == ' ') /* skip embedded blanks in the value */ cptr++; } } if (*cptr == 'E' || *cptr == 'D') /* check for exponent */ { cptr++; while (*cptr == ' ') /* skip blanks */ cptr++; if (*cptr == '-' || *cptr == '+') /* check for exponent sign */ { if (*cptr == '-') esign = -1; cptr++; while (*cptr == ' ') /* skip blanks between sign and exp */ cptr++; } while (*cptr >= '0' && *cptr <= '9') { exponent = exponent * 10 + *cptr - chrzero; /* accumulate exp */ cptr++; while (*cptr == ' ') /* skip embedded blanks */ cptr++; } } if (*cptr != 0) /* should end up at the null terminator */ { sprintf(message, "Cannot read number from ASCII table"); ffpmsg(message); sprintf(message, "Column field = %s.", cstring); ffpmsg(message); /* restore the char that was overwritten by the null */ *tpos = tempstore; return(*status = BAD_C2D); } if (!decpt) /* if no explicit decimal, use implied */ power = implipower; dvalue = (sign * val / power) * pow(10., (double) (esign * exponent)); dvalue = dvalue * scale + zero; /* apply the scaling */ if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT_MAX; } else output[ii] = (long) dvalue; } /* restore the char that was overwritten by the null */ *tpos = tempstore; } return(*status); } indi-0.5/src/cfitsio/eval_f.c0000644000175000017500000027572110610474374013764 0ustar jrjr/************************************************************************/ /* */ /* CFITSIO Lexical Parser */ /* */ /* This file is one of 3 files containing code which parses an */ /* arithmetic expression and evaluates it in the context of an input */ /* FITS file table extension. The CFITSIO lexical parser is divided */ /* into the following 3 parts/files: the CFITSIO "front-end", */ /* eval_f.c, contains the interface between the user/CFITSIO and the */ /* real core of the parser; the FLEX interpreter, eval_l.c, takes the */ /* input string and parses it into tokens and identifies the FITS */ /* information required to evaluate the expression (ie, keywords and */ /* columns); and, the BISON grammar and evaluation routines, eval_y.c, */ /* receives the FLEX output and determines and performs the actual */ /* operations. The files eval_l.c and eval_y.c are produced from */ /* running flex and bison on the files eval.l and eval.y, respectively. */ /* (flex and bison are available from any GNU archive: see www.gnu.org) */ /* */ /* The grammar rules, rather than evaluating the expression in situ, */ /* builds a tree, or Nodal, structure mapping out the order of */ /* operations and expression dependencies. This "compilation" process */ /* allows for much faster processing of multiple rows. This technique */ /* was developed by Uwe Lammers of the XMM Science Analysis System, */ /* although the CFITSIO implementation is entirely code original. */ /* */ /* */ /* Modification History: */ /* */ /* Kent Blackburn c1992 Original parser code developed for the */ /* FTOOLS software package, in particular, */ /* the fselect task. */ /* Kent Blackburn c1995 BIT column support added */ /* Peter D Wilson Feb 1998 Vector column support added */ /* Peter D Wilson May 1998 Ported to CFITSIO library. User */ /* interface routines written, in essence */ /* making fselect, fcalc, and maketime */ /* capabilities available to all tools */ /* via single function calls. */ /* Peter D Wilson Jun 1998 Major rewrite of parser core, so as to */ /* create a run-time evaluation tree, */ /* inspired by the work of Uwe Lammers, */ /* resulting in a speed increase of */ /* 10-100 times. */ /* Peter D Wilson Jul 1998 gtifilter(a,b,c,d) function added */ /* Peter D Wilson Aug 1998 regfilter(a,b,c,d) function added */ /* Peter D Wilson Jul 1999 Make parser fitsfile-independent, */ /* allowing a purely vector-based usage */ /* Peter D Wilson Aug 1999 Add row-offset capability */ /* Peter D Wilson Sep 1999 Add row-range capability to ffcalc_rng */ /* */ /************************************************************************/ #include #include #include "eval_defs.h" #include "region.h" typedef struct { int datatype; /* Data type to cast parse results into for user */ void *dataPtr; /* Pointer to array of results, NULL if to use iterCol */ void *nullPtr; /* Pointer to nulval, use zero if NULL */ long maxRows; /* Max No. of rows to process, -1=all, 0=1 iteration */ int anyNull; /* Flag indicating at least 1 undef value encountered */ } parseInfo; /* Internal routines needed to allow the evaluator to operate on FITS data */ static void Setup_DataArrays( int nCols, iteratorCol *cols, long fRow, long nRows ); static int find_column( char *colName, void *itslval ); static int find_keywd ( char *key, void *itslval ); static int allocateCol( int nCol, int *status ); static int load_column( int varNum, long fRow, long nRows, void *data, char *undef ); static int DEBUG_PIXFILTER; #define FREE(x) { if (x) free(x); else printf("invalid free(" #x ") at %s:%d\n", __FILE__, __LINE__); } /*---------------------------------------------------------------------------*/ int fffrow( fitsfile *fptr, /* I - Input FITS file */ char *expr, /* I - Boolean expression */ long firstrow, /* I - First row of table to eval */ long nrows, /* I - Number of rows to evaluate */ long *n_good_rows, /* O - Number of rows eval to True */ char *row_status, /* O - Array of boolean results */ int *status ) /* O - Error status */ /* */ /* Evaluate a boolean expression using the indicated rows, returning an */ /* array of flags indicating which rows evaluated to TRUE/FALSE */ /*---------------------------------------------------------------------------*/ { parseInfo Info; int naxis, constant; long nelem, naxes[MAXDIMS], elem; char result; if( *status ) return( *status ); if( ffiprs( fptr, 0, expr, MAXDIMS, &Info.datatype, &nelem, &naxis, naxes, status ) ) { ffcprs(); return( *status ); } if( nelem<0 ) { constant = 1; nelem = -nelem; } else constant = 0; if( Info.datatype!=TLOGICAL || nelem!=1 ) { ffcprs(); ffpmsg("Expression does not evaluate to a logical scalar."); return( *status = PARSE_BAD_TYPE ); } if( constant ) { /* No need to call parser... have result from ffiprs */ result = gParse.Nodes[gParse.resultNode].value.data.log; *n_good_rows = nrows; for( elem=0; elem1 ? firstrow : 1); Info.dataPtr = row_status; Info.nullPtr = NULL; Info.maxRows = nrows; if( ffiter( gParse.nCols, gParse.colData, firstrow-1, 0, parse_data, (void*)&Info, status ) == -1 ) *status = 0; /* -1 indicates exitted without error before end... OK */ if( *status ) { /***********************/ /* Error... Do nothing */ /***********************/ } else { /***********************************/ /* Count number of good rows found */ /***********************************/ *n_good_rows = 0L; for( elem=0; elemHDUposition != (infptr->Fptr)->curhdu ) ffmahd( infptr, (infptr->HDUposition) + 1, NULL, status ); if( *status ) { ffcprs(); return( *status ); } inExt.rowLength = (long) (infptr->Fptr)->rowlength; inExt.numRows = (infptr->Fptr)->numrows; inExt.heapSize = (infptr->Fptr)->heapsize; if( inExt.numRows == 0 ) { /* Nothing to copy */ ffcprs(); return( *status ); } if( outfptr->HDUposition != (outfptr->Fptr)->curhdu ) ffmahd( outfptr, (outfptr->HDUposition) + 1, NULL, status ); if( (outfptr->Fptr)->datastart < 0 ) ffrdef( outfptr, status ); if( *status ) { ffcprs(); return( *status ); } outExt.rowLength = (long) (outfptr->Fptr)->rowlength; outExt.numRows = (outfptr->Fptr)->numrows; if( !outExt.numRows ) (outfptr->Fptr)->heapsize = 0L; outExt.heapSize = (outfptr->Fptr)->heapsize; if( inExt.rowLength != outExt.rowLength ) { ffpmsg("Output table has different row length from input"); ffcprs(); return( *status = PARSE_BAD_OUTPUT ); } /***********************************/ /* Fill out Info data for parser */ /***********************************/ Info.dataPtr = (char *)malloc( (size_t) ((inExt.numRows + 1) * sizeof(char)) ); Info.nullPtr = NULL; Info.maxRows = (long) inExt.numRows; if( !Info.dataPtr ) { ffpmsg("Unable to allocate memory for row selection"); ffcprs(); return( *status = MEMORY_ALLOCATION ); } /* make sure array is zero terminated */ ((char*)Info.dataPtr)[inExt.numRows] = 0; if( constant ) { /* Set all rows to the same value from constant result */ result = gParse.Nodes[gParse.resultNode].value.data.log; for( ntodo = 0; ntodo 1) ffirow( outfptr, outExt.numRows, nGood, status ); } do { if( ((char*)Info.dataPtr)[inloc-1] ) { ffgtbb( infptr, inloc, 1L, rdlen, buffer+rdlen*nbuff, status ); nbuff++; if( nbuff==maxrows ) { ffptbb( outfptr, outloc, 1L, rdlen*nbuff, buffer, status ); outloc += nbuff; nbuff = 0; } } inloc++; } while( !*status && inloc<=inExt.numRows ); if( nbuff ) { ffptbb( outfptr, outloc, 1L, rdlen*nbuff, buffer, status ); outloc += nbuff; } if( infptr==outfptr ) { if( outloc<=inExt.numRows ) ffdrow( infptr, outloc, inExt.numRows-outloc+1, status ); } else if( inExt.heapSize && nGood ) { /* Copy heap, if it exists and at least one row copied */ /********************************************************/ /* Get location information from the output extension */ /********************************************************/ if( outfptr->HDUposition != (outfptr->Fptr)->curhdu ) ffmahd( outfptr, (outfptr->HDUposition) + 1, NULL, status ); outExt.dataStart = (outfptr->Fptr)->datastart; outExt.heapStart = (outfptr->Fptr)->heapstart; /*************************************************/ /* Insert more space into outfptr if necessary */ /*************************************************/ hsize = outExt.heapStart + outExt.heapSize; freespace = (long) (( ( (hsize + 2879) / 2880) * 2880) - hsize); ntodo = inExt.heapSize; if ( (freespace - ntodo) < 0) { /* not enough existing space? */ ntodo = (ntodo - freespace + 2879) / 2880; /* number of blocks */ ffiblk(outfptr, (long) ntodo, 1, status); /* insert the blocks */ } ffukyj( outfptr, "PCOUNT", inExt.heapSize+outExt.heapSize, NULL, status ); /*******************************************************/ /* Get location information from the input extension */ /*******************************************************/ if( infptr->HDUposition != (infptr->Fptr)->curhdu ) ffmahd( infptr, (infptr->HDUposition) + 1, NULL, status ); inExt.dataStart = (infptr->Fptr)->datastart; inExt.heapStart = (infptr->Fptr)->heapstart; /**********************************/ /* Finally copy heap to outfptr */ /**********************************/ ntodo = inExt.heapSize; inbyteloc = inExt.heapStart + inExt.dataStart; outbyteloc = outExt.heapStart + outExt.dataStart + outExt.heapSize; while ( ntodo && !*status ) { rdlen = (long) minvalue(ntodo,500000); ffmbyt( infptr, inbyteloc, REPORT_EOF, status ); ffgbyt( infptr, rdlen, buffer, status ); ffmbyt( outfptr, outbyteloc, IGNORE_EOF, status ); ffpbyt( outfptr, rdlen, buffer, status ); inbyteloc += rdlen; outbyteloc += rdlen; ntodo -= rdlen; } /***********************************************************/ /* But must update DES if data is being appended to a */ /* pre-existing heap space. Edit each new entry in file */ /***********************************************************/ if( outExt.heapSize ) { LONGLONG repeat, offset, j; int i; for( i=1; i<=(outfptr->Fptr)->tfield; i++ ) { if( (outfptr->Fptr)->tableptr[i-1].tdatatype<0 ) { for( j=outExt.numRows+1; j<=outExt.numRows+nGood; j++ ) { ffgdesll( outfptr, i, j, &repeat, &offset, status ); offset += outExt.heapSize; ffpdes( outfptr, i, j, repeat, offset, status ); } } } } } /* End of HEAP copy */ FREE(buffer); } FREE(Info.dataPtr); ffcprs(); ffcmph(outfptr, status); /* compress heap, deleting any orphaned data */ return(*status); } /*---------------------------------------------------------------------------*/ int ffcrow( fitsfile *fptr, /* I - Input FITS file */ int datatype, /* I - Datatype to return results as */ char *expr, /* I - Arithmetic expression */ long firstrow, /* I - First row to evaluate */ long nelements, /* I - Number of elements to return */ void *nulval, /* I - Ptr to value to use as UNDEF */ void *array, /* O - Array of results */ int *anynul, /* O - Were any UNDEFs encountered? */ int *status ) /* O - Error status */ /* */ /* Calculate an expression for the indicated rows of a table, returning */ /* the results, cast as datatype (TSHORT, TDOUBLE, etc), in array. If */ /* nulval==NULL, UNDEFs will be zeroed out. For vector results, the number */ /* of elements returned may be less than nelements if nelements is not an */ /* even multiple of the result dimension. Call fftexp to obtain the */ /* dimensions of the results. */ /*---------------------------------------------------------------------------*/ { parseInfo Info; int naxis; long nelem1, naxes[MAXDIMS]; if( *status ) return( *status ); if( ffiprs( fptr, 0, expr, MAXDIMS, &Info.datatype, &nelem1, &naxis, naxes, status ) ) { ffcprs(); return( *status ); } if( nelem1<0 ) nelem1 = - nelem1; if( nelements1 ? firstrow : 1); if( datatype ) Info.datatype = datatype; Info.dataPtr = array; Info.nullPtr = nulval; Info.maxRows = nelements / nelem1; if( ffiter( gParse.nCols, gParse.colData, firstrow-1, 0, parse_data, (void*)&Info, status ) == -1 ) *status=0; /* -1 indicates exitted without error before end... OK */ *anynul = Info.anyNull; ffcprs(); return( *status ); } /*--------------------------------------------------------------------------*/ int ffcalc( fitsfile *infptr, /* I - Input FITS file */ char *expr, /* I - Arithmetic expression */ fitsfile *outfptr, /* I - Output fits file */ char *parName, /* I - Name of output parameter */ char *parInfo, /* I - Extra information on parameter */ int *status ) /* O - Error status */ /* */ /* Evaluate an expression for all rows of a table. Call ffcalc_rng with */ /* a row range of 1-MAX. */ { long start=1, end=LONG_MAX; return ffcalc_rng( infptr, expr, outfptr, parName, parInfo, 1, &start, &end, status ); } /*--------------------------------------------------------------------------*/ int ffcalc_rng( fitsfile *infptr, /* I - Input FITS file */ char *expr, /* I - Arithmetic expression */ fitsfile *outfptr, /* I - Output fits file */ char *parName, /* I - Name of output parameter */ char *parInfo, /* I - Extra information on parameter */ int nRngs, /* I - Row range info */ long *start, /* I - Row range info */ long *end, /* I - Row range info */ int *status ) /* O - Error status */ /* */ /* Evaluate an expression using the data in the input FITS file and place */ /* the results into either a column or keyword in the output fits file, */ /* depending on the value of parName (keywords normally prefixed with '#') */ /* and whether the expression evaluates to a constant or a table column. */ /* The logic is as follows: */ /* (1) If a column exists with name, parName, put results there. */ /* (2) If parName starts with '#', as in #NAXIS, put result there, */ /* with parInfo used as the comment. If expression does not evaluate */ /* to a constant, flag an error. */ /* (3) If a keyword exists with name, parName, and expression is a */ /* constant, put result there, using parInfo as the new comment. */ /* (4) Else, create a new column with name parName and TFORM parInfo. */ /* If parInfo is NULL, use a default data type for the column. */ /*--------------------------------------------------------------------------*/ { parseInfo Info; int naxis, constant, typecode, newNullKwd=0; long nelem, naxes[MAXDIMS], repeat, width; int col_cnt, colNo; Node *result; char card[81], tform[16], nullKwd[9], tdimKwd[9]; if( *status ) return( *status ); if( ffiprs( infptr, 0, expr, MAXDIMS, &Info.datatype, &nelem, &naxis, naxes, status ) ) { ffcprs(); return( *status ); } if( nelem<0 ) { constant = 1; nelem = -nelem; } else constant = 0; /* Case (1): If column exists put it there */ colNo = 0; if( ffgcno( outfptr, CASEINSEN, parName, &colNo, status )==COL_NOT_FOUND ) { /* Output column doesn't exist. Test for keyword. */ /* Case (2): Does parName indicate result should be put into keyword */ *status = 0; if( parName[0]=='#' ) { if( ! constant ) { ffcprs(); ffpmsg( "Cannot put tabular result into keyword (ffcalc)" ); return( *status = PARSE_BAD_TYPE ); } parName++; } else if( constant ) { /* Case (3): Does a keyword named parName already exist */ if( ffgcrd( outfptr, parName, card, status )==KEY_NO_EXIST ) { colNo = -1; } else if( *status ) { ffcprs(); return( *status ); } } else colNo = -1; if( colNo<0 ) { /* Case (4): Create new column */ *status = 0; ffgncl( outfptr, &colNo, status ); colNo++; if( parInfo==NULL || *parInfo=='\0' ) { /* Figure out best default column type */ if( gParse.hdutype==BINARY_TBL ) { sprintf(tform,"%ld",nelem); switch( Info.datatype ) { case TLOGICAL: strcat(tform,"L"); break; case TLONG: strcat(tform,"J"); break; case TDOUBLE: strcat(tform,"D"); break; case TSTRING: strcat(tform,"A"); break; case TBIT: strcat(tform,"X"); break; case TLONGLONG: strcat(tform,"K"); break; } } else { switch( Info.datatype ) { case TLOGICAL: ffcprs(); ffpmsg("Cannot create LOGICAL column in ASCII table"); return( *status = NOT_BTABLE ); break; case TLONG: strcpy(tform,"I11"); break; case TDOUBLE: strcpy(tform,"D23.15"); break; case TSTRING: case TBIT: sprintf(tform,"A%ld",nelem); break; } } parInfo = tform; } else if( !(isdigit((int) *parInfo)) && gParse.hdutype==BINARY_TBL ) { if( Info.datatype==TBIT && *parInfo=='B' ) nelem = (nelem+7)/8; sprintf(tform,"%ld%s",nelem,parInfo); parInfo = tform; } fficol( outfptr, colNo, parName, parInfo, status ); if( naxis>1 ) ffptdm( outfptr, colNo, naxis, naxes, status ); /* Setup TNULLn keyword in case NULLs are encountered */ ffkeyn("TNULL", colNo, nullKwd, status); if( ffgcrd( outfptr, nullKwd, card, status )==KEY_NO_EXIST ) { *status = 0; if( gParse.hdutype==BINARY_TBL ) { LONGLONG nullVal=0; fits_binary_tform( parInfo, &typecode, &repeat, &width, status ); if( typecode==TBYTE ) nullVal = UCHAR_MAX; else if( typecode==TSHORT ) nullVal = SHRT_MIN; else if( typecode==TINT ) nullVal = INT_MIN; else if( typecode==TLONG ) nullVal = LONG_MIN; else if( typecode==TLONGLONG ) nullVal = LONGLONG_MIN; if( nullVal ) { ffpkyj( outfptr, nullKwd, nullVal, "Null value", status ); fits_set_btblnull( outfptr, colNo, nullVal, status ); newNullKwd = 1; } } else if( gParse.hdutype==ASCII_TBL ) { ffpkys( outfptr, nullKwd, "NULL", "Null value string", status ); fits_set_atblnull( outfptr, colNo, "NULL", status ); newNullKwd = 1; } } } } else if( *status ) { ffcprs(); return( *status ); } else { /********************************************************/ /* Check if a TDIM keyword should be written/updated. */ /********************************************************/ ffkeyn("TDIM", colNo, tdimKwd, status); ffgcrd( outfptr, tdimKwd, card, status ); if( *status==0 ) { /* TDIM exists, so update it with result's dimension */ ffptdm( outfptr, colNo, naxis, naxes, status ); } else if( *status==KEY_NO_EXIST ) { /* TDIM does not exist, so clear error stack and */ /* write a TDIM only if result is multi-dimensional */ *status = 0; ffcmsg(); if( naxis>1 ) ffptdm( outfptr, colNo, naxis, naxes, status ); } if( *status ) { /* Either some other error happened in ffgcrd */ /* or one happened in ffptdm */ ffcprs(); return( *status ); } } if( colNo>0 ) { /* Output column exists (now)... put results into it */ int anyNull = 0; int nPerLp, i; long totaln; ffgkyj(infptr, "NAXIS2", &totaln, 0, status); /*************************************/ /* Create new iterator Output Column */ /*************************************/ col_cnt = gParse.nCols; if( allocateCol( col_cnt, status ) ) { ffcprs(); return( *status ); } fits_iter_set_by_num( gParse.colData+col_cnt, outfptr, colNo, 0, OutputCol ); gParse.nCols++; for( i=0; i= 10) && (nRngs == 1) && (start[0] == 1) && (end[0] == totaln)) nPerLp = 0; else nPerLp = Info.maxRows; if( ffiter( gParse.nCols, gParse.colData, start[i]-1, nPerLp, parse_data, (void*)&Info, status ) == -1 ) *status = 0; else if( *status ) { ffcprs(); return( *status ); } if( Info.anyNull ) anyNull = 1; } if( newNullKwd && !anyNull ) { ffdkey( outfptr, nullKwd, status ); } } else { /* Put constant result into keyword */ result = gParse.Nodes + gParse.resultNode; switch( Info.datatype ) { case TDOUBLE: ffukyd( outfptr, parName, result->value.data.dbl, 15, parInfo, status ); break; case TLONG: ffukyj( outfptr, parName, result->value.data.lng, parInfo, status ); break; case TLOGICAL: ffukyl( outfptr, parName, result->value.data.log, parInfo, status ); break; case TBIT: case TSTRING: ffukys( outfptr, parName, result->value.data.str, parInfo, status ); break; } } ffcprs(); return( *status ); } /*--------------------------------------------------------------------------*/ int fftexp( fitsfile *fptr, /* I - Input FITS file */ char *expr, /* I - Arithmetic expression */ int maxdim, /* I - Max Dimension of naxes */ int *datatype, /* O - Data type of result */ long *nelem, /* O - Vector length of result */ int *naxis, /* O - # of dimensions of result */ long *naxes, /* O - Size of each dimension */ int *status ) /* O - Error status */ /* */ /* Evaluate the given expression and return information on the result. */ /*--------------------------------------------------------------------------*/ { ffiprs( fptr, 0, expr, maxdim, datatype, nelem, naxis, naxes, status ); ffcprs(); return( *status ); } /*--------------------------------------------------------------------------*/ int ffiprs( fitsfile *fptr, /* I - Input FITS file */ int compressed, /* I - Is FITS file hkunexpanded? */ char *expr, /* I - Arithmetic expression */ int maxdim, /* I - Max Dimension of naxes */ int *datatype, /* O - Data type of result */ long *nelem, /* O - Vector length of result */ int *naxis, /* O - # of dimensions of result */ long *naxes, /* O - Size of each dimension */ int *status ) /* O - Error status */ /* */ /* Initialize the parser and determine what type of result the expression */ /* produces. */ /*--------------------------------------------------------------------------*/ { Node *result; int i,lexpr, tstatus = 0; int xaxis, bitpix; long xaxes[9]; static iteratorCol dmyCol; if( *status ) return( *status ); /* Initialize the Parser structure */ gParse.def_fptr = fptr; gParse.compressed = compressed; gParse.nCols = 0; gParse.colData = NULL; gParse.varData = NULL; gParse.getData = find_column; gParse.loadData = load_column; gParse.Nodes = NULL; gParse.nNodesAlloc= 0; gParse.nNodes = 0; gParse.hdutype = 0; gParse.status = 0; fits_get_hdu_type(fptr, &gParse.hdutype, status ); if (gParse.hdutype == IMAGE_HDU) { fits_get_img_param(fptr, 9, &bitpix, &xaxis, xaxes, status); if (*status) { ffpmsg("ffiprs: unable to get image dimensions"); return( *status ); } gParse.totalRows = xaxis > 0 ? 1 : 0; for (i = 0; i < xaxis; ++i) gParse.totalRows *= xaxes[i]; if (DEBUG_PIXFILTER) printf("naxis=%d, gParse.totalRows=%ld\n", xaxis, gParse.totalRows); } else if( ffgkyj(fptr, "NAXIS2", &gParse.totalRows, 0, &tstatus) ) { /* this might be a 1D or null image with no NAXIS2 keyword */ gParse.totalRows = 0; } /* Copy expression into parser... read from file if necessary */ if( expr[0]=='@' ) { if( ffimport_file( expr+1, &gParse.expr, status ) ) return( *status ); lexpr = strlen(gParse.expr); } else { lexpr = strlen(expr); gParse.expr = (char*)malloc( (2+lexpr)*sizeof(char)); strcpy(gParse.expr,expr); } strcat(gParse.expr + lexpr,"\n"); gParse.index = 0; gParse.is_eobuf = 0; /* Parse the expression, building the Nodes and determing */ /* which columns are needed and what data type is returned */ ffrestart(NULL); if( ffparse() ) { return( *status = PARSE_SYNTAX_ERR ); } /* Check results */ *status = gParse.status; if( *status ) return(*status); if( !gParse.nNodes ) { ffpmsg("Blank expression"); return( *status = PARSE_SYNTAX_ERR ); } if( !gParse.nCols ) { dmyCol.fptr = fptr; /* This allows iterator to know value of */ gParse.colData = &dmyCol; /* fptr when no columns are referenced */ } result = gParse.Nodes + gParse.resultNode; *naxis = result->value.naxis; *nelem = result->value.nelem; for( i=0; i<*naxis && ivalue.naxes[i]; switch( result->type ) { case BOOLEAN: *datatype = TLOGICAL; break; case LONG: *datatype = TLONG; break; case DOUBLE: *datatype = TDOUBLE; break; case BITSTR: *datatype = TBIT; break; case STRING: *datatype = TSTRING; break; default: *datatype = 0; ffpmsg("Bad return data type"); *status = gParse.status = PARSE_BAD_TYPE; break; } gParse.datatype = *datatype; FREE(gParse.expr); if( result->operation==CONST_OP ) *nelem = - *nelem; return(*status); } /*--------------------------------------------------------------------------*/ void ffcprs( void ) /* No parameters */ /* */ /* Clear the parser, making it ready to accept a new expression. */ /*--------------------------------------------------------------------------*/ { int col, node, i; if( gParse.nCols > 0 ) { FREE( gParse.colData ); for( col=0; col 0 ) { node = gParse.nNodes; while( node-- ) { if( gParse.Nodes[node].operation==gtifilt_fct ) { i = gParse.Nodes[node].SubNodes[0]; FREE( gParse.Nodes[ i ].value.data.ptr ); } else if( gParse.Nodes[node].operation==regfilt_fct ) { i = gParse.Nodes[node].SubNodes[0]; fits_free_region( (SAORegion *)gParse.Nodes[ i ].value.data.ptr ); } } gParse.nNodes = 0; } if( gParse.Nodes ) free( gParse.Nodes ); gParse.Nodes = NULL; gParse.hdutype = ANY_HDU; gParse.pixFilter = 0; } /*---------------------------------------------------------------------------*/ int parse_data( long totalrows, /* I - Total rows to be processed */ long offset, /* I - Number of rows skipped at start*/ long firstrow, /* I - First row of this iteration */ long nrows, /* I - Number of rows in this iter */ int nCols, /* I - Number of columns in use */ iteratorCol *colData, /* IO- Column information/data */ void *userPtr ) /* I - Data handling instructions */ /* */ /* Iterator work function which calls the parser and copies the results */ /* into either an OutputCol or a data pointer supplied in the userPtr */ /* structure. */ /*---------------------------------------------------------------------------*/ { int status, constant=0, anyNullThisTime=0; long jj, kk, idx, remain, ntodo; Node *result; iteratorCol * outcol; /* declare variables static to preserve their values between calls */ static void *Data, *Null; static int datasize; static long lastRow, repeat, resDataSize; LONGLONG jnull = 0; static parseInfo *userInfo; static long zeros[4] = {0,0,0,0}; if (DEBUG_PIXFILTER) printf("parse_data(total=%ld, offset=%ld, first=%ld, rows=%ld, cols=%d)\n", totalrows, offset, firstrow, nrows, nCols); /*--------------------------------------------------------*/ /* Initialization procedures: execute on the first call */ /*--------------------------------------------------------*/ outcol = colData + (nCols - 1); if (firstrow == offset+1) { userInfo = (parseInfo*)userPtr; userInfo->anyNull = 0; if( userInfo->maxRows>0 ) userInfo->maxRows = minvalue(totalrows,userInfo->maxRows); else if( userInfo->maxRows<0 ) userInfo->maxRows = totalrows; else userInfo->maxRows = nrows; lastRow = firstrow + userInfo->maxRows - 1; if( userInfo->dataPtr==NULL ) { if( outcol->iotype == InputCol ) { ffpmsg("Output column for parser results not found!"); return( PARSE_NO_OUTPUT ); } /* Data gets set later */ Null = outcol->array; userInfo->datatype = outcol->datatype; /* Check for a TNULL/BLANK keyword for output column/image */ status = 0; jnull = 0; if (gParse.hdutype == IMAGE_HDU) { if (gParse.pixFilter->blank) jnull = (LONGLONG) gParse.pixFilter->blank; } else { ffgknjj( outcol->fptr, "TNULL", outcol->colnum, 1, &jnull, (int*)&jj, &status ); if( status==BAD_INTKEY ) { /* Probably ASCII table with text TNULL keyword */ switch( userInfo->datatype ) { case TSHORT: jnull = (LONGLONG) SHRT_MIN; break; case TINT: jnull = (LONGLONG) INT_MIN; break; case TLONG: jnull = (LONGLONG) LONG_MIN; break; } } } repeat = outcol->repeat; if (DEBUG_PIXFILTER) printf("using null value %ld\n", jnull); } else { Data = userInfo->dataPtr; Null = (userInfo->nullPtr ? userInfo->nullPtr : zeros); repeat = gParse.Nodes[gParse.resultNode].value.nelem; } /* Determine the size of each element of the returned result */ switch( userInfo->datatype ) { case TBIT: /* Fall through to TBYTE */ case TLOGICAL: /* Fall through to TBYTE */ case TBYTE: datasize = sizeof(char); break; case TSHORT: datasize = sizeof(short); break; case TINT: datasize = sizeof(int); break; case TLONG: datasize = sizeof(long); break; case TLONGLONG: datasize = sizeof(LONGLONG); break; case TFLOAT: datasize = sizeof(float); break; case TDOUBLE: datasize = sizeof(double); break; case TSTRING: datasize = sizeof(char*); break; } /* Determine the size of each element of the calculated result */ /* (only matters for numeric/logical data) */ switch( gParse.Nodes[gParse.resultNode].type ) { case BOOLEAN: resDataSize = sizeof(char); break; case LONG: resDataSize = sizeof(long); break; case DOUBLE: resDataSize = sizeof(double); break; } } /*-------------------------------------------*/ /* Main loop: process all the rows of data */ /*-------------------------------------------*/ /* If writing to output column, set first element to appropriate */ /* null value. If no NULLs encounter, zero out before returning. */ if( userInfo->dataPtr == NULL ) { /* First, reset Data pointer to start of output array */ Data = (char*) outcol->array + datasize; switch( userInfo->datatype ) { case TLOGICAL: *(char *)Null = 'U'; break; case TBYTE: *(char *)Null = (char )jnull; break; case TSHORT: *(short *)Null = (short)jnull; break; case TINT: *(int *)Null = (int )jnull; break; case TLONG: *(long *)Null = (long )jnull; break; case TLONGLONG: *(LONGLONG *)Null = (LONGLONG )jnull; break; case TFLOAT: *(float *)Null = FLOATNULLVALUE; break; case TDOUBLE: *(double*)Null = DOUBLENULLVALUE; break; case TSTRING: (*(char **)Null)[0] = '\1'; (*(char **)Null)[1] = '\0'; break; } } /* Alter nrows in case calling routine didn't want to do all rows */ nrows = minvalue(nrows,lastRow-firstrow+1); Setup_DataArrays( nCols, colData, firstrow, nrows ); /* Parser allocates arrays for each column and calculation it performs. */ /* Limit number of rows processed during each pass to reduce memory */ /* requirements... In most cases, iterator will limit rows to less */ /* than 2500 rows per iteration, so this is really only relevant for */ /* hk-compressed files which must be decompressed in memory and sent */ /* whole to parse_data in a single iteration. */ remain = nrows; while( remain ) { ntodo = minvalue(remain,2500); Evaluate_Parser ( firstrow, ntodo ); if( gParse.status ) break; firstrow += ntodo; remain -= ntodo; /* Copy results into data array */ result = gParse.Nodes + gParse.resultNode; if( result->operation==CONST_OP ) constant = 1; switch( result->type ) { case BOOLEAN: case LONG: case DOUBLE: if( constant ) { char undef=0; for( kk=0; kkvalue.data), &undef, result->value.nelem /* 1 */, userInfo->datatype, Null, (char*)Data + (kk*repeat+jj)*datasize, &anyNullThisTime, &gParse.status ); } else { if ( repeat == result->value.nelem ) { ffcvtn( gParse.datatype, result->value.data.ptr, result->value.undef, result->value.nelem*ntodo, userInfo->datatype, Null, Data, &anyNullThisTime, &gParse.status ); } else if( result->value.nelem == 1 ) { for( kk=0; kkvalue.data.ptr + kk*resDataSize, (char*)result->value.undef + kk, 1, userInfo->datatype, Null, (char*)Data + (kk*repeat+jj)*datasize, &anyNullThisTime, &gParse.status ); } } else { int nCopy; nCopy = minvalue( repeat, result->value.nelem ); for( kk=0; kkvalue.data.ptr + kk*result->value.nelem*resDataSize, (char*)result->value.undef + kk*result->value.nelem, nCopy, userInfo->datatype, Null, (char*)Data + (kk*repeat)*datasize, &anyNullThisTime, &gParse.status ); if( nCopy < repeat ) { memset( (char*)Data + (kk*repeat+nCopy)*datasize, 0, (repeat-nCopy)*datasize); } } } if( result->operation>0 ) { FREE( result->value.data.ptr ); } } if( gParse.status==OVERFLOW_ERR ) { gParse.status = NUM_OVERFLOW; ffpmsg("Numerical overflow while converting expression to necessary datatype"); } break; case BITSTR: switch( userInfo->datatype ) { case TBYTE: idx = -1; for( kk=0; kkvalue.nelem; jj++ ) { if( jj%8 == 0 ) ((char*)Data)[++idx] = 0; if( constant ) { if( result->value.data.str[jj]=='1' ) ((char*)Data)[idx] |= 128>>(jj%8); } else { if( result->value.data.strptr[kk][jj]=='1' ) ((char*)Data)[idx] |= 128>>(jj%8); } } } break; case TBIT: case TLOGICAL: if( constant ) { for( kk=0; kkvalue.nelem; jj++ ) { ((char*)Data)[ jj+kk*result->value.nelem ] = ( result->value.data.str[jj]=='1' ); } } else { for( kk=0; kkvalue.nelem; jj++ ) { ((char*)Data)[ jj+kk*result->value.nelem ] = ( result->value.data.strptr[kk][jj]=='1' ); } } break; case TSTRING: if( constant ) { for( jj=0; jjvalue.data.str ); } } else { for( jj=0; jjvalue.data.strptr[jj] ); } } break; default: ffpmsg("Cannot convert bit expression to desired type."); gParse.status = PARSE_BAD_TYPE; break; } if( result->operation>0 ) { FREE( result->value.data.strptr[0] ); FREE( result->value.data.strptr ); } break; case STRING: if( userInfo->datatype==TSTRING ) { if( constant ) { for( jj=0; jjvalue.data.str ); } else { for( jj=0; jjvalue.undef[jj] ) { anyNullThisTime = 1; strcpy( ((char**)Data)[jj], *(char **)Null ); } else { strcpy( ((char**)Data)[jj], result->value.data.strptr[jj] ); } } } else { ffpmsg("Cannot convert string expression to desired type."); gParse.status = PARSE_BAD_TYPE; } if( result->operation>0 ) { FREE( result->value.data.strptr[0] ); FREE( result->value.data.strptr ); } break; } if( gParse.status ) break; /* Increment Data to point to where the next block should go */ if( result->type==BITSTR && userInfo->datatype==TBYTE ) Data = (char*)Data + datasize * ( (result->value.nelem+7)/8 ) * ntodo; else if( result->type==STRING ) Data = (char*)Data + datasize * ntodo; else Data = (char*)Data + datasize * ntodo * repeat; } /* If no NULLs encountered during this pass, set Null value to */ /* zero to make the writing of the output column data faster */ if( anyNullThisTime ) userInfo->anyNull = 1; else if( userInfo->dataPtr == NULL ) { if( userInfo->datatype == TSTRING ) memcpy( *(char **)Null, zeros, 2 ); else memcpy( Null, zeros, datasize ); } /*-------------------------------------------------------*/ /* Clean up procedures: after processing all the rows */ /*-------------------------------------------------------*/ /* if the calling routine specified that only a limited number */ /* of rows in the table should be processed, return a value of -1 */ /* once all the rows have been done, if no other error occurred. */ if (gParse.hdutype != IMAGE_HDU && firstrow - 1 == lastRow) { if (!gParse.status && userInfo->maxRowsiotype == OutputCol ) continue; nelem = varData->nelem; len = nelem * nRows; switch ( varData->type ) { case BITSTR: /* No need for UNDEF array, but must make string DATA array */ len = (nelem+1)*nRows; /* Count '\0' */ bitStrs = (char**)varData->data; if( bitStrs ) FREE( bitStrs[0] ); free( bitStrs ); bitStrs = (char**)malloc( nRows*sizeof(char*) ); if( bitStrs==NULL ) { varData->data = varData->undef = NULL; gParse.status = MEMORY_ALLOCATION; break; } bitStrs[0] = (char*)malloc( len*sizeof(char) ); if( bitStrs[0]==NULL ) { free( bitStrs ); varData->data = varData->undef = NULL; gParse.status = MEMORY_ALLOCATION; break; } for( row=0; rowarray)[idx] & (1<<(7-len%8)) ) bitStrs[row][len] = '1'; else bitStrs[row][len] = '0'; if( len%8==7 ) idx++; } bitStrs[row][len] = '\0'; } varData->undef = (char*)bitStrs; varData->data = (char*)bitStrs; break; case STRING: sptr = (char**)icol->array; if (varData->undef) free( varData->undef ); varData->undef = (char*)malloc( nRows*sizeof(char) ); if( varData->undef==NULL ) { gParse.status = MEMORY_ALLOCATION; break; } row = nRows; while( row-- ) varData->undef[row] = ( **sptr != '\0' && FSTRCMP( sptr[0], sptr[row+1] )==0 ); varData->data = sptr + 1; break; case BOOLEAN: barray = (char*)icol->array; if (varData->undef) free( varData->undef ); varData->undef = (char*)malloc( len*sizeof(char) ); if( varData->undef==NULL ) { gParse.status = MEMORY_ALLOCATION; break; } while( len-- ) { varData->undef[len] = ( barray[0]!=0 && barray[0]==barray[len+1] ); } varData->data = barray + 1; break; case LONG: iarray = (long*)icol->array; if (varData->undef) free( varData->undef ); varData->undef = (char*)malloc( len*sizeof(char) ); if( varData->undef==NULL ) { gParse.status = MEMORY_ALLOCATION; break; } while( len-- ) { varData->undef[len] = ( iarray[0]!=0L && iarray[0]==iarray[len+1] ); } varData->data = iarray + 1; break; case DOUBLE: rarray = (double*)icol->array; if (varData->undef) free( varData->undef ); varData->undef = (char*)malloc( len*sizeof(char) ); if( varData->undef==NULL ) { gParse.status = MEMORY_ALLOCATION; break; } while( len-- ) { varData->undef[len] = ( rarray[0]!=0.0 && rarray[0]==rarray[len+1]); } varData->data = rarray + 1; break; default: sprintf(msg, "SetupDataArrays, unhandled type %d\n", varData->type); ffpmsg(msg); } if( gParse.status ) { /* Deallocate NULL arrays of previous columns */ while( i-- ) { varData = gParse.varData + i; if( varData->type==BITSTR ) FREE( ((char**)varData->data)[0] ); FREE( varData->undef ); varData->undef = NULL; } return; } } } /*--------------------------------------------------------------------------*/ int ffcvtn( int inputType, /* I - Data type of input array */ void *input, /* I - Input array of type inputType */ char *undef, /* I - Array of flags indicating UNDEF elems */ long ntodo, /* I - Number of elements to process */ int outputType, /* I - Data type of output array */ void *nulval, /* I - Ptr to value to use for UNDEF elements */ void *output, /* O - Output array of type outputType */ int *anynull, /* O - Any nulls flagged? */ int *status ) /* O - Error status */ /* */ /* Convert an array of any input data type to an array of any output */ /* data type, using an array of UNDEF flags to assign nulvals to */ /*--------------------------------------------------------------------------*/ { long i; switch( outputType ) { case TLOGICAL: switch( inputType ) { case TLOGICAL: case TBYTE: for( i=0; i UCHAR_MAX ) { *status = OVERFLOW_ERR; ((unsigned char*)output)[i] = UCHAR_MAX; } else ((unsigned char*)output)[i] = (unsigned char) ((long*)input)[i]; } } return( *status ); break; case TFLOAT: fffr4i1((float*)input,ntodo,1.,0.,0,0,NULL,NULL, (unsigned char*)output,status); break; case TDOUBLE: fffr8i1((double*)input,ntodo,1.,0.,0,0,NULL,NULL, (unsigned char*)output,status); break; default: *status = BAD_DATATYPE; break; } for(i=0;i SHRT_MAX ) { *status = OVERFLOW_ERR; ((short*)output)[i] = SHRT_MAX; } else ((short*)output)[i] = (short) ((long*)input)[i]; } } return( *status ); break; case TFLOAT: fffr4i2((float*)input,ntodo,1.,0.,0,0,NULL,NULL, (short*)output,status); break; case TDOUBLE: fffr8i2((double*)input,ntodo,1.,0.,0,0,NULL,NULL, (short*)output,status); break; default: *status = BAD_DATATYPE; break; } for(i=0;i=0 ) { found[parNo] = 1; /* Flag this parameter as found */ switch( gParse.colData[parNo].datatype ) { case TLONG: ffgcvj( fptr, gParse.valCol, row, 1L, 1L, ((long*)gParse.colData[parNo].array)[0], ((long*)gParse.colData[parNo].array)+currelem, &anynul, status ); break; case TDOUBLE: ffgcvd( fptr, gParse.valCol, row, 1L, 1L, ((double*)gParse.colData[parNo].array)[0], ((double*)gParse.colData[parNo].array)+currelem, &anynul, status ); break; case TSTRING: ffgcvs( fptr, gParse.valCol, row, 1L, 1L, ((char**)gParse.colData[parNo].array)[0], ((char**)gParse.colData[parNo].array)+currelem, &anynul, status ); break; } if( *status ) return( *status ); } } if( currelemoperation==CONST_OP ) { if( result->value.data.log ) { *(long*)userPtr = firstrow; return( -1 ); } } else { for( idx=0; idxvalue.data.logptr[idx] && !result->value.undef[idx] ) { *(long*)userPtr = firstrow + idx; return( -1 ); } } } return( gParse.status ); } static int set_image_col_types (fitsfile * fptr, const char * name, int bitpix, DataInfo * varInfo, iteratorCol *colIter) { int istatus; double tscale, tzero; char temp[80]; switch (bitpix) { case BYTE_IMG: case SHORT_IMG: case LONG_IMG: istatus = 0; if (fits_read_key(fptr, TDOUBLE, "BZERO", &tzero, NULL, &istatus)) tzero = 0.0; istatus = 0; if (fits_read_key(fptr, TDOUBLE, "BSCALE", &tscale, NULL, &istatus)) tscale = 1.0; if (tscale == 1.0 && (tzero == 0.0 || tzero == 32768.0 )) { varInfo->type = LONG; colIter->datatype = TLONG; } else { varInfo->type = DOUBLE; colIter->datatype = TDOUBLE; if (DEBUG_PIXFILTER) printf("use DOUBLE for %s with BSCALE=%g/BZERO=%g\n", name, tscale, tzero); } break; case LONGLONG_IMG: case FLOAT_IMG: case DOUBLE_IMG: varInfo->type = DOUBLE; colIter->datatype = TDOUBLE; break; default: sprintf(temp, "set_image_col_types: unrecognized image bitpix [%d]\n", bitpix); ffpmsg(temp); return gParse.status = PARSE_BAD_TYPE; } return 0; } /************************************************************************* Functions used by the evaluator to access FITS data (find_column, find_keywd, allocateCol, load_column) *************************************************************************/ static int find_column( char *colName, void *itslval ) { FFSTYPE *thelval = (FFSTYPE*)itslval; int col_cnt, status; int colnum, typecode, type; long repeat, width; fitsfile *fptr; char temp[80]; double tzero,tscale; int istatus; DataInfo *varInfo; iteratorCol *colIter; if (DEBUG_PIXFILTER) printf("find_column(%s)\n", colName); if( *colName == '#' ) return( find_keywd( colName + 1, itslval ) ); fptr = gParse.def_fptr; status = 0; col_cnt = gParse.nCols; if (gParse.hdutype == IMAGE_HDU) { int i; if (!gParse.pixFilter) { gParse.status = COL_NOT_FOUND; ffpmsg("find_column: IMAGE_HDU but no PixelFilter"); return pERROR; } colnum = -1; for (i = 0; i < gParse.pixFilter->count; ++i) { if (!strcasecmp(colName, gParse.pixFilter->tag[i])) colnum = i; } if (colnum < 0) { sprintf(temp, "find_column: PixelFilter tag %s not found", colName); ffpmsg(temp); gParse.status = COL_NOT_FOUND; return pERROR; } if( allocateCol( col_cnt, &gParse.status ) ) return pERROR; varInfo = gParse.varData + col_cnt; colIter = gParse.colData + col_cnt; fptr = gParse.pixFilter->ifptr[colnum]; fits_get_img_param(fptr, MAXDIMS, &typecode, /* actually bitpix */ &varInfo->naxis, &varInfo->naxes[0], &status); varInfo->nelem = 1; type = COLUMN; if (set_image_col_types(fptr, colName, typecode, varInfo, colIter)) return pERROR; colIter->fptr = fptr; colIter->iotype = InputCol; } else { /* HDU holds a table */ if( gParse.compressed ) colnum = gParse.valCol; else if( fits_get_colnum( fptr, CASEINSEN, colName, &colnum, &status ) ) { if( status == COL_NOT_FOUND ) { type = find_keywd( colName, itslval ); if( type != pERROR ) ffcmsg(); return( type ); } gParse.status = status; return pERROR; } if( fits_get_coltype( fptr, colnum, &typecode, &repeat, &width, &status ) ) { gParse.status = status; return pERROR; } if( allocateCol( col_cnt, &gParse.status ) ) return pERROR; varInfo = gParse.varData + col_cnt; colIter = gParse.colData + col_cnt; fits_iter_set_by_num( colIter, fptr, colnum, 0, InputCol ); } /* Make sure we don't overflow variable name array */ strncpy(varInfo->name,colName,MAXVARNAME); varInfo->name[MAXVARNAME] = '\0'; if (gParse.hdutype != IMAGE_HDU) { switch( typecode ) { case TBIT: varInfo->type = BITSTR; colIter->datatype = TBYTE; type = BITCOL; break; case TBYTE: case TSHORT: case TLONG: /* The datatype of column with TZERO and TSCALE keywords might be float or double. */ sprintf(temp,"TZERO%d",colnum); istatus = 0; if(fits_read_key(fptr,TDOUBLE,temp,&tzero,NULL,&istatus)) { tzero = 0.0; } sprintf(temp,"TSCAL%d",colnum); istatus = 0; if(fits_read_key(fptr,TDOUBLE,temp,&tscale,NULL,&istatus)) { tscale = 1.0; } if (tscale == 1.0 && (tzero == 0.0 || tzero == 32768.0 )) { varInfo->type = LONG; colIter->datatype = TLONG; /* Reading an unsigned long column as a long can cause overflow errors. Treat the column as a double instead. } else if (tscale == 1.0 && tzero == 2147483648.0 ) { varInfo->type = LONG; colIter->datatype = TULONG; */ } else { varInfo->type = DOUBLE; colIter->datatype = TDOUBLE; } type = COLUMN; break; /* For now, treat 8-byte integer columns as type double. This can lose precision, so the better long term solution will be to add support for TLONGLONG as a separate datatype. */ case TLONGLONG: case TFLOAT: case TDOUBLE: varInfo->type = DOUBLE; colIter->datatype = TDOUBLE; type = COLUMN; break; case TLOGICAL: varInfo->type = BOOLEAN; colIter->datatype = TLOGICAL; type = BCOLUMN; break; case TSTRING: varInfo->type = STRING; colIter->datatype = TSTRING; type = SCOLUMN; if( gParse.hdutype == ASCII_TBL ) repeat = width; break; default: if (typecode < 0) { sprintf(temp, "variable-length array columns are not supported. typecode = %d", typecode); ffpmsg(temp); } gParse.status = PARSE_BAD_TYPE; return pERROR; } varInfo->nelem = repeat; if( repeat>1 && typecode!=TSTRING ) { if( fits_read_tdim( fptr, colnum, MAXDIMS, &varInfo->naxis, &varInfo->naxes[0], &status ) ) { gParse.status = status; return pERROR; } } else { varInfo->naxis = 1; varInfo->naxes[0] = 1; } } gParse.nCols++; thelval->lng = col_cnt; return( type ); } static int find_keywd(char *keyname, void *itslval ) { FFSTYPE *thelval = (FFSTYPE*)itslval; int status, type; char keyvalue[FLEN_VALUE], dtype; fitsfile *fptr; double rval; int bval; long ival; status = 0; fptr = gParse.def_fptr; if( fits_read_keyword( fptr, keyname, keyvalue, NULL, &status ) ) { if( status == KEY_NO_EXIST ) { /* Do this since ffgkey doesn't put an error message on stack */ sprintf(keyvalue, "ffgkey could not find keyword: %s",keyname); ffpmsg(keyvalue); } gParse.status = status; return( pERROR ); } if( fits_get_keytype( keyvalue, &dtype, &status ) ) { gParse.status = status; return( pERROR ); } switch( dtype ) { case 'C': fits_read_key_str( fptr, keyname, keyvalue, NULL, &status ); type = STRING; strcpy( thelval->str , keyvalue ); break; case 'L': fits_read_key_log( fptr, keyname, &bval, NULL, &status ); type = BOOLEAN; thelval->log = bval; break; case 'I': fits_read_key_lng( fptr, keyname, &ival, NULL, &status ); type = LONG; thelval->lng = ival; break; case 'F': fits_read_key_dbl( fptr, keyname, &rval, NULL, &status ); type = DOUBLE; thelval->dbl = rval; break; default: type = pERROR; break; } if( status ) { gParse.status=status; return pERROR; } return( type ); } static int allocateCol( int nCol, int *status ) { if( (nCol%25)==0 ) { if( nCol ) { gParse.colData = (iteratorCol*) realloc( gParse.colData, (nCol+25)*sizeof(iteratorCol) ); gParse.varData = (DataInfo *) realloc( gParse.varData, (nCol+25)*sizeof(DataInfo) ); } else { gParse.colData = (iteratorCol*) malloc( 25*sizeof(iteratorCol) ); gParse.varData = (DataInfo *) malloc( 25*sizeof(DataInfo) ); } if( gParse.colData == NULL || gParse.varData == NULL ) { if( gParse.colData ) free(gParse.colData); if( gParse.varData ) free(gParse.varData); gParse.colData = NULL; gParse.varData = NULL; return( *status = MEMORY_ALLOCATION ); } } gParse.varData[nCol].data = NULL; gParse.varData[nCol].undef = NULL; return 0; } static int load_column( int varNum, long fRow, long nRows, void *data, char *undef ) { iteratorCol *var = gParse.colData+varNum; long nelem,nbytes,row,len,idx; char **bitStrs, msg[80]; unsigned char *bytes; int status = 0, anynul; if (gParse.hdutype == IMAGE_HDU) { /* This test would need to be on a per varNum basis to support * cross HDU operations */ fits_read_imgnull(var->fptr, var->datatype, fRow, nRows, data, undef, &anynul, &status); if (DEBUG_PIXFILTER) printf("load_column: IMAGE_HDU fRow=%ld, nRows=%ld => %d\n", fRow, nRows, status); } else { nelem = nRows * var->repeat; switch( var->datatype ) { case TBYTE: nbytes = ((var->repeat+7)/8) * nRows; bytes = (unsigned char *)malloc( nbytes * sizeof(char) ); ffgcvb(var->fptr, var->colnum, fRow, 1L, nbytes, 0, bytes, &anynul, &status); nelem = var->repeat; bitStrs = (char **)data; for( row=0; rowfptr, var->colnum, fRow, 1L, nRows, (char **)data, undef, &anynul, &status); break; case TLOGICAL: ffgcfl(var->fptr, var->colnum, fRow, 1L, nelem, (char *)data, undef, &anynul, &status); break; case TLONG: ffgcfj(var->fptr, var->colnum, fRow, 1L, nelem, (long *)data, undef, &anynul, &status); break; case TDOUBLE: ffgcfd(var->fptr, var->colnum, fRow, 1L, nelem, (double *)data, undef, &anynul, &status); break; default: sprintf(msg,"load_column: unexpected datatype %d", var->datatype); ffpmsg(msg); } } if( status ) { gParse.status = status; return pERROR; } return 0; } /*--------------------------------------------------------------------------*/ int fits_pixel_filter (PixelFilter * filter, int * status) /* Evaluate an expression using the data in the input FITS file(s) */ /*--------------------------------------------------------------------------*/ { parseInfo Info = { 0 }; int naxis, constant, bitpix; long nelem, naxes[MAXDIMS]; int col_cnt; Node *result; int datatype; fitsfile * infptr; fitsfile * outfptr; char * DEFAULT_TAGS[] = { "X" }; char msg[256]; int writeBlankKwd = 0; /* write BLANK if any output nulls? */ DEBUG_PIXFILTER = getenv("DEBUG_PIXFILTER") ? 1 : 0; if (*status) return (*status); if (!filter->tag || !filter->tag[0] || !filter->tag[0][0]) { filter->tag = DEFAULT_TAGS; if (DEBUG_PIXFILTER) printf("using default tag '%s'\n", filter->tag[0]); } infptr = filter->ifptr[0]; outfptr = filter->ofptr; gParse.pixFilter = filter; if (ffiprs(infptr, 0, filter->expression, MAXDIMS, &Info.datatype, &nelem, &naxis, naxes, status)) { goto CLEANUP; } if (nelem < 0) { constant = 1; nelem = -nelem; } else constant = 0; { /* validate result type */ const char * type = 0; switch (Info.datatype) { case TLOGICAL: type = "LOGICAL"; break; case TLONG: type = "LONG"; break; case TDOUBLE: type = "DOUBLE"; break; case TSTRING: type = "STRING"; *status = pERROR; ffpmsg("pixel_filter: cannot have string image"); case TBIT: type = "BIT"; if (DEBUG_PIXFILTER) printf("hmm, image from bits?\n"); break; default: type = "UNKNOWN?!"; *status = pERROR; ffpmsg("pixel_filter: unexpected result datatype"); } if (DEBUG_PIXFILTER) printf("result type is %s [%d]\n", type, Info.datatype); if (*status) goto CLEANUP; } if (fits_get_img_param(infptr, MAXDIMS, &bitpix, &naxis, &naxes[0], status)) { ffpmsg("pixel_filter: unable to read input image parameters"); goto CLEANUP; } if (DEBUG_PIXFILTER) printf("input bitpix %d\n", bitpix); if (Info.datatype == TDOUBLE) { /* for floating point expressions, set the default output image to bitpix = -32 (float) unless the default is already a double */ if (bitpix != DOUBLE_IMG) bitpix = FLOAT_IMG; } /* override output image bitpix if specified by caller */ if (filter->bitpix) bitpix = filter->bitpix; if (DEBUG_PIXFILTER) printf("output bitpix %d\n", bitpix); if (fits_create_img(outfptr, bitpix, naxis, naxes, status)) { ffpmsg("pixel_filter: unable to create output image"); goto CLEANUP; } /* transfer keycards */ { int i, ncards, more; if (fits_get_hdrspace(infptr, &ncards, &more, status)) { ffpmsg("pixel_filter: unable to determine number of keycards"); goto CLEANUP; } for (i = 1; i <= ncards; ++i) { int keyclass; char card[FLEN_CARD]; if (fits_read_record(infptr, i, card, status)) { sprintf(msg, "pixel_filter: unable to read keycard %d", i); ffpmsg(msg); goto CLEANUP; } keyclass = fits_get_keyclass(card); if (keyclass == TYP_STRUC_KEY) { /* output structure defined by fits_create_img */ } else if (keyclass == TYP_COMM_KEY && i < 12) { /* assume this is one of the FITS standard comments */ } else if (keyclass == TYP_NULL_KEY && bitpix < 0) { /* do not transfer BLANK to real output image */ } else if (keyclass == TYP_SCAL_KEY && bitpix < 0) { /* do not transfer BZERO, BSCALE to real output image */ } else if (fits_write_record(outfptr, card, status)) { sprintf(msg, "pixel_filter: unable to write keycard '%s' [%d]\n", card, *status); ffpmsg(msg); goto CLEANUP; } } } switch (bitpix) { case BYTE_IMG: datatype = TLONG; Info.datatype = TBYTE; break; case SHORT_IMG: datatype = TLONG; Info.datatype = TSHORT; break; case LONG_IMG: datatype = TLONG; Info.datatype = TLONG; break; case FLOAT_IMG: datatype = TDOUBLE; Info.datatype = TFLOAT; break; case DOUBLE_IMG: datatype = TDOUBLE; Info.datatype = TDOUBLE; break; default: sprintf(msg, "pixel_filter: unexpected output bitpix %d\n", bitpix); ffpmsg(msg); *status = pERROR; goto CLEANUP; } if (bitpix > 0) { /* arrange for NULLs in output */ long nullVal = filter->blank; if (!filter->blank) { int tstatus = 0; if (fits_read_key_lng(infptr, "BLANK", &nullVal, 0, &tstatus)) { writeBlankKwd = 1; if (bitpix == BYTE_IMG) nullVal = UCHAR_MAX; else if (bitpix == SHORT_IMG) nullVal = SHRT_MIN; else if (bitpix == LONG_IMG) nullVal = LONG_MIN; else printf("unhandled positive output BITPIX %d\n", bitpix); } filter->blank = nullVal; } fits_set_imgnull(outfptr, filter->blank, status); if (DEBUG_PIXFILTER) printf("using blank %ld\n", nullVal); } if (!filter->keyword[0]) { iteratorCol * colIter; DataInfo * varInfo; /*************************************/ /* Create new iterator Output Column */ /*************************************/ col_cnt = gParse.nCols; if (allocateCol(col_cnt, status)) goto CLEANUP; gParse.nCols++; colIter = &gParse.colData[col_cnt]; colIter->fptr = filter->ofptr; colIter->iotype = OutputCol; varInfo = &gParse.varData[col_cnt]; set_image_col_types(colIter->fptr, "CREATED", bitpix, varInfo, colIter); Info.maxRows = -1; if (ffiter(gParse.nCols, gParse.colData, 0, 0, parse_data, &Info, status) == -1) *status = 0; else if (*status) goto CLEANUP; if (Info.anyNull) { if (writeBlankKwd) { fits_update_key_lng(outfptr, "BLANK", filter->blank, "NULL pixel value", status); if (*status) ffpmsg("pixel_filter: unable to write BLANK keyword"); if (DEBUG_PIXFILTER) { printf("output has NULLs\n"); printf("wrote blank [%d]\n", *status); } } } else if (bitpix > 0) /* never used a null */ if (fits_set_imgnull(outfptr, -1234554321, status)) ffpmsg("pixel_filter: unable to reset imgnull"); } else { /* Put constant result into keyword */ char * parName = filter->keyword; char * parInfo = filter->comment; result = gParse.Nodes + gParse.resultNode; switch (Info.datatype) { case TDOUBLE: ffukyd(outfptr, parName, result->value.data.dbl, 15, parInfo, status); break; case TLONG: ffukyj(outfptr, parName, result->value.data.lng, parInfo, status); break; case TLOGICAL: ffukyl(outfptr, parName, result->value.data.log, parInfo, status); break; case TBIT: case TSTRING: ffukys(outfptr, parName, result->value.data.str, parInfo, status); break; default: sprintf(msg, "pixel_filter: unexpected constant result type [%d]\n", Info.datatype); ffpmsg(msg); } } CLEANUP: ffcprs(); return (*status); } indi-0.5/src/cfitsio/modkey.c0000644000175000017500000016310210610474375014006 0ustar jrjr/* This file, modkey.c, contains routines that modify, insert, or update */ /* keywords in a FITS header. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include /* stddef.h is apparently needed to define size_t */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffuky( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ char *keyname, /* I - name of keyword to write */ void *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Update the keyword, value and comment in the FITS header. The datatype is specified by the 2nd argument. */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (datatype == TSTRING) { ffukys(fptr, keyname, (char *) value, comm, status); } else if (datatype == TBYTE) { ffukyj(fptr, keyname, (LONGLONG) *(unsigned char *) value, comm, status); } else if (datatype == TSBYTE) { ffukyj(fptr, keyname, (LONGLONG) *(signed char *) value, comm, status); } else if (datatype == TUSHORT) { ffukyj(fptr, keyname, (LONGLONG) *(unsigned short *) value, comm, status); } else if (datatype == TSHORT) { ffukyj(fptr, keyname, (LONGLONG) *(short *) value, comm, status); } else if (datatype == TINT) { ffukyj(fptr, keyname, (LONGLONG) *(int *) value, comm, status); } else if (datatype == TUINT) { ffukyg(fptr, keyname, (double) *(unsigned int *) value, 0, comm, status); } else if (datatype == TLOGICAL) { ffukyl(fptr, keyname, *(int *) value, comm, status); } else if (datatype == TULONG) { ffukyg(fptr, keyname, (double) *(unsigned long *) value, 0, comm, status); } else if (datatype == TLONG) { ffukyj(fptr, keyname, (LONGLONG) *(long *) value, comm, status); } else if (datatype == TLONGLONG) { ffukyj(fptr, keyname, *(LONGLONG *) value, comm, status); } else if (datatype == TFLOAT) { ffukye(fptr, keyname, *(float *) value, -7, comm, status); } else if (datatype == TDOUBLE) { ffukyd(fptr, keyname, *(double *) value, -15, comm, status); } else if (datatype == TCOMPLEX) { ffukyc(fptr, keyname, (float *) value, -7, comm, status); } else if (datatype == TDBLCOMPLEX) { ffukym(fptr, keyname, (double *) value, -15, comm, status); } else *status = BAD_DATATYPE; return(*status); } /*--------------------------------------------------------------------------*/ int ffukyu(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyu(fptr, keyname, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyu(fptr, keyname, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukys(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkys(fptr, keyname, value, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkys(fptr, keyname, value, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukls(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { /* update a long string keyword */ int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkls(fptr, keyname, value, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkls(fptr, keyname, value, comm, status); } return(*status); }/*--------------------------------------------------------------------------*/ int ffukyl(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ int value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyl(fptr, keyname, value, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyl(fptr, keyname, value, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyj(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ LONGLONG value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyj(fptr, keyname, value, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyj(fptr, keyname, value, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyf(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyf(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyf(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukye(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkye(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkye(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyg(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyg(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyg(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyd(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyd(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyd(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukfc(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkfc(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkfc(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukyc(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkyc(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkyc(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukfm(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkfm(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkfm(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffukym(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmkym(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST) { *status = tstatus; ffpkym(fptr, keyname, value, decim, comm, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffucrd(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *card, /* I - card string value */ int *status) /* IO - error status */ { int tstatus; if (*status > 0) /* inherit input status value if > 0 */ return(*status); tstatus = *status; if (ffmcrd(fptr, keyname, card, status) == KEY_NO_EXIST) { *status = tstatus; ffprec(fptr, card, status); } return(*status); } /*--------------------------------------------------------------------------*/ int ffmrec(fitsfile *fptr, /* I - FITS file pointer */ int nkey, /* I - number of the keyword to modify */ char *card, /* I - card string value */ int *status) /* IO - error status */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffmaky(fptr, nkey+1, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmcrd(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *card, /* I - card string value */ int *status) /* IO - error status */ { char tcard[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgcrd(fptr, keyname, tcard, status) > 0) return(*status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmnam(fitsfile *fptr, /* I - FITS file pointer */ char *oldname, /* I - existing keyword name */ char *newname, /* I - new name for keyword */ int *status) /* IO - error status */ { char comm[FLEN_COMMENT]; char value[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, oldname, value, comm, status) > 0) return(*status); ffmkky(newname, value, comm, card, status); /* construct the card */ ffmkey(fptr, card, status); /* rewrite with new name */ return(*status); } /*--------------------------------------------------------------------------*/ int ffmcom(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char oldcomm[FLEN_COMMENT]; char value[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, value, oldcomm, status) > 0) return(*status); ffmkky(keyname, value, comm, card, status); /* construct the card */ ffmkey(fptr, card, status); /* rewrite with new comment */ return(*status); } /*--------------------------------------------------------------------------*/ int ffpunt(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *unit, /* I - keyword unit string */ int *status) /* IO - error status */ /* Write (put) the units string into the comment field of the existing keyword. This routine uses a local FITS convention (not defined in the official FITS standard) in which the units are enclosed in square brackets following the '/' comment field delimiter, e.g.: KEYWORD = 12 / [kpc] comment string goes here */ { char oldcomm[FLEN_COMMENT]; char newcomm[FLEN_COMMENT]; char value[FLEN_VALUE]; char card[FLEN_CARD]; char *loc; size_t len; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, value, oldcomm, status) > 0) return(*status); /* copy the units string to the new comment string if not null */ if (*unit) { strcpy(newcomm, "["); strncat(newcomm, unit, 45); /* max allowed length is about 45 chars */ strcat(newcomm, "] "); len = strlen(newcomm); len = FLEN_COMMENT - len - 1; /* amount of space left in the field */ } else { newcomm[0] = '\0'; len = FLEN_COMMENT - 1; } if (oldcomm[0] == '[') /* check for existing units field */ { loc = strchr(oldcomm, ']'); /* look for the closing bracket */ if (loc) { loc++; while (*loc == ' ') /* skip any blank spaces */ loc++; strncat(newcomm, loc, len); /* concat remainder of comment */ } else { strncat(newcomm, oldcomm, len); /* append old comment onto new */ } } else { strncat(newcomm, oldcomm, len); } ffmkky(keyname, value, newcomm, card, status); /* construct the card */ ffmkey(fptr, card, status); /* rewrite with new units string */ return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyu(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring," "); /* create a dummy value string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkys(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { /* NOTE: This routine does not support long continued strings */ /* It will correctly overwrite an existing long continued string, */ /* but it will not write a new long string. */ char oldval[FLEN_VALUE], valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; int len, keypos; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, oldval, oldcomm, status) > 0) return(*status); /* get old comment */ ffs2c(value, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); /* overwrite the previous keyword */ keypos = (int) (((((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])) / 80) + 1); /* check if old string value was continued over multiple keywords */ ffc2s(oldval, valstring, status); /* remove quotes and trailing spaces */ len = strlen(valstring); while (len && valstring[len - 1] == '&') /* ampersand is continuation char */ { ffgcnt(fptr, valstring, status); if (*valstring) { ffdrec(fptr, keypos, status); /* delete the continuation */ len = strlen(valstring); } else /* a null valstring indicates no continuation */ len = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffmkls( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ char *value, /* I - keyword value */ char *incomm, /* I - keyword comment */ int *status) /* IO - error status */ /* Modify the value and optionally the comment of a long string keyword. This routine supports the HEASARC long string convention and can modify arbitrarily long string keyword values. The value is continued over multiple keywords that have the name COMTINUE without an equal sign in column 9 of the card. This routine also supports simple string keywords which are less than 69 characters in length. This routine is not very efficient, so it should be used sparingly. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; char comm[FLEN_COMMENT]; char tstring[FLEN_VALUE], *cptr; char *longval; int next, remain, vlen, nquote, nchar, namelen, contin, tstatus = -1; int nkeys, keypos; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (!incomm || incomm[0] == '&') /* preserve the old comment string */ { ffghps(fptr, &nkeys, &keypos, status); /* save current position */ if (ffgkls(fptr, keyname, &longval, comm, status) > 0) return(*status); /* keyword doesn't exist */ free(longval); /* don't need the old value */ /* move back to previous position to ensure that we delete */ /* the right keyword in case there are more than one keyword */ /* with this same name. */ ffgrec(fptr, keypos - 1, card, status); } else strcpy(comm, incomm); /* copy the input comment string */ /* delete the old keyword */ if (ffdkey(fptr, keyname, status) > 0) return(*status); /* keyword doesn't exist */ ffghps(fptr, &nkeys, &keypos, status); /* save current position */ /* now construct the new keyword, and insert into header */ remain = strlen(value); /* number of characters to write out */ next = 0; /* pointer to next character to write */ /* count the number of single quote characters in the string */ nquote = 0; cptr = strchr(value, '\''); /* search for quote character */ while (cptr) /* search for quote character */ { nquote++; /* increment no. of quote characters */ cptr++; /* increment pointer to next character */ cptr = strchr(cptr, '\''); /* search for another quote char */ } cptr = keyname; while(*cptr == ' ') /* skip over leading spaces in name */ cptr++; /* determine the number of characters that will fit on the line */ /* Note: each quote character is expanded to 2 quotes */ namelen = strlen(cptr); if (namelen <= 8 && (fftkey(cptr, &tstatus) <= 0) ) { /* This a normal 8-character FITS keyword */ nchar = 68 - nquote; /* max of 68 chars fit in a FITS string value */ } else { /* This a HIERARCH keyword */ if (FSTRNCMP(cptr, "HIERARCH ", 9) && FSTRNCMP(cptr, "hierarch ", 9)) nchar = 66 - nquote - namelen; else nchar = 75 - nquote - namelen; /* don't count 'HIERARCH' twice */ } contin = 0; while (remain > 0) { strncpy(tstring, &value[next], nchar); /* copy string to temp buff */ tstring[nchar] = '\0'; ffs2c(tstring, valstring, status); /* put quotes around the string */ if (remain > nchar) /* if string is continued, put & as last char */ { vlen = strlen(valstring); nchar -= 1; /* outputting one less character now */ if (valstring[vlen-2] != '\'') valstring[vlen-2] = '&'; /* over write last char with & */ else { /* last char was a pair of single quotes, so over write both */ valstring[vlen-3] = '&'; valstring[vlen-1] = '\0'; } } if (contin) /* This is a CONTINUEd keyword */ { ffmkky("CONTINUE", valstring, comm, card, status); /* make keyword */ strncpy(&card[8], " ", 2); /* overwrite the '=' */ } else { ffmkky(keyname, valstring, comm, card, status); /* make keyword */ } ffirec(fptr, keypos, card, status); /* insert the keyword */ keypos++; /* next insert position */ contin = 1; remain -= nchar; next += nchar; nchar = 68 - nquote; } return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyl(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ int value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffl2c(value, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyj(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ LONGLONG value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffi2c(value, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyf(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffr2f(value, decim, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkye(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffr2e(value, decim, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyg(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffd2f(value, decim, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyd(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ ffd2e(value, decim, valstring, status); /* convert value to a string */ if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkfc(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring, "(" ); ffr2f(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2f(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkyc(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring, "(" ); ffr2e(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2e(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkfm(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring, "(" ); ffd2f(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2f(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffmkym(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char oldcomm[FLEN_COMMENT]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0) return(*status); /* get old comment */ strcpy(valstring, "(" ); ffd2e(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2e(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); if (!comm || comm[0] == '&') /* preserve the current comment string */ ffmkky(keyname, valstring, oldcomm, card, status); else ffmkky(keyname, valstring, comm, card, status); ffmkey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffikyu(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Insert a null-valued keyword and comment into the FITS header. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring," "); /* create a dummy value string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffikys(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffs2c(value, valstring, status); /* put quotes around the string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffikls( fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - name of keyword to write */ char *value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ /* Insert a long string keyword. This routine supports the HEASARC long string convention and can insert arbitrarily long string keyword values. The value is continued over multiple keywords that have the name COMTINUE without an equal sign in column 9 of the card. This routine also supports simple string keywords which are less than 69 characters in length. */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; char tstring[FLEN_VALUE], *cptr; int next, remain, vlen, nquote, nchar, namelen, contin, tstatus = -1; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* construct the new keyword, and insert into header */ remain = strlen(value); /* number of characters to write out */ next = 0; /* pointer to next character to write */ /* count the number of single quote characters in the string */ nquote = 0; cptr = strchr(value, '\''); /* search for quote character */ while (cptr) /* search for quote character */ { nquote++; /* increment no. of quote characters */ cptr++; /* increment pointer to next character */ cptr = strchr(cptr, '\''); /* search for another quote char */ } cptr = keyname; while(*cptr == ' ') /* skip over leading spaces in name */ cptr++; /* determine the number of characters that will fit on the line */ /* Note: each quote character is expanded to 2 quotes */ namelen = strlen(cptr); if (namelen <= 8 && (fftkey(cptr, &tstatus) <= 0) ) { /* This a normal 8-character FITS keyword */ nchar = 68 - nquote; /* max of 68 chars fit in a FITS string value */ } else { /* This a HIERARCH keyword */ if (FSTRNCMP(cptr, "HIERARCH ", 9) && FSTRNCMP(cptr, "hierarch ", 9)) nchar = 66 - nquote - namelen; else nchar = 75 - nquote - namelen; /* don't count 'HIERARCH' twice */ } contin = 0; while (remain > 0) { strncpy(tstring, &value[next], nchar); /* copy string to temp buff */ tstring[nchar] = '\0'; ffs2c(tstring, valstring, status); /* put quotes around the string */ if (remain > nchar) /* if string is continued, put & as last char */ { vlen = strlen(valstring); nchar -= 1; /* outputting one less character now */ if (valstring[vlen-2] != '\'') valstring[vlen-2] = '&'; /* over write last char with & */ else { /* last char was a pair of single quotes, so over write both */ valstring[vlen-3] = '&'; valstring[vlen-1] = '\0'; } } if (contin) /* This is a CONTINUEd keyword */ { ffmkky("CONTINUE", valstring, comm, card, status); /* make keyword */ strncpy(&card[8], " ", 2); /* overwrite the '=' */ } else { ffmkky(keyname, valstring, comm, card, status); /* make keyword */ } ffikey(fptr, card, status); /* insert the keyword */ contin = 1; remain -= nchar; next += nchar; nchar = 68 - nquote; } return(*status); } /*--------------------------------------------------------------------------*/ int ffikyl(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ int value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffl2c(value, valstring, status); /* convert logical to 'T' or 'F' */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyj(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ LONGLONG value, /* I - keyword value */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffi2c(value, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyf(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffr2f(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikye(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffr2e(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyg(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffd2f(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyd(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffd2e(value, decim, valstring, status); /* convert to formatted string */ ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikfc(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffr2f(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2f(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikyc(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ float *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffr2e(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffr2e(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikfm(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffd2f(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2f(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffikym(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ double *value, /* I - keyword value */ int decim, /* I - no of decimals */ char *comm, /* I - keyword comment */ int *status) /* IO - error status */ { char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE]; char card[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); strcpy(valstring, "(" ); ffd2e(value[0], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ", "); ffd2e(value[1], decim, tmpstring, status); /* convert to string */ strcat(valstring, tmpstring); strcat(valstring, ")"); ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/ ffikey(fptr, card, status); /* write the keyword*/ return(*status); } /*--------------------------------------------------------------------------*/ int ffirec(fitsfile *fptr, /* I - FITS file pointer */ int nkey, /* I - position to insert new keyword */ char *card, /* I - card string value */ int *status) /* IO - error status */ { if (*status > 0) /* inherit input status value if > 0 */ return(*status); ffmaky(fptr, nkey, status); /* move to insert position */ ffikey(fptr, card, status); /* insert the keyword card */ return(*status); } /*--------------------------------------------------------------------------*/ int ffikey(fitsfile *fptr, /* I - FITS file pointer */ char *card, /* I - card string value */ int *status) /* IO - error status */ /* insert a keyword at the position of (fptr->Fptr)->nextkey */ { int ii, len, nshift; long nblocks; LONGLONG bytepos; char *inbuff, *outbuff, *tmpbuff, buff1[FLEN_CARD], buff2[FLEN_CARD]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if ( ((fptr->Fptr)->datastart - (fptr->Fptr)->headend) == 80) /* only room for END card */ { nblocks = 1; if (ffiblk(fptr, nblocks, 0, status) > 0) /* add new 2880-byte block*/ return(*status); } /* no. keywords to shift */ nshift= (int) (( (fptr->Fptr)->headend - (fptr->Fptr)->nextkey ) / 80); strncpy(buff2, card, 80); /* copy card to output buffer */ buff2[80] = '\0'; len = strlen(buff2); for (ii=len; ii < 80; ii++) /* fill buffer with spaces if necessary */ buff2[ii] = ' '; for (ii=0; ii < 8; ii++) /* make sure keyword name is uppercase */ buff2[ii] = toupper(buff2[ii]); fftkey(buff2, status); /* test keyword name contains legal chars */ fftrec(buff2, status); /* test rest of keyword for legal chars */ inbuff = buff1; outbuff = buff2; bytepos = (fptr->Fptr)->nextkey; /* pointer to next keyword in header */ ffmbyt(fptr, bytepos, REPORT_EOF, status); for (ii = 0; ii < nshift; ii++) /* shift each keyword down one position */ { ffgbyt(fptr, 80, inbuff, status); /* read the current keyword */ ffmbyt(fptr, bytepos, REPORT_EOF, status); /* move back */ ffpbyt(fptr, 80, outbuff, status); /* overwrite with other buffer */ tmpbuff = inbuff; /* swap input and output buffers */ inbuff = outbuff; outbuff = tmpbuff; bytepos += 80; } ffpbyt(fptr, 80, outbuff, status); /* write the final keyword */ (fptr->Fptr)->headend += 80; /* increment the position of the END keyword */ (fptr->Fptr)->nextkey += 80; /* increment the pointer to next keyword */ return(*status); } /*--------------------------------------------------------------------------*/ int ffdkey(fitsfile *fptr, /* I - FITS file pointer */ char *keyname, /* I - keyword name */ int *status) /* IO - error status */ /* delete a specified header keyword */ { int keypos, len; char valstring[FLEN_VALUE], comm[FLEN_COMMENT], value[FLEN_VALUE]; char message[FLEN_ERRMSG]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); if (ffgkey(fptr, keyname, valstring, comm, status) > 0) /* read keyword */ { sprintf(message, "Could not find the %s keyword to delete (ffdkey)", keyname); ffpmsg(message); return(*status); } /* calc position of keyword in header */ keypos = (int) ((((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])) / 80); ffdrec(fptr, keypos, status); /* delete the keyword */ /* check for string value which may be continued over multiple keywords */ ffc2s(valstring, value, status); /* remove quotes and trailing spaces */ len = strlen(value); while (len && value[len - 1] == '&') /* ampersand used as continuation char */ { ffgcnt(fptr, value, status); if (*value) { ffdrec(fptr, keypos, status); /* delete the keyword */ len = strlen(value); } else /* a null valstring indicates no continuation */ len = 0; } return(*status); } /*--------------------------------------------------------------------------*/ int ffdrec(fitsfile *fptr, /* I - FITS file pointer */ int keypos, /* I - position in header of keyword to delete */ int *status) /* IO - error status */ /* Delete a header keyword at position keypos. The 1st keyword is at keypos=1. */ { int ii, nshift; LONGLONG bytepos; char *inbuff, *outbuff, *tmpbuff, buff1[81], buff2[81]; char message[FLEN_ERRMSG]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); if (keypos < 1 || keypos > (fptr->Fptr)->headend - (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] / 80 ) return(*status = KEY_OUT_BOUNDS); (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] + (keypos - 1) * 80; nshift=(int) (( (fptr->Fptr)->headend - (fptr->Fptr)->nextkey ) / 80); /* no. keywords to shift */ if (nshift <= 0) { sprintf(message, "Cannot delete keyword number %d. It does not exist.", keypos); ffpmsg(message); return(*status = KEY_OUT_BOUNDS); } bytepos = (fptr->Fptr)->headend - 80; /* last keyword in header */ /* construct a blank keyword */ strcpy(buff2, " "); strcat(buff2, " "); inbuff = buff1; outbuff = buff2; for (ii = 0; ii < nshift; ii++) /* shift each keyword up one position */ { ffmbyt(fptr, bytepos, REPORT_EOF, status); ffgbyt(fptr, 80, inbuff, status); /* read the current keyword */ ffmbyt(fptr, bytepos, REPORT_EOF, status); ffpbyt(fptr, 80, outbuff, status); /* overwrite with next keyword */ tmpbuff = inbuff; /* swap input and output buffers */ inbuff = outbuff; outbuff = tmpbuff; bytepos -= 80; } (fptr->Fptr)->headend -= 80; /* decrement the position of the END keyword */ return(*status); } indi-0.5/src/cfitsio/drvrnet.c0000644000175000017500000020737710610474374014216 0ustar jrjr/* This file, drvrhttp.c contains driver routines for http, ftp and root files. */ /* This file was written by Bruce O'Neel at the ISDC, Switzerland */ /* The FITSIO software is maintained by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ /* Notes on the drivers: The ftp driver uses passive mode exclusivly. If your remote system can't deal with passive mode then it'll fail. Since Netscape Navigator uses passive mode as well there shouldn't be too many ftp servers which have problems. The http driver works properly with 301 and 302 redirects. For many more gory details see http://www.w3c.org/Protocols/rfc2068/rfc2068. The only catch to the 301/302 redirects is that they have to redirect to another http:// url. If not, things would have to change a lot in cfitsio and this was thought to be too difficult. Redirects look like 301 Moved Permanently

Moved Permanently

The document has moved here.

This redirect was from apache 1.2.5 but most of the other servers produce something very similiar. The parser for the redirects finds the first anchor tag in the body and goes there. If that wasn't what was intended by the remote system then hopefully the error stack, which includes notes about the redirect will help the user fix the problem. Root protocal doesn't have any real docs, so, the emperical docs are as follows. First, you must use a slightly modified rootd server. The modifications include implimentation of the stat command which returns the size of the remote file. Without that it's impossible for cfitsio to work properly since fitsfiles don't include any information about the size of the files in the headers. The rootd server closes the connections on any errors, including reading beyond the end of the file or seeking beyond the end of the file. The rootd:// driver doesn't reopen a closed connection, if the connection is closed you're pretty much done. The messages are of the form All binary information is transfered in network format, so use htonl and ntohl to convert back and forth. :== 4 byte length, in network format, the len doesn't include the length of :== one of the message opcodes below, 4 bytes, network format :== depends on opcode The response is of the same form with the same opcode sent. Success is indicated by being 0. Root is a NFSish protocol where each read/write includes the byte offset to read or write to. As a result, seeks will always succeed in the driver even if they would cause a fatal error when you try to read because you're beyond the end of the file. There is file locking on the host such that you need to possibly create /usr/tmp/rootdtab on the host system. There is one file per socket connection, though the rootd daemon can support multiple files open at once. The messages are sent in the following order: ROOTD_USER - user name, is the user name, trailing null is sent though it's not required it seems. A ROOTD_AUTH message is returned with any sort of error meaning that the user name is wrong. ROOTD_PASS - password, ones complemented, stored in . Once again the trailing null is sent. Once again a ROOTD_AUTH message is returned ROOTD_OPEN - includes filename and one of {create|update|read} as the file mode. ~ seems to be dealt with as the username's login directory. A ROOTD_OPEN message is returned. Once the file is opened any of the following can be sent: ROOTD_STAT - file status and size returns a message where is the file length in bytes ROOTD_FLUSH - flushes the file, not sure this has any real effect on the daemon since the daemon uses open/read/write/close rather than the buffered fopen/fread/fwrite/fclose. ROOTD_GET - on send includes a text message of offset and length to get. Return is a status message first with a status value, then, the raw bytes for the length that you requested. It's an error to seek or read past the end of the file, and, the rootd daemon exits and won't respond anymore. Ie, don't do this. ROOTD_PUT - on send includes a text message of offset and length to put. Then send the raw bytes you want to write. Then recieve a status message When you are finished then you send the message: ROOTD_CLOSE - closes the file Once the file is closed then the socket is closed. $Id: drvrnet.c,v 3.45 2005/12/21 18:18:01 pence Exp $ $Log: drvrnet.c,v $ Revision 3.45 2005/12/21 18:18:01 pence New beta 3.005 release. Contains new cfortran.h to support integer*8 parameters when calling cfitsio from Fortran tasks. Also has modified fitsio.h file that now assumes that the 'long long' data type is supported by the C compiler (which may not be the case for older compilers). Revision 1.56 2000/01/04 11:58:31 oneel Updates so that compressed network files are dealt with regardless of their file names and/or mime types. Revision 1.55 2000/01/04 10:52:40 oneel cfitsio 2.034 Revision 1.51 1999/08/10 12:13:40 oneel Make the http code a bit less picky about the types of files it uncompresses. Now it also uncompresses files which end in .Z or .gz. Revision 1.50 1999/08/04 12:38:46 oneel Don's 2.0.32 patch with dal 1.3 Revision 1.39 1998/12/02 15:31:33 oneel Updates to drvrnet.c so that less compiler warnings would be generated. Fixes the signal handling. Revision 1.38 1998/11/23 10:03:24 oneel Added in a useragent string, as suggested by: Tim Kimball · Data Systems Division ¦ kimball@stsci.edu · 410-338-4417 Space Telescope Science Institute ¦ http://www.stsci.edu/~kimball/ 3700 San Martin Drive ¦ http://archive.stsci.edu/ Baltimore MD 21218 USA ¦ http://faxafloi.stsci.edu:4547/ */ #ifdef HAVE_NET_SERVICES #include #include #include #include #include #include #include #include #include #include #include #if defined(unix) || defined(__unix__) || defined(__unix) #include #endif #include #include #include "fitsio2.h" static jmp_buf env; /* holds the jump buffer for setjmp/longjmp pairs */ static void signal_handler(int sig); /* Network routine error codes */ #define NET_OK 0 #define NOT_INET_ADDRESS -1000 #define UNKNOWN_INET_HOST -1001 #define CONNECTION_ERROR -1002 /* Network routine constants */ #define NET_DEFAULT 0 #define NET_OOB 1 #define NET_PEEK 2 #define NETTIMEOUT 180 /* in secs */ /* local defines and variables */ #define MAXLEN 1200 #define SHORTLEN 100 static char netoutfile[MAXLEN]; #define ROOTD_USER 2000 /*user id follows */ #define ROOTD_PASS 2001 /*passwd follows */ #define ROOTD_AUTH 2002 /*authorization status (to client) */ #define ROOTD_FSTAT 2003 /*filename follows */ #define ROOTD_OPEN 2004 /*filename follows + mode */ #define ROOTD_PUT 2005 /*offset, number of bytes and buffer */ #define ROOTD_GET 2006 /*offset, number of bytes */ #define ROOTD_FLUSH 2007 /*flush file */ #define ROOTD_CLOSE 2008 /*close file */ #define ROOTD_STAT 2009 /*return rootd statistics */ #define ROOTD_ACK 2010 /*acknowledgement (all OK) */ #define ROOTD_ERR 2011 /*error code and message follow */ typedef struct /* structure containing disk file structure */ { int sock; LONGLONG currentpos; } rootdriver; static rootdriver handleTable[NMAXFILES]; /* allocate diskfile handle tables */ /* static prototypes */ static int NET_TcpConnect(char *hostname, int port); static int NET_SendRaw(int sock, const void *buf, int length, int opt); static int NET_RecvRaw(int sock, void *buffer, int length); static int NET_ParseUrl(const char *url, char *proto, char *host, int *port, char *fn); static int CreateSocketAddress(struct sockaddr_in *sockaddrPtr, char *host,int port); static int ftp_status(FILE *ftp, char *statusstr); static int http_open_network(char *url, FILE **httpfile, char *contentencoding, int *contentlength); static int ftp_open_network(char *url, FILE **ftpfile, FILE **command, int *sock); static int root_send_buffer(int sock, int op, char *buffer, int buflen); static int root_recv_buffer(int sock, int *op, char *buffer,int buflen); static int root_openfile(char *filename, char *rwmode, int *sock); /***************************/ /* Static variables */ static int closehttpfile; static int closememfile; static int closefdiskfile; static int closediskfile; static int closefile; static int closeoutfile; static int closecommandfile; static int closeftpfile; static FILE *diskfile; static FILE *outfile; /*--------------------------------------------------------------------------*/ /* This creates a memory file handle with a copy of the URL in filename. The file is uncompressed if necessary */ int http_open(char *filename, int rwmode, int *handle) { FILE *httpfile; char contentencoding[SHORTLEN]; char newfilename[MAXLEN]; char errorstr[MAXLEN]; char recbuf[MAXLEN]; long len; int contentlength; int status; char firstchar; closehttpfile = 0; closememfile = 0; /* don't do r/w files */ if (rwmode != 0) { ffpmsg("Can't open http:// type file with READWRITE access"); ffpmsg(" Specify an outfile for r/w access (http_open)"); goto error; } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); goto error; } (void) signal(SIGALRM, signal_handler); /* Open the network connection */ /* Does the file have a .Z or .gz in it */ /* Also, if file has a '?' in it (probably cgi script) */ if (strstr(filename,".Z") || strstr(filename,".gz") || strstr(filename,"?")) { alarm(NETTIMEOUT); if (http_open_network(filename,&httpfile,contentencoding, &contentlength)) { alarm(0); ffpmsg("Unable to open http file (http_open):"); ffpmsg(filename); goto error; } } else { alarm(NETTIMEOUT); /* Try the .gz one */ strcpy(newfilename,filename); strcat(newfilename,".gz"); if (http_open_network(newfilename,&httpfile,contentencoding, &contentlength)) { alarm(0); /* Now the .Z one */ strcpy(newfilename,filename); strcat(newfilename,".Z"); alarm(NETTIMEOUT); if (http_open_network(newfilename,&httpfile,contentencoding, &contentlength)) { alarm(0); alarm(NETTIMEOUT); if (http_open_network(filename,&httpfile,contentencoding, &contentlength)) { alarm(0); ffpmsg("Unable to open http file (http_open)"); ffpmsg(filename); goto error; } } } } closehttpfile++; /* Create the memory file */ if ((status = mem_create(filename,handle))) { ffpmsg("Unable to create memory file (http_open)"); goto error; } closememfile++; /* Now, what do we do with the file */ /* Check to see what the first character is */ firstchar = fgetc(httpfile); ungetc(firstchar,httpfile); if (!strcmp(contentencoding,"x-gzip") || !strcmp(contentencoding,"x-compress") || strstr(filename,".gz") || strstr(filename,".Z") || ('\037' == firstchar)) { /* do the compress dance, which is the same as the gzip dance */ /* Using the cfitsio routine */ status = 0; /* Ok, this is a tough case, let's be arbritary and say 10*NETTIMEOUT, Given the choices for nettimeout above they'll probaby ^C before, but it's always worth a shot*/ alarm(NETTIMEOUT*10); status = mem_uncompress2mem(filename, httpfile, *handle); alarm(0); if (status) { ffpmsg("Error writing compressed memory file (http_open)"); ffpmsg(filename); goto error; } } else { /* It's not compressed, bad choice, but we'll copy it anyway */ if (contentlength % 2880) { sprintf(errorstr,"Content-Length not a multiple of 2880 (http_open) %d", contentlength); ffpmsg(errorstr); } /* write a memory file */ alarm(NETTIMEOUT); while(0 != (len = fread(recbuf,1,MAXLEN,httpfile))) { alarm(0); /* cancel alarm */ status = mem_write(*handle,recbuf,len); if (status) { ffpmsg("Error copying http file into memory (http_open)"); ffpmsg(filename); goto error; } alarm(NETTIMEOUT); /* rearm the alarm */ } } fclose(httpfile); signal(SIGALRM, SIG_DFL); alarm(0); return mem_seek(*handle,0); error: alarm(0); /* clear it */ if (closehttpfile) { fclose(httpfile); } if (closememfile) { mem_close_free(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This creates a memory file handle with a copy of the URL in filename. The file must be compressed and is copied (still compressed) to disk first. The compressed disk file is then uncompressed into memory (READONLY). */ int http_compress_open(char *url, int rwmode, int *handle) { FILE *httpfile; char contentencoding[SHORTLEN]; char recbuf[MAXLEN]; long len; int contentlength; int ii, flen, status; char firstchar; closehttpfile = 0; closediskfile = 0; closefdiskfile = 0; closememfile = 0; /* cfileio made a mistake, should set the netoufile first otherwise we don't know where to write the output file */ flen = strlen(netoutfile); if (!flen) { ffpmsg ("Output file not set, shouldn't have happened (http_compress_open)"); goto error; } if (rwmode != 0) { ffpmsg("Can't open compressed http:// type file with READWRITE access"); ffpmsg(" Specify an UNCOMPRESSED outfile (http_compress_open)"); goto error; } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); goto error; } signal(SIGALRM, signal_handler); /* Open the http connectin */ alarm(NETTIMEOUT); if ((status = http_open_network(url,&httpfile,contentencoding, &contentlength))) { alarm(0); ffpmsg("Unable to open http file (http_compress_open)"); ffpmsg(url); goto error; } closehttpfile++; /* Better be compressed */ firstchar = fgetc(httpfile); ungetc(firstchar,httpfile); if (!strcmp(contentencoding,"x-gzip") || !strcmp(contentencoding,"x-compress") || ('\037' == firstchar)) { if (*netoutfile == '!') { /* user wants to clobber file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ status = file_remove(netoutfile); } /* Create the new file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output disk file (http_compress_open):"); ffpmsg(netoutfile); goto error; } closediskfile++; /* write a file */ alarm(NETTIMEOUT); while(0 != (len = fread(recbuf,1,MAXLEN,httpfile))) { alarm(0); status = file_write(*handle,recbuf,len); if (status) { ffpmsg("Error writing disk file (http_compres_open)"); ffpmsg(netoutfile); goto error; } alarm(NETTIMEOUT); } file_close(*handle); fclose(httpfile); closehttpfile--; closediskfile--; /* File is on disk, let's uncompress it into memory */ if (NULL == (diskfile = fopen(netoutfile,"r"))) { ffpmsg("Unable to reopen disk file (http_compress_open)"); ffpmsg(netoutfile); goto error; } closefdiskfile++; /* Create the memory handle to hold it */ if ((status = mem_create(url,handle))) { ffpmsg("Unable to create memory file (http_compress_open)"); goto error; } closememfile++; /* Uncompress it */ status = 0; status = mem_uncompress2mem(url,diskfile,*handle); fclose(diskfile); closefdiskfile--; if (status) { ffpmsg("Error uncompressing disk file to memory (http_compress_open)"); ffpmsg(netoutfile); goto error; } } else { /* Opps, this should not have happened */ ffpmsg("Can only have compressed files here (http_compress_open)"); goto error; } signal(SIGALRM, SIG_DFL); alarm(0); return mem_seek(*handle,0); error: alarm(0); /* clear it */ if (closehttpfile) { fclose(httpfile); } if (closefdiskfile) { fclose(diskfile); } if (closememfile) { mem_close_free(*handle); } if (closediskfile) { file_close(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This creates a file handle with a copy of the URL in filename. The http file is copied to disk first. If it's compressed then it is uncompressed when copying to the disk */ int http_file_open(char *url, int rwmode, int *handle) { FILE *httpfile; char contentencoding[SHORTLEN]; char errorstr[MAXLEN]; char recbuf[MAXLEN]; long len; int contentlength; int ii, flen, status; char firstchar; /* Check if output file is actually a memory file */ if (!strncmp(netoutfile, "mem:", 4) ) { /* allow the memory file to be opened with write access */ return( http_open(url, READONLY, handle) ); } closehttpfile = 0; closefile = 0; closeoutfile = 0; /* cfileio made a mistake, we need to know where to write the file */ flen = strlen(netoutfile); if (!flen) { ffpmsg("Output file not set, shouldn't have happened (http_file_open)"); return (FILE_NOT_OPENED); } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); goto error; } signal(SIGALRM, signal_handler); /* Open the network connection */ alarm(NETTIMEOUT); if ((status = http_open_network(url,&httpfile,contentencoding, &contentlength))) { alarm(0); ffpmsg("Unable to open http file (http_file_open)"); ffpmsg(url); goto error; } closehttpfile++; if (*netoutfile == '!') { /* user wants to clobber disk file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ status = file_remove(netoutfile); } firstchar = fgetc(httpfile); ungetc(firstchar,httpfile); if (!strcmp(contentencoding,"x-gzip") || !strcmp(contentencoding,"x-compress") || ('\037' == firstchar)) { /* to make this more cfitsioish we use the file driver calls to create the disk file */ /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (http_file_open)"); ffpmsg(netoutfile); goto error; } file_close(*handle); if (NULL == (outfile = fopen(netoutfile,"w"))) { ffpmsg("Unable to reopen the output file (http_file_open)"); ffpmsg(netoutfile); goto error; } closeoutfile++; status = 0; /* Ok, this is a tough case, let's be arbritary and say 10*NETTIMEOUT, Given the choices for nettimeout above they'll probaby ^C before, but it's always worth a shot*/ alarm(NETTIMEOUT*10); status = uncompress2file(url,httpfile,outfile,&status); alarm(0); if (status) { ffpmsg("Error uncompressing http file to disk file (http_file_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } fclose(outfile); closeoutfile--; } else { /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (http_file_open)"); ffpmsg(netoutfile); goto error; } /* Give a warning message. This could just be bad padding at the end so don't treat it like an error. */ closefile++; if (contentlength % 2880) { sprintf(errorstr, "Content-Length not a multiple of 2880 (http_file_open) %d", contentlength); ffpmsg(errorstr); } /* write a file */ alarm(NETTIMEOUT); while(0 != (len = fread(recbuf,1,MAXLEN,httpfile))) { alarm(0); status = file_write(*handle,recbuf,len); if (status) { ffpmsg("Error copying http file to disk file (http_file_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } } file_close(*handle); closefile--; } fclose(httpfile); closehttpfile--; signal(SIGALRM, SIG_DFL); alarm(0); return file_open(netoutfile,rwmode,handle); error: alarm(0); /* clear it */ if (closehttpfile) { fclose(httpfile); } if (closeoutfile) { fclose(outfile); } if (closefile) { file_close(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This is the guts of the code to get a file via http. url is the input url httpfile is set to be the file connected to the socket which you can read the file from contentencoding is the mime type of the file, returned if the http server returns it contentlength is the lenght of the file, returned if the http server returns it */ static int http_open_network(char *url, FILE **httpfile, char *contentencoding, int *contentlength) { int status; int sock; int tmpint; char recbuf[MAXLEN]; char tmpstr[MAXLEN]; char tmpstr1[SHORTLEN]; char errorstr[MAXLEN]; char proto[SHORTLEN]; char host[SHORTLEN]; char fn[MAXLEN]; char turl[MAXLEN]; char *scratchstr; int port; float version; char pproto[SHORTLEN]; char phost[SHORTLEN]; /* address of the proxy server */ int pport; /* port number of the proxy server */ char pfn[MAXLEN]; char *proxy; /* URL of the proxy server */ /* Parse the URL apart again */ strcpy(turl,"http://"); strcat(turl,url); if (NET_ParseUrl(turl,proto,host,&port,fn)) { sprintf(errorstr,"URL Parse Error (http_open) %s",url); ffpmsg(errorstr); return (FILE_NOT_OPENED); } /* Ph. Prugniel 2003/04/03 Are we using a proxy? We use a proxy if the environment variable "http_proxy" is set to an address, eg. http://wwwcache.nottingham.ac.uk:3128 ("http_proxy" is also used by wget) */ proxy = getenv("http_proxy"); /* Connect to the remote host */ if (proxy) { if (NET_ParseUrl(proxy,pproto,phost,&pport,pfn)) { sprintf(errorstr,"URL Parse Error (http_open) %s",proxy); ffpmsg(errorstr); return (FILE_NOT_OPENED); } sock = NET_TcpConnect(phost,pport); } else sock = NET_TcpConnect(host,port); if (sock < 0) { if (proxy) { ffpmsg("Couldn't connect to host via proxy server (http_open_network)"); ffpmsg(proxy); } return (FILE_NOT_OPENED); } /* Make the socket a stdio file */ if (NULL == (*httpfile = fdopen(sock,"r"))) { ffpmsg ("fdopen failed to convert socket to file (http_open_network)"); close(sock); return (FILE_NOT_OPENED); } /* Send the GET request to the remote server */ /* Ph. Prugniel 2003/04/03 One must add the Host: command because of HTTP 1.1 servers (ie. virtual hosts) */ if (proxy) sprintf(tmpstr,"GET http://%s:%-d%s HTTP/1.0\n",host,port,fn); else sprintf(tmpstr,"GET %s HTTP/1.0\n",fn); sprintf(tmpstr1,"User-Agent: HEASARC/CFITSIO/%-8.3f\n",ffvers(&version)); strcat(tmpstr,tmpstr1); /* HTTP 1.1 servers require the following 'Host: ' string */ sprintf(tmpstr1,"Host: %s:%-d\n\n",host,port); strcat(tmpstr,tmpstr1); status = NET_SendRaw(sock,tmpstr,strlen(tmpstr),NET_DEFAULT); /* read the header */ if (!(fgets(recbuf,MAXLEN,*httpfile))) { sprintf (errorstr,"http header short (http_open_network) %s",recbuf); ffpmsg(errorstr); fclose(*httpfile); return (FILE_NOT_OPENED); } *contentlength = 0; contentencoding[0] = '\0'; /* Our choices are 200, ok, 301, temporary redirect, or 302 perm redirect */ sscanf(recbuf,"%s %d",tmpstr,&status); if (status != 200){ if (status == 301 || status == 302) { /* got a redirect */ if (status == 301) { ffpmsg("Note: Web server replied with a temporary redirect from"); } else { ffpmsg("Note: Web server replied with a redirect from"); } ffpmsg(turl); /* now, let's not write the most sophisticated parser here */ while (fgets(recbuf,MAXLEN,*httpfile)) { scratchstr = strstr(recbuf," 3) { recbuf[strlen(recbuf)-1] = '\0'; recbuf[strlen(recbuf)-1] = '\0'; } sscanf(recbuf,"%s %d",tmpstr,&tmpint); /* Did we get a content-length header ? */ if (!strcmp(tmpstr,"Content-Length:")) { *contentlength = tmpint; } /* Did we get the content-encoding header ? */ if (!strcmp(tmpstr,"Content-Encoding:")) { if (NULL != (scratchstr = strstr(recbuf,":"))) { /* Found the : */ scratchstr++; /* skip the : */ scratchstr++; /* skip the extra space */ strcpy(contentencoding,scratchstr); } } } /* we're done, so return */ return 0; } /*--------------------------------------------------------------------------*/ /* This creates a memory file handle with a copy of the URL in filename. The file is uncompressed if necessary */ int ftp_open(char *filename, int rwmode, int *handle) { FILE *ftpfile; FILE *command; int sock; char newfilename[MAXLEN]; char recbuf[MAXLEN]; long len; int status; char firstchar; closememfile = 0; closecommandfile = 0; closeftpfile = 0; /* don't do r/w files */ if (rwmode != 0) { ffpmsg("Can't open ftp:// type file with READWRITE access"); ffpmsg("Specify an outfile for r/w access (ftp_open)"); return (FILE_NOT_OPENED); } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); goto error; } signal(SIGALRM, signal_handler); /* Open the ftp connetion. ftpfile is connected to the file port, command is connected to port 21. sock is the socket on port 21 */ alarm(NETTIMEOUT); strcpy(newfilename,filename); /* Does the file have a .Z or .gz in it */ if (strstr(newfilename,".Z") || strstr(newfilename,".gz")) { alarm(NETTIMEOUT); if (ftp_open_network(filename,&ftpfile,&command,&sock)) { alarm(0); ffpmsg("Unable to open ftp file (ftp_open)"); ffpmsg(filename); goto error; } } else { /* Try the .gz one */ strcpy(newfilename,filename); strcat(newfilename,".gz"); alarm(NETTIMEOUT); if (ftp_open_network(newfilename,&ftpfile,&command,&sock)) { alarm(0); strcpy(newfilename,filename); strcat(newfilename,".Z"); alarm(NETTIMEOUT); if (ftp_open_network(newfilename,&ftpfile,&command,&sock)) { /* Now as given */ alarm(0); strcpy(newfilename,filename); alarm(NETTIMEOUT); if (ftp_open_network(newfilename,&ftpfile,&command,&sock)) { alarm(0); ffpmsg("Unable to open ftp file (ftp_open)"); ffpmsg(newfilename); goto error; } } } } closeftpfile++; closecommandfile++; /* create the memory file */ if ((status = mem_create(filename,handle))) { ffpmsg ("Could not create memory file to passive port (ftp_open)"); ffpmsg(filename); goto error; } closememfile++; /* This isn't quite right, it'll fail if the file has .gzabc at the end for instance */ /* Decide if the file is compressed */ firstchar = fgetc(ftpfile); ungetc(firstchar,ftpfile); if (strstr(newfilename,".gz") || strstr(newfilename,".Z") || ('\037' == firstchar)) { status = 0; /* A bit arbritary really, the user will probably hit ^C */ alarm(NETTIMEOUT*10); status = mem_uncompress2mem(filename, ftpfile, *handle); alarm(0); if (status) { ffpmsg("Error writing compressed memory file (ftp_open)"); ffpmsg(filename); goto error; } } else { /* write a memory file */ alarm(NETTIMEOUT); while(0 != (len = fread(recbuf,1,MAXLEN,ftpfile))) { alarm(0); status = mem_write(*handle,recbuf,len); if (status) { ffpmsg("Error writing memory file (http_open)"); ffpmsg(filename); goto error; } alarm(NETTIMEOUT); } } /* close and clean up */ fclose(ftpfile); closeftpfile--; NET_SendRaw(sock,"QUIT\n",5,NET_DEFAULT); fclose(command); closecommandfile--; signal(SIGALRM, SIG_DFL); alarm(0); return mem_seek(*handle,0); error: alarm(0); /* clear it */ if (closecommandfile) { fclose(command); } if (closeftpfile) { fclose(ftpfile); } if (closememfile) { mem_close_free(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This creates a file handle with a copy of the URL in filename. The file must be uncompressed and is copied to disk first */ int ftp_file_open(char *url, int rwmode, int *handle) { FILE *ftpfile; FILE *command; char recbuf[MAXLEN]; long len; int sock; int ii, flen, status; char firstchar; /* Check if output file is actually a memory file */ if (!strncmp(netoutfile, "mem:", 4) ) { /* allow the memory file to be opened with write access */ return( ftp_open(url, READONLY, handle) ); } closeftpfile = 0; closecommandfile = 0; closefile = 0; closeoutfile = 0; /* cfileio made a mistake, need to know where to write the output file */ flen = strlen(netoutfile); if (!flen) { ffpmsg("Output file not set, shouldn't have happened (ftp_file_open)"); return (FILE_NOT_OPENED); } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); goto error; } signal(SIGALRM, signal_handler); /* open the network connection to url. ftpfile holds the connection to the input file, command holds the connection to port 21, and sock is the socket connected to port 21 */ alarm(NETTIMEOUT); if ((status = ftp_open_network(url,&ftpfile,&command,&sock))) { alarm(0); ffpmsg("Unable to open http file (ftp_file_open)"); ffpmsg(url); goto error; } closeftpfile++; closecommandfile++; if (*netoutfile == '!') { /* user wants to clobber file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ status = file_remove(netoutfile); } /* Now, what do we do with the file */ firstchar = fgetc(ftpfile); ungetc(firstchar,ftpfile); if (strstr(url,".gz") || strstr(url,".Z") || ('\037' == firstchar)) { /* to make this more cfitsioish we use the file driver calls to create the file */ /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (ftp_file_open)"); ffpmsg(netoutfile); goto error; } file_close(*handle); if (NULL == (outfile = fopen(netoutfile,"w"))) { ffpmsg("Unable to reopen the output file (ftp_file_open)"); ffpmsg(netoutfile); goto error; } closeoutfile++; status = 0; /* Ok, this is a tough case, let's be arbritary and say 10*NETTIMEOUT, Given the choices for nettimeout above they'll probaby ^C before, but it's always worth a shot*/ alarm(NETTIMEOUT*10); status = uncompress2file(url,ftpfile,outfile,&status); alarm(0); if (status) { ffpmsg("Unable to uncompress the output file (ftp_file_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } fclose(outfile); closeoutfile--; } else { /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (ftp_file_open)"); ffpmsg(netoutfile); goto error; } closefile++; /* write a file */ alarm(NETTIMEOUT); while(0 != (len = fread(recbuf,1,MAXLEN,ftpfile))) { alarm(0); status = file_write(*handle,recbuf,len); if (status) { ffpmsg("Error writing file (ftp_file_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } alarm(NETTIMEOUT); } file_close(*handle); } fclose(ftpfile); closeftpfile--; NET_SendRaw(sock,"QUIT\n",5,NET_DEFAULT); fclose(command); closecommandfile--; signal(SIGALRM, SIG_DFL); alarm(0); return file_open(netoutfile,rwmode,handle); error: alarm(0); /* clear it */ if (closeftpfile) { fclose(ftpfile); } if (closecommandfile) { fclose(command); } if (closeoutfile) { fclose(outfile); } if (closefile) { file_close(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* This creates a memory handle with a copy of the URL in filename. The file must be compressed and is copied to disk first */ int ftp_compress_open(char *url, int rwmode, int *handle) { FILE *ftpfile; FILE *command; char recbuf[MAXLEN]; long len; int ii, flen, status; int sock; char firstchar; closeftpfile = 0; closecommandfile = 0; closememfile = 0; closefdiskfile = 0; closediskfile = 0; /* don't do r/w files */ if (rwmode != 0) { ffpmsg("Compressed files must be r/o"); return (FILE_NOT_OPENED); } /* Need to know where to write the output file */ flen = strlen(netoutfile); if (!flen) { ffpmsg( "Output file not set, shouldn't have happened (ftp_compress_open)"); return (FILE_NOT_OPENED); } /* do the signal handler bits */ if (setjmp(env) != 0) { /* feels like the second time */ /* this means something bad happened */ ffpmsg("Timeout (http_open)"); goto error; } signal(SIGALRM, signal_handler); /* Open the network connection to url, ftpfile is connected to the file port, command is connected to port 21. sock is for writing to port 21 */ alarm(NETTIMEOUT); if ((status = ftp_open_network(url,&ftpfile,&command,&sock))) { alarm(0); ffpmsg("Unable to open ftp file (ftp_compress_open)"); ffpmsg(url); goto error; } closeftpfile++; closecommandfile++; /* Now, what do we do with the file */ firstchar = fgetc(ftpfile); ungetc(firstchar,ftpfile); if (strstr(url,".gz") || strstr(url,".Z") || ('\037' == firstchar)) { if (*netoutfile == '!') { /* user wants to clobber file, if it already exists */ for (ii = 0; ii < flen; ii++) netoutfile[ii] = netoutfile[ii + 1]; /* remove '!' */ status = file_remove(netoutfile); } /* Create the output file */ if ((status = file_create(netoutfile,handle))) { ffpmsg("Unable to create output file (ftp_compress_open)"); ffpmsg(netoutfile); goto error; } closediskfile++; /* write a file */ alarm(NETTIMEOUT); while(0 != (len = fread(recbuf,1,MAXLEN,ftpfile))) { alarm(0); status = file_write(*handle,recbuf,len); if (status) { ffpmsg("Error writing file (ftp_compres_open)"); ffpmsg(url); ffpmsg(netoutfile); goto error; } alarm(NETTIMEOUT); } file_close(*handle); closediskfile--; fclose(ftpfile); closeftpfile--; /* Close down the ftp connection */ NET_SendRaw(sock,"QUIT\n",5,NET_DEFAULT); fclose(command); closecommandfile--; /* File is on disk, let's uncompress it into memory */ if (NULL == (diskfile = fopen(netoutfile,"r"))) { ffpmsg("Unable to reopen disk file (ftp_compress_open)"); ffpmsg(netoutfile); return (FILE_NOT_OPENED); } closefdiskfile++; if ((status = mem_create(url,handle))) { ffpmsg("Unable to create memory file (ftp_compress_open)"); ffpmsg(url); goto error; } closememfile++; status = 0; status = mem_uncompress2mem(url,diskfile,*handle); fclose(diskfile); closefdiskfile--; if (status) { ffpmsg("Error writing compressed memory file (ftp_compress_open)"); goto error; } } else { /* Opps, this should not have happened */ ffpmsg("Can only compressed files here (ftp_compress_open)"); goto error; } signal(SIGALRM, SIG_DFL); alarm(0); return mem_seek(*handle,0); error: alarm(0); /* clear it */ if (closeftpfile) { fclose(ftpfile); } if (closecommandfile) { fclose(command); } if (closefdiskfile) { fclose(diskfile); } if (closememfile) { mem_close_free(*handle); } if (closediskfile) { file_close(*handle); } signal(SIGALRM, SIG_DFL); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* Open a ftp connection to filename (really a URL), return ftpfile set to the file connection, and command set to the control connection, with sock also set to the control connection */ int ftp_open_network(char *filename, FILE **ftpfile, FILE **command, int *sock) { int status; int sock1; int tmpint; char recbuf[MAXLEN]; char errorstr[MAXLEN]; char tmpstr[MAXLEN]; char proto[SHORTLEN]; char host[SHORTLEN]; char *newhost; char *username; char *password; char fn[MAXLEN]; char *newfn; char *passive; char *tstr; char ip[SHORTLEN]; char turl[MAXLEN]; int port; /* parse the URL */ strcpy(turl,"ftp://"); strcat(turl,filename); if (NET_ParseUrl(turl,proto,host,&port,fn)) { sprintf(errorstr,"URL Parse Error (ftp_open) %s",filename); ffpmsg(errorstr); return (FILE_NOT_OPENED); } #ifdef DEBUG printf ("proto, %s, host, %s, port %d, fn %s\n",proto,host,port,fn); #endif port = 21; /* we might have a user name */ username = "anonymous"; password = "user@host.com"; /* is there an @ sign */ if (NULL != (newhost = strrchr(host,'@'))) { *newhost = '\0'; /* make it a null, */ newhost++; /* Now newhost points to the host name and host points to the user name, password combo */ username = host; /* is there a : for a password */ if (NULL != strchr(username,':')) { password = strchr(username,':'); *password = '\0'; password++; } } else { newhost = host; } #ifdef DEBUG printf("User %s pass %s\n",username,password); #endif /* Connect to the host on the required port */ *sock = NET_TcpConnect(newhost,port); /* convert it to a stdio file */ if (NULL == (*command = fdopen(*sock,"r"))) { ffpmsg ("fdopen failed to convert socket to stdio file (ftp_open)"); return (FILE_NOT_OPENED); } /* Wait for the 220 response */ if (ftp_status(*command,"220 ")) { ffpmsg ("error connecting to remote server, no 220 seen (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } /* Send the user name and wait for the right response */ sprintf(tmpstr,"USER %s\n",username); status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(*command,"331 ")) { ffpmsg ("USER error no 331 seen (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } /* Send the password and wait for the right response */ sprintf(tmpstr,"PASS %s\n",password); status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(*command,"230 ")) { ffpmsg ("PASS error, no 230 seen (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } /* now do the cwd command */ newfn = strrchr(fn,'/'); if (newfn == NULL) { strcpy(tmpstr,"CWD /\n"); newfn = fn; } else { *newfn = '\0'; newfn++; if (strlen(fn) == 0) { strcpy(tmpstr,"CWD /\n"); } else { /* remove the leading slash */ if (fn[0] == '/') { sprintf(tmpstr,"CWD %s\n",&fn[1]); } else { sprintf(tmpstr,"CWD %s\n",fn); } } } #ifdef DEBUG printf("CWD command is %s\n",tmpstr); #endif status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(*command,"250 ")) { ffpmsg ("CWD error, no 250 seen (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } if (!strlen(newfn)) { ffpmsg("Null file name (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } /* Always use binary mode */ sprintf(tmpstr,"TYPE I\n"); status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); if (ftp_status(*command,"200 ")) { ffpmsg ("TYPE I error, 200 not seen (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } status = NET_SendRaw(*sock,"PASV\n",5,NET_DEFAULT); if (!(fgets(recbuf,MAXLEN,*command))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } /* Passive mode response looks like 227 Entering Passive Mode (129,194,67,8,210,80) */ if (recbuf[0] == '2' && recbuf[1] == '2' && recbuf[2] == '7') { /* got a good passive mode response, find the opening ( */ if (!(passive = strchr(recbuf,'('))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } *passive = '\0'; passive++; ip[0] = '\0'; /* Messy parsing of response from PASV *command */ if (!(tstr = strtok(passive,",)"))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } strcpy(ip,tstr); strcat(ip,"."); if (!(tstr = strtok(NULL,",)"))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } strcat(ip,tstr); strcat(ip,"."); if (!(tstr = strtok(NULL,",)"))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } strcat(ip,tstr); strcat(ip,"."); if (!(tstr = strtok(NULL,",)"))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } strcat(ip,tstr); /* Done the ip number, now do the port # */ if (!(tstr = strtok(NULL,",)"))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } sscanf(tstr,"%d",&port); port *= 256; if (!(tstr = strtok(NULL,",)"))) { ffpmsg ("PASV error (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } sscanf(tstr,"%d",&tmpint); port += tmpint; if (!strlen(newfn)) { ffpmsg("Null file name (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } #ifdef DEBUG puts("connection to passive port"); #endif /* COnnect to the data port */ sock1 = NET_TcpConnect(ip,port); if (NULL == (*ftpfile = fdopen(sock1,"r"))) { ffpmsg ("Could not connect to passive port (ftp_open)"); fclose(*command); return (FILE_NOT_OPENED); } /* now we return */ /* Send the retrieve command */ sprintf(tmpstr,"RETR %s\n",newfn); status = NET_SendRaw(*sock,tmpstr,strlen(tmpstr),NET_DEFAULT); #ifdef DEBUG puts("Sent RETR command"); #endif if (ftp_status(*command,"150 ")) { ffpmsg ("RETR error, most likely file is not there (ftp_open)"); fclose(*command); #ifdef DEBUG puts("File not there"); #endif return (FILE_NOT_OPENED); } return 0; } /* no passive mode */ NET_SendRaw(*sock,"QUIT\n",5,NET_DEFAULT); fclose(*command); return (FILE_NOT_OPENED); } /*--------------------------------------------------------------------------*/ /* return a socket which results from connection to hostname on port port */ static int NET_TcpConnect(char *hostname, int port) { /* Connect to hostname on port */ struct sockaddr_in sockaddr; int sock; int stat; int val = 1; CreateSocketAddress(&sockaddr,hostname,port); /* Create socket */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { ffpmsg("Can't create socket"); return CONNECTION_ERROR; } if ((stat = connect(sock, (struct sockaddr*) &sockaddr, sizeof(sockaddr))) < 0) { close(sock); /* perror("NET_Tcpconnect - Connection error"); ffpmsg("Can't connect to host, connection error"); */ return CONNECTION_ERROR; } setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&val, sizeof(val)); val = 65536; setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&val, sizeof(val)); setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&val, sizeof(val)); return sock; } /*--------------------------------------------------------------------------*/ /* Write len bytes from buffer to socket sock */ static int NET_SendRaw(int sock, const void *buffer, int length, int opt) { char * buf = (char *) buffer; int flag; int n, nsent = 0; switch (opt) { case NET_DEFAULT: flag = 0; break; case NET_OOB: flag = MSG_OOB; break; case NET_PEEK: default: flag = 0; break; } if (sock < 0) return -1; for (n = 0; n < length; n += nsent) { if ((nsent = send(sock, buf+n, length-n, flag)) <= 0) { return nsent; } #ifdef DEBUG printf ("send raw, sent %d bytes\n",nsent); #endif } #ifdef DEBUG printf ("send raw end, sent %d bytes\n",n); #endif return n; } /*--------------------------------------------------------------------------*/ static int NET_RecvRaw(int sock, void *buffer, int length) { /* Receive exactly length bytes into buffer. Returns number of bytes */ /* received. Returns -1 in case of error. */ int nrecv, n; char *buf = (char *)buffer; if (sock < 0) return -1; for (n = 0; n < length; n += nrecv) { while ((nrecv = recv(sock, buf+n, length-n, 0)) == -1 && errno == EINTR) errno = 0; /* probably a SIGCLD that was caught */ if (nrecv < 0) return nrecv; else if (nrecv == 0) break; /*/ EOF */ } return n; } /*--------------------------------------------------------------------------*/ /* Yet Another URL Parser url - input url proto - input protocol host - output host port - output port fn - output filename */ static int NET_ParseUrl(const char *url, char *proto, char *host, int *port, char *fn) { /* parses urls into their bits */ /* returns 1 if error, else 0 */ char *urlcopy, *urlcopyorig; char *ptrstr; char *thost; int isftp = 0; /* figure out if there is a http: or ftp: */ urlcopyorig = urlcopy = (char *) malloc(strlen(url)+1); strcpy(urlcopy,url); /* set some defaults */ *port = 80; strcpy(proto,"http:"); strcpy(host,"localhost"); strcpy(fn,"/"); ptrstr = strstr(urlcopy,"http:"); if (ptrstr == NULL) { /* Nope, not http: */ ptrstr = strstr(urlcopy,"root:"); if (ptrstr == NULL) { /* Nope, not root either */ ptrstr = strstr(urlcopy,"ftp:"); if (ptrstr != NULL) { if (ptrstr == urlcopy) { strcpy(proto,"ftp:"); *port = 21; isftp++; urlcopy += 4; /* move past ftp: */ } else { /* not at the beginning, bad url */ free(urlcopyorig); return 1; } } } else { if (ptrstr == urlcopy) { urlcopy += 5; /* move past root: */ } else { /* not at the beginning, bad url */ free(urlcopyorig); return 1; } } } else { if (ptrstr == urlcopy) { urlcopy += 5; /* move past http: */ } else { free(urlcopyorig); return 1; } } /* got the protocol */ /* get the hostname */ if (urlcopy[0] == '/' && urlcopy[1] == '/') { /* we have a hostname */ urlcopy += 2; /* move past the // */ } /* do this only if http */ if (!strcmp(proto,"http:")) { strcpy(host,urlcopy); thost = host; while (*urlcopy != '/' && *urlcopy != ':' && *urlcopy) { thost++; urlcopy++; } /* we should either be at the end of the string, have a /, or have a : */ *thost = '\0'; if (*urlcopy == ':') { /* follows a port number */ urlcopy++; sscanf(urlcopy,"%d",port); while (*urlcopy != '/' && *urlcopy) urlcopy++; /* step to the */ } } else { /* do this for ftp */ strcpy(host,urlcopy); thost = host; while (*urlcopy != '/' && *urlcopy) { thost++; urlcopy++; } *thost = '\0'; /* Now, we should either be at the end of the string, or have a / */ } /* Now the rest is a fn */ if (*urlcopy) { strcpy(fn,urlcopy); } free(urlcopyorig); return 0; } /*--------------------------------------------------------------------------*/ /* Small helper functions to set the netoutfile static string */ /* Called by cfileio after parsing the output file off of the input file url */ int http_checkfile (char *urltype, char *infile, char *outfile1) { char newinfile[MAXLEN]; FILE *httpfile; char contentencoding[MAXLEN]; int contentlength; /* default to http:// if there is no output file */ strcpy(urltype,"http://"); if (strlen(outfile1)) { /* there is an output file */ /* don't copy the "file://" prefix, if present. */ if (!strncmp(outfile1, "file://", 7) ) strcpy(netoutfile,outfile1+7); else strcpy(netoutfile,outfile1); if (!strncmp(outfile1, "mem:", 4) ) { /* copy the file to memory, with READ and WRITE access In this case, it makes no difference whether the http file and or the output file are compressed or not. */ strcpy(urltype, "httpmem://"); /* use special driver */ return 0; } if (strstr(infile, "?")) { /* file name contains a '?' so probably a cgi string; don't open it */ strcpy(urltype,"httpfile://"); return 0; } if (!http_open_network(infile,&httpfile,contentencoding,&contentlength)) { fclose(httpfile); /* It's there, we're happy */ if (strstr(infile,".gz") || (strstr(infile,".Z"))) { /* It's compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"httpcompress://"); } else { strcpy(urltype,"httpfile://"); } } else { strcpy(urltype,"httpfile://"); } return 0; } /* Ok, let's try the .gz one */ strcpy(newinfile,infile); strcat(newinfile,".gz"); if (!http_open_network(newinfile,&httpfile,contentencoding, &contentlength)) { fclose(httpfile); strcpy(infile,newinfile); /* It's there, we're happy, and, it's compressed */ /* It's compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"httpcompress://"); } else { strcpy(urltype,"httpfile://"); } return 0; } /* Ok, let's try the .Z one */ strcpy(newinfile,infile); strcat(newinfile,".Z"); if (!http_open_network(newinfile,&httpfile,contentencoding, &contentlength)) { fclose(httpfile); strcpy(infile,newinfile); /* It's there, we're happy, and, it's compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"httpcompress://"); } else { strcpy(urltype,"httpfile://"); } return 0; } } return 0; } /*--------------------------------------------------------------------------*/ int ftp_checkfile (char *urltype, char *infile, char *outfile1) { char newinfile[MAXLEN]; FILE *ftpfile; FILE *command; int sock; /* default to ftp:// */ strcpy(urltype,"ftp://"); if (strlen(outfile1)) { /* there is an output file */ /* don't copy the "file://" prefix, if present. */ if (!strncmp(outfile1, "file://", 7) ) strcpy(netoutfile,outfile1+7); else strcpy(netoutfile,outfile1); if (!strncmp(outfile1, "mem:", 4) ) { /* copy the file to memory, with READ and WRITE access In this case, it makes no difference whether the ftp file and or the output file are compressed or not. */ strcpy(urltype, "ftpmem://"); /* use special driver */ return 0; } if (!ftp_open_network(infile,&ftpfile,&command,&sock)) { fclose(ftpfile); fclose(command); /* It's there, we're happy */ if (strstr(infile,".gz") || (strstr(infile,".Z"))) { /* It's compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"ftpcompress://"); } else { strcpy(urltype,"ftpfile://"); } } else { strcpy(urltype,"ftpfile://"); } return 0; } /* Ok, let's try the .gz one */ strcpy(newinfile,infile); strcat(newinfile,".gz"); if (!ftp_open_network(newinfile,&ftpfile,&command,&sock)) { fclose(ftpfile); fclose(command); strcpy(infile,newinfile); /* It's there, we're happy, and, it's compressed */ if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"ftpcompress://"); } else { strcpy(urltype,"ftpfile://"); } return 0; } /* Ok, let's try the .Z one */ strcpy(newinfile,infile); strcat(newinfile,".Z"); if (!ftp_open_network(newinfile,&ftpfile,&command,&sock)) { fclose(ftpfile); fclose(command); strcpy(infile,newinfile); if (strstr(outfile1,".gz") || (strstr(outfile1,".Z"))) { strcpy(urltype,"ftpcompress://"); } else { strcpy(urltype,"ftpfile://"); } return 0; } } return 0; } /*--------------------------------------------------------------------------*/ /* A small helper function to wait for a particular status on the ftp connectino */ static int ftp_status(FILE *ftp, char *statusstr) { /* read through until we find a string beginning with statusstr */ /* This needs a timeout */ char recbuf[MAXLEN]; int len; len = strlen(statusstr); while (1) { if (!(fgets(recbuf,MAXLEN,ftp))) { #ifdef DEBUG puts("error reading response in ftp_status"); #endif return 1; /* error reading */ } #ifdef DEBUG printf("ftp_status, return string was %s\n",recbuf); #endif recbuf[len] = '\0'; /* make it short */ if (!strcmp(recbuf,statusstr)) { return 0; /* we're ok */ } if (recbuf[0] > '3') { /* oh well, some sort of error */ return 1; } } } /* *---------------------------------------------------------------------- * * CreateSocketAddress -- * * This function initializes a sockaddr structure for a host and port. * * Results: * 1 if the host was valid, 0 if the host could not be converted to * an IP address. * * Side effects: * Fills in the *sockaddrPtr structure. * *---------------------------------------------------------------------- */ static int CreateSocketAddress( struct sockaddr_in *sockaddrPtr, /* Socket address */ char *host, /* Host. NULL implies INADDR_ANY */ int port) /* Port number */ { struct hostent *hostent; /* Host database entry */ struct in_addr addr; /* For 64/32 bit madness */ char localhost[MAXLEN]; strcpy(localhost,host); memset((void *) sockaddrPtr, '\0', sizeof(struct sockaddr_in)); sockaddrPtr->sin_family = AF_INET; sockaddrPtr->sin_port = htons((unsigned short) (port & 0xFFFF)); if (host == NULL) { addr.s_addr = INADDR_ANY; } else { addr.s_addr = inet_addr(localhost); if (addr.s_addr == 0xFFFFFFFF) { hostent = gethostbyname(localhost); if (hostent != NULL) { memcpy((void *) &addr, (void *) hostent->h_addr_list[0], (size_t) hostent->h_length); } else { #ifdef EHOSTUNREACH errno = EHOSTUNREACH; #else #ifdef ENXIO errno = ENXIO; #endif #endif return 0; /* error */ } } } /* * NOTE: On 64 bit machines the assignment below is rumored to not * do the right thing. Please report errors related to this if you * observe incorrect behavior on 64 bit machines such as DEC Alphas. * Should we modify this code to do an explicit memcpy? */ sockaddrPtr->sin_addr.s_addr = addr.s_addr; return 1; /* Success. */ } /* Signal handler for timeouts */ static void signal_handler(int sig) { switch (sig) { case SIGALRM: /* process for alarm */ longjmp(env,sig); default: { /* Hmm, shouldn't have happend */ exit(sig); } } } /**************************************************************/ /* Root driver */ /*--------------------------------------------------------------------------*/ int root_init(void) { int ii; for (ii = 0; ii < NMAXFILES; ii++) /* initialize all empty slots in table */ { handleTable[ii].sock = 0; handleTable[ii].currentpos = 0; } return(0); } /*--------------------------------------------------------------------------*/ int root_setoptions(int options) { /* do something with the options argument, to stop compiler warning */ options = 0; return(options); } /*--------------------------------------------------------------------------*/ int root_getoptions(int *options) { *options = 0; return(0); } /*--------------------------------------------------------------------------*/ int root_getversion(int *version) { *version = 10; return(0); } /*--------------------------------------------------------------------------*/ int root_shutdown(void) { return(0); } /*--------------------------------------------------------------------------*/ int root_open(char *url, int rwmode, int *handle) { int ii, status; int sock; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in table */ { if (handleTable[ii].sock == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ /*open the file */ if (rwmode) { status = root_openfile(url, "update", &sock); } else { status = root_openfile(url, "read", &sock); } if (status) return(status); handleTable[ii].sock = sock; handleTable[ii].currentpos = 0; return(0); } /*--------------------------------------------------------------------------*/ int root_create(char *filename, int *handle) { int ii, status; int sock; *handle = -1; for (ii = 0; ii < NMAXFILES; ii++) /* find empty slot in table */ { if (handleTable[ii].sock == 0) { *handle = ii; break; } } if (*handle == -1) return(TOO_MANY_FILES); /* too many files opened */ /*open the file */ status = root_openfile(filename, "create", &sock); if (status) { ffpmsg("Unable to create file"); return(status); } handleTable[ii].sock = sock; handleTable[ii].currentpos = 0; return(0); } /*--------------------------------------------------------------------------*/ int root_size(int handle, LONGLONG *filesize) /* return the size of the file in bytes */ { int sock; int offset; int status; int op; sock = handleTable[handle].sock; status = root_send_buffer(sock,ROOTD_STAT,NULL,0); status = root_recv_buffer(sock,&op,(char *)&offset, 4); *filesize = (LONGLONG) ntohl(offset); return(0); } /*--------------------------------------------------------------------------*/ int root_close(int handle) /* close the file */ { int status; int sock; sock = handleTable[handle].sock; status = root_send_buffer(sock,ROOTD_CLOSE,NULL,0); close(sock); handleTable[handle].sock = 0; return(0); } /*--------------------------------------------------------------------------*/ int root_flush(int handle) /* flush the file */ { int status; int sock; sock = handleTable[handle].sock; status = root_send_buffer(sock,ROOTD_FLUSH,NULL,0); return(0); } /*--------------------------------------------------------------------------*/ int root_seek(int handle, LONGLONG offset) /* seek to position relative to start of the file */ { handleTable[handle].currentpos = offset; return(0); } /*--------------------------------------------------------------------------*/ int root_read(int hdl, void *buffer, long nbytes) /* read bytes from the current position in the file */ { char msg[SHORTLEN]; int op; int status; int astat; /* we presume here that the file position will never be > 2**31 = 2.1GB */ sprintf(msg,"%ld %ld ",(long) handleTable[hdl].currentpos,nbytes); status = root_send_buffer(handleTable[hdl].sock,ROOTD_GET,msg,strlen(msg)); if ((unsigned) status != strlen(msg)) { return (READ_ERROR); } astat = 0; status = root_recv_buffer(handleTable[hdl].sock,&op,(char *) &astat,4); if (astat != 0) { return (READ_ERROR); } #ifdef DEBUG printf("root_read, op %d astat %d\n",op,astat); #endif status = NET_RecvRaw(handleTable[hdl].sock,buffer,nbytes); if (status != nbytes) { return (READ_ERROR); } handleTable[hdl].currentpos += nbytes; return(0); } /*--------------------------------------------------------------------------*/ int root_write(int hdl, void *buffer, long nbytes) /* write bytes at the current position in the file */ { char msg[SHORTLEN]; int len; int sock; int status; int astat; int op; sock = handleTable[hdl].sock; /* we presume here that the file position will never be > 2**31 = 2.1GB */ sprintf(msg,"%ld %ld ",(long) handleTable[hdl].currentpos,nbytes); len = strlen(msg); status = root_send_buffer(sock,ROOTD_PUT,msg,len+1); if (status != len+1) { return (WRITE_ERROR); } status = NET_SendRaw(sock,buffer,nbytes,NET_DEFAULT); if (status != nbytes) { return (WRITE_ERROR); } astat = 0; status = root_recv_buffer(handleTable[hdl].sock,&op,(char *) &astat,4); #ifdef DEBUG printf("root_read, op %d astat %d\n",op,astat); #endif if (astat != 0) { return (WRITE_ERROR); } handleTable[hdl].currentpos += nbytes; return(0); } /*--------------------------------------------------------------------------*/ int root_openfile(char *url, char *rwmode, int *sock) /* lowest level routine to physically open a root file */ { int status; char recbuf[MAXLEN]; char errorstr[MAXLEN]; char proto[SHORTLEN]; char host[SHORTLEN]; char fn[MAXLEN]; char turl[MAXLEN]; int port; int op; int ii; int authstat; /* Parse the URL apart again */ strcpy(turl,"root://"); strcat(turl,url); if (NET_ParseUrl(turl,proto,host,&port,fn)) { sprintf(errorstr,"URL Parse Error (root_open) %s",url); ffpmsg(errorstr); return (FILE_NOT_OPENED); } #ifdef DEBUG printf("Connecting to %s on port %d\n",host,port); #endif /* Connect to the remote host */ *sock = NET_TcpConnect(host,port); if (*sock < 0) { ffpmsg("Couldn't connect to host (http_open_network)"); return (FILE_NOT_OPENED); } /* get the username */ if (NULL != getenv("ROOTUSERNAME")) { strcpy(recbuf,getenv("ROOTUSERNAME")); } else { printf("Username: "); fgets(recbuf,MAXLEN,stdin); recbuf[strlen(recbuf)-1] = '\0'; } status = root_send_buffer(*sock, ROOTD_USER, recbuf,strlen(recbuf)); if (status < 0) { ffpmsg("error talking to remote system on username "); return (FILE_NOT_OPENED); } status = root_recv_buffer(*sock,&op,(char *)&authstat,4); if (!status) { ffpmsg("error talking to remote system on username"); return (FILE_NOT_OPENED); } #ifdef DEBUG printf("op is %d and authstat is %d\n",op,authstat); #endif if (op != ROOTD_AUTH) { ffpmsg("ERROR on ROOTD_USER"); ffpmsg(recbuf); return (FILE_NOT_OPENED); } /* now the password */ if (NULL != getenv("ROOTPASSWORD")) { strcpy(recbuf,getenv("ROOTPASSWORD")); } else { printf("Password: "); fgets(recbuf,MAXLEN,stdin); recbuf[strlen(recbuf)-1] = '\0'; } /* ones complement the password */ for (ii=0;(unsigned) ii includes the 4 bytes for the op, the length bytes (4) are implicit if buffer is null don't send it, not everything needs something sent */ int len; int status; int hdr[2]; len = 4; if (buffer != NULL) { len += buflen; } hdr[0] = htonl(len); #ifdef DEBUG printf("len sent is %x\n",hdr[0]); #endif hdr[1] = htonl(op); #ifdef DEBUG printf("op sent is %x\n",hdr[1]); #endif #ifdef DEBUG printf("Sending op %d and length of %d\n",op,len); #endif status = NET_SendRaw(sock,hdr,sizeof(hdr),NET_DEFAULT); if (status < 0) { return status; } if (buffer != NULL) { status = NET_SendRaw(sock,buffer,buflen,NET_DEFAULT); } return status; } static int root_recv_buffer(int sock, int *op, char *buffer, int buflen) { /* recv a buffer, the form is */ int recv1 = 0; int len; int status; char recbuf[MAXLEN]; status = NET_RecvRaw(sock,&len,4); #ifdef DEBUG printf("Recv: status from rec is %d\n",status); #endif if (status < 0) { return status; } recv1 += status; len = ntohl(len); #ifdef DEBUG printf ("Recv: length is %d\n",len); #endif /* ok, have the length, recive the operation */ len -= 4; status = NET_RecvRaw(sock,op,4); if (status < 0) { return status; } recv1 += status; *op = ntohl(*op); #ifdef DEBUG printf ("Recv: Operation is %d\n",*op); #endif if (len > MAXLEN) { len = MAXLEN; } if (len > 0) { /* Get the rest of the message */ status = NET_RecvRaw(sock,recbuf,len); if (len > buflen) { len = buflen; } memcpy(buffer,recbuf,len); if (status < 0) { return status; } } recv1 += status; return recv1; } #endif indi-0.5/src/cfitsio/swapproc.c0000644000175000017500000001353410610474375014357 0ustar jrjr/* Copyright (Unpublished-all rights reserved under the copyright laws of the United States), U.S. Government as represented by the Administrator of the National Aeronautics and Space Administration. No copyright is claimed in the United States under Title 17, U.S. Code. Permission to freely use, copy, modify, and distribute this software and its documentation without fee is hereby granted, provided that this copyright notice and disclaimer of warranty appears in all copies. (However, see the restriction on the use of the gzip compression code, below). e-mail: pence@tetra.gsfc.nasa.gov DISCLAIMER: THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NASA BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT , OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER." The file compress.c contains (slightly modified) source code that originally came from gzip-1.2.4, copyright (C) 1992-1993 by Jean-loup Gailly. This gzip code is distributed under the GNU General Public License and thus requires that any software that uses the CFITSIO library (which in turn uses the gzip code) must conform to the provisions in the GNU General Public License. A copy of the GNU license is included at the beginning of compress.c file. Similarly, the file wcsutil.c contains 2 slightly modified routines from the Classic AIPS package that are also distributed under the GNU General Public License. Alternate versions of the compress.c and wcsutil.c files (called compress_alternate.c and wcsutil_alternate.c) are provided for users who want to use the CFITSIO library but are unwilling or unable to publicly release their software under the terms of the GNU General Public License. These alternate versions contains non-functional stubs for the file compression and uncompression routines and the world coordinate transformation routines used by CFITSIO. Replace the file `compress.c' with `compress_alternate.c' and 'wcsutil.c' with 'wcsutil_alternate.c before compiling the CFITSIO library. This will produce a version of CFITSIO which does not support reading or writing compressed FITS files, or doing image coordinate transformations, but is otherwise identical to the standard version. */ /* This file, swapproc.c, contains general utility routines that are */ /* used by other FITSIO routines to swap bytes. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ void ffswap2(short *svalues, /* IO - pointer to shorts to be swapped */ long nvals) /* I - number of shorts to be swapped */ /* swap the bytes in the input short integers: ( 0 1 -> 1 0 ) */ { register char *cvalues; register long ii; union u_tag { char cvals[2]; /* equivalence an array of 4 bytes with */ short sval; /* a short */ } u; cvalues = (char *) svalues; /* copy the initial pointer value */ for (ii = 0; ii < nvals;) { u.sval = svalues[ii++]; /* copy next short to temporary buffer */ *cvalues++ = u.cvals[1]; /* copy the 2 bytes to output in turn */ *cvalues++ = u.cvals[0]; } return; } /*--------------------------------------------------------------------------*/ void ffswap4(INT32BIT *ivalues, /* IO - pointer to floats to be swapped */ long nvals) /* I - number of floats to be swapped */ /* swap the bytes in the input 4-byte integer: ( 0 1 2 3 -> 3 2 1 0 ) */ { register char *cvalues; register long ii; union u_tag { char cvals[4]; /* equivalence an array of 4 bytes with */ INT32BIT ival; /* a float */ } u; cvalues = (char *) ivalues; /* copy the initial pointer value */ for (ii = 0; ii < nvals;) { u.ival = ivalues[ii++]; /* copy next float to buffer */ *cvalues++ = u.cvals[3]; /* copy the 4 bytes in turn */ *cvalues++ = u.cvals[2]; *cvalues++ = u.cvals[1]; *cvalues++ = u.cvals[0]; } return; } /*--------------------------------------------------------------------------*/ void ffswap8(double *dvalues, /* IO - pointer to doubles to be swapped */ long nvals) /* I - number of doubles to be swapped */ /* swap the bytes in the input doubles: ( 01234567 -> 76543210 ) */ { register char *cvalues; register long ii; register char temp; cvalues = (char *) dvalues; /* copy the pointer value */ for (ii = 0; ii < nvals*8; ii += 8) { temp = cvalues[ii]; cvalues[ii] = cvalues[ii+7]; cvalues[ii+7] = temp; temp = cvalues[ii+1]; cvalues[ii+1] = cvalues[ii+6]; cvalues[ii+6] = temp; temp = cvalues[ii+2]; cvalues[ii+2] = cvalues[ii+5]; cvalues[ii+5] = temp; temp = cvalues[ii+3]; cvalues[ii+3] = cvalues[ii+4]; cvalues[ii+4] = temp; } return; } indi-0.5/src/cfitsio/fitsio.h0000644000175000017500000027555610610474402014030 0ustar jrjr/* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ /* Copyright (Unpublished--all rights reserved under the copyright laws of the United States), U.S. Government as represented by the Administrator of the National Aeronautics and Space Administration. No copyright is claimed in the United States under Title 17, U.S. Code. Permission to freely use, copy, modify, and distribute this software and its documentation without fee is hereby granted, provided that this copyright notice and disclaimer of warranty appears in all copies. DISCLAIMER: THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NASA BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT , OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER." */ #ifndef _FITSIO_H #define _FITSIO_H #define CFITSIO_VERSION 3.03 #include /* the following was provided by Michael Greason (GSFC) to fix a */ /* C/Fortran compatibility problem on an SGI Altix system running */ /* SGI ProPack 4 [this is a Novell SuSE Enterprise 9 derivative] */ /* and using the Intel C++ and Fortran compilers (version 9.1) */ #if defined(__INTEL_COMPILER) && defined(__itanium__) # define mipsFortran 1 # define _MIPS_SZLONG 64 #endif #if defined(linux) || defined(__APPLE__) || defined(__sgi) # include /* apparently needed on debian linux systems */ #endif /* to define off_t */ #include /* apparently needed to define size_t with gcc 2.8.1 */ #include /* needed for LLONG_MAX and INT64_MAX definitions */ /* Define the datatype for variables which store file offset values. */ /* The newer 'off_t' datatype should be used for this purpose, but some */ /* older compilers do not recognize this type, in which case we use 'long' */ /* instead. Note that _OFF_T is defined (or not) in stdio.h depending */ /* on whether _LARGEFILE_SOURCE is defined in sys/feature_tests.h */ /* (at least on Solaris platforms using cc) */ /* Debian systems require the 2nd test, below, */ /* i.e, "(defined(linux) && defined(__off_t_defined))" */ #if defined(_OFF_T) || (defined(linux) && defined(__off_t_defined)) || defined(_MIPS_SZLONG) || defined(__APPLE__) || defined(_AIX) # define OFF_T off_t #else # define OFF_T long #endif /* this block determines if the the string function name is strtol or strtoll, and whether to use %ld or %lld in printf statements */ /* The following 2 cases for that Athon64 were removed on 4 Jan 2006; they appear to be incorrect now that LONGLONG is always typedef'ed to 'long long' || defined(__ia64__) \ || defined(__x86_64__) \ */ #if (defined(__alpha) && ( defined(__unix__) || defined(__NetBSD__) )) \ || defined(__sparcv9) \ || defined(__powerpc64__) || defined(__64BIT__) \ || (defined(_MIPS_SZLONG) && _MIPS_SZLONG == 64) \ || defined( _MSC_VER)|| defined(__BORLANDC__) # define USE_LL_SUFFIX 0 #else # define USE_LL_SUFFIX 1 #endif /* Determine what 8-byte integer data type is available. 'long long' is now supported by most compilers, but older MS Visual C++ compilers before V7.0 use '__int64' instead. */ #ifndef LONGLONG_TYPE /* this may have been previously defined */ #if defined(_MSC_VER) /* Microsoft Visual C++ */ #if (_MSC_VER < 1300) /* versions earlier than V7.0 do not have 'long long' */ typedef __int64 LONGLONG; #else /* newer versions do support 'long long' */ typedef long long LONGLONG; #endif #else typedef long long LONGLONG; #endif #define LONGLONG_TYPE #endif /* ================================================================= */ /* The following exclusion if __CINT__ is defined is needed for ROOT */ #ifndef __CINT__ #include "longnam.h" #endif /* global variables */ #define FLEN_FILENAME 1025 /* max length of a filename */ #define FLEN_KEYWORD 72 /* max length of a keyword (HIERARCH convention) */ #define FLEN_CARD 81 /* length of a FITS header card */ #define FLEN_VALUE 71 /* max length of a keyword value string */ #define FLEN_COMMENT 73 /* max length of a keyword comment string */ #define FLEN_ERRMSG 81 /* max length of a FITSIO error message */ #define FLEN_STATUS 31 /* max length of a FITSIO status text string */ #define TBIT 1 /* codes for FITS table data types */ #define TBYTE 11 #define TSBYTE 12 #define TLOGICAL 14 #define TSTRING 16 #define TUSHORT 20 #define TSHORT 21 #define TUINT 30 #define TINT 31 #define TULONG 40 #define TLONG 41 #define TINT32BIT 41 /* used when returning datatype of a column */ #define TFLOAT 42 #define TLONGLONG 81 #define TDOUBLE 82 #define TCOMPLEX 83 #define TDBLCOMPLEX 163 #define TYP_STRUC_KEY 10 #define TYP_CMPRS_KEY 20 #define TYP_SCAL_KEY 30 #define TYP_NULL_KEY 40 #define TYP_DIM_KEY 50 #define TYP_RANG_KEY 60 #define TYP_UNIT_KEY 70 #define TYP_DISP_KEY 80 #define TYP_HDUID_KEY 90 #define TYP_CKSUM_KEY 100 #define TYP_WCS_KEY 110 #define TYP_REFSYS_KEY 120 #define TYP_COMM_KEY 130 #define TYP_CONT_KEY 140 #define TYP_USER_KEY 150 #define INT32BIT int /* 32-bit integer datatype. Currently this */ /* datatype is an 'int' on all useful platforms */ /* however, it is possible that that are cases */ /* where 'int' is a 2-byte integer, in which case */ /* INT32BIT would need to be defined as 'long'. */ #define BYTE_IMG 8 /* BITPIX code values for FITS image types */ #define SHORT_IMG 16 #define LONG_IMG 32 #define LONGLONG_IMG 64 #define FLOAT_IMG -32 #define DOUBLE_IMG -64 /* The following 2 codes are not true FITS */ /* datatypes; these codes are only used internally */ /* within cfitsio to make it easier for users */ /* to deal with unsigned integers. */ #define SBYTE_IMG 10 #define USHORT_IMG 20 #define ULONG_IMG 40 #define IMAGE_HDU 0 /* Primary Array or IMAGE HDU */ #define ASCII_TBL 1 /* ASCII table HDU */ #define BINARY_TBL 2 /* Binary table HDU */ #define ANY_HDU -1 /* matches any HDU type */ #define READONLY 0 /* options when opening a file */ #define READWRITE 1 /* adopt a hopefully obscure number to use as a null value flag */ /* could be problems if the FITS files contain data with these values */ #define FLOATNULLVALUE -9.11912E-36F #define DOUBLENULLVALUE -9.1191291391491E-36 /* Image compression algorithm types */ #define MAX_COMPRESS_DIM 6 #define RICE_1 11 #define GZIP_1 21 #define PLIO_1 31 #define HCOMPRESS_1 41 #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define CASESEN 1 /* do case-sensitive string match */ #define CASEINSEN 0 /* do case-insensitive string match */ #define GT_ID_ALL_URI 0 /* hierarchical grouping parameters */ #define GT_ID_REF 1 #define GT_ID_POS 2 #define GT_ID_ALL 3 #define GT_ID_REF_URI 11 #define GT_ID_POS_URI 12 #define OPT_RM_GPT 0 #define OPT_RM_ENTRY 1 #define OPT_RM_MBR 2 #define OPT_RM_ALL 3 #define OPT_GCP_GPT 0 #define OPT_GCP_MBR 1 #define OPT_GCP_ALL 2 #define OPT_MCP_ADD 0 #define OPT_MCP_NADD 1 #define OPT_MCP_REPL 2 #define OPT_MCP_MOV 3 #define OPT_MRG_COPY 0 #define OPT_MRG_MOV 1 #define OPT_CMT_MBR 1 #define OPT_CMT_MBR_DEL 11 typedef struct /* structure used to store table column information */ { char ttype[70]; /* column name = FITS TTYPEn keyword; */ LONGLONG tbcol; /* offset in row to first byte of each column */ int tdatatype; /* datatype code of each column */ LONGLONG trepeat; /* repeat count of column; number of elements */ double tscale; /* FITS TSCALn linear scaling factor */ double tzero; /* FITS TZEROn linear scaling zero point */ LONGLONG tnull; /* FITS null value for int image or binary table cols */ char strnull[20]; /* FITS null value string for ASCII table columns */ char tform[10]; /* FITS tform keyword value */ long twidth; /* width of each ASCII table column */ }tcolumn; #define VALIDSTRUC 555 /* magic value used to identify if structure is valid */ typedef struct /* structure used to store basic FITS file information */ { int filehandle; /* handle returned by the file open function */ int driver; /* defines which set of I/O drivers should be used */ int open_count; /* number of opened 'fitsfiles' using this structure */ char *filename; /* file name */ int validcode; /* magic value used to verify that structure is valid */ LONGLONG filesize; /* current size of the physical disk file in bytes */ LONGLONG logfilesize; /* logical size of file, including unflushed buffers */ int lasthdu; /* is this the last HDU in the file? 0 = no, else yes */ LONGLONG bytepos; /* current logical I/O pointer position in file */ LONGLONG io_pos; /* current I/O pointer position in the physical file */ int curbuf; /* number of I/O buffer currently in use */ int curhdu; /* current HDU number; 0 = primary array */ int hdutype; /* 0 = primary array, 1 = ASCII table, 2 = binary table */ int writemode; /* 0 = readonly, 1 = readwrite */ int maxhdu; /* highest numbered HDU known to exist in the file */ int MAXHDU; /* dynamically allocated dimension of headstart array */ LONGLONG *headstart; /* byte offset in file to start of each HDU */ LONGLONG headend; /* byte offest in file to end of the current HDU header */ LONGLONG nextkey; /* byte offset in file to beginning of next keyword */ LONGLONG datastart; /* byte offset in file to start of the current data unit */ int tfield; /* number of fields in the table (primary array has 2 */ LONGLONG origrows; /* original number of rows (value of NAXIS2 keyword) */ LONGLONG numrows; /* number of rows in the table (dynamically updated) */ LONGLONG rowlength; /* length of a table row or image size (bytes) */ tcolumn *tableptr; /* pointer to the table structure */ LONGLONG heapstart; /* heap start byte relative to start of data unit */ LONGLONG heapsize; /* size of the heap, in bytes */ /* the following elements are related to compressed images */ int request_compress_type; /* requested image compression algorithm */ long request_tilesize[MAX_COMPRESS_DIM]; /* requested tiling size */ int request_noise_nbits; /* requested noise bit parameter value */ int request_hcomp_scale; /* requested HCOMPRESS scale factor */ int request_hcomp_smooth; /* requested HCOMPRESS smooth parameter */ int compressimg; /* 1 if HDU contains a compressed image, else 0 */ char zcmptype[12]; /* compression type string */ int compress_type; /* type of compression algorithm */ int zbitpix; /* FITS data type of image (BITPIX) */ int zndim; /* dimension of image */ long znaxis[MAX_COMPRESS_DIM]; /* length of each axis */ long tilesize[MAX_COMPRESS_DIM]; /* size of compression tiles */ long maxtilelen; /* max number of pixels in each image tile */ long maxelem; /* maximum length of variable length arrays */ int cn_compressed; /* column number for COMPRESSED_DATA column */ int cn_uncompressed; /* column number for UNCOMPRESSED_DATA column */ int cn_zscale; /* column number for ZSCALE column */ int cn_zzero; /* column number for ZZERO column */ int cn_zblank; /* column number for the ZBLANK column */ double zscale; /* scaling value, if same for all tiles */ double zzero; /* zero pt, if same for all tiles */ double cn_bscale; /* value of the BSCALE keyword in header */ double cn_bzero; /* value of the BZERO keyword in header */ int zblank; /* value for null pixels, if not a column */ int rice_blocksize; /* first compression parameter */ int noise_nbits; /* floating point noise parameter */ int hcomp_scale; /* 1st hcompress compression parameter */ int hcomp_smooth; /* 2nd hcompress compression parameter */ } FITSfile; typedef struct /* structure used to store basic HDU information */ { int HDUposition; /* HDU position in file; 0 = first HDU */ FITSfile *Fptr; /* pointer to FITS file structure */ }fitsfile; typedef struct /* structure for the iterator function column information */ { /* elements required as input to fits_iterate_data: */ fitsfile *fptr; /* pointer to the HDU containing the column */ int colnum; /* column number in the table (use name if < 1) */ char colname[70]; /* name (= TTYPEn value) of the column (optional) */ int datatype; /* output datatype (converted if necessary */ int iotype; /* = InputCol, InputOutputCol, or OutputCol */ /* output elements that may be useful for the work function: */ void *array; /* pointer to the array (and the null value) */ long repeat; /* binary table vector repeat value */ long tlmin; /* legal minimum data value */ long tlmax; /* legal maximum data value */ char tunit[70]; /* physical unit string */ char tdisp[70]; /* suggested display format */ } iteratorCol; #define InputCol 0 /* flag for input only iterator column */ #define InputOutputCol 1 /* flag for input and output iterator column */ #define OutputCol 2 /* flag for output only iterator column */ /*============================================================================= * * The following wtbarr typedef is used in the fits_read_wcstab() routine, * which is intended for use with the WCSLIB library written by Mark * Calabretta, http://www.atnf.csiro.au/~mcalabre/index.html * * In order to maintain WCSLIB and CFITSIO as independent libraries it * was not permissible for any CFITSIO library code to include WCSLIB * header files, or vice versa. However, the CFITSIO function * fits_read_wcstab() accepts an array of structs defined by wcs.h within * WCSLIB. The problem then was to define this struct within fitsio.h * without including wcs.h, especially noting that wcs.h will often (but * not always) be included together with fitsio.h in an applications * program that uses fits_read_wcstab(). * * Of the various possibilities, the solution adopted was for WCSLIB to * define "struct wtbarr" while fitsio.h defines "typedef wtbarr", a * untagged struct with identical members. This allows both wcs.h and * fitsio.h to define a wtbarr data type without conflict by virtue of * the fact that structure tags and typedef names share different * namespaces in C. Therefore, declarations within WCSLIB look like * * struct wtbarr *w; * * while within CFITSIO they are simply * * wtbarr *w; * * but as suggested by the commonality of the names, these are really the * same aggregate data type. However, in passing a (struct wtbarr *) to * fits_read_wcstab() a cast to (wtbarr *) is formally required. *===========================================================================*/ #ifndef WCSLIB_GETWCSTAB #define WCSLIB_GETWCSTAB typedef struct { int i; /* Image axis number. */ int m; /* Array axis number for index vectors. */ int kind; /* Array type, 'c' (coord) or 'i' (index). */ char extnam[72]; /* EXTNAME of binary table extension. */ int extver; /* EXTVER of binary table extension. */ int extlev; /* EXTLEV of binary table extension. */ char ttype[72]; /* TTYPEn of column containing the array. */ long row; /* Table row number. */ int ndim; /* Expected array dimensionality. */ int *dimlen; /* Where to write the array axis lengths. */ double **arrayp; /* Where to write the address of the array */ /* allocated to store the array. */ } wtbarr; int fits_read_wcstab(fitsfile *fptr, int nwtb, wtbarr *wtb, int *status); #endif /* WCSLIB_GETWCSTAB */ /* error status codes */ #define CREATE_DISK_FILE -106 /* create disk file, without extended filename syntax */ #define OPEN_DISK_FILE -105 /* open disk file, without extended filename syntax */ #define SKIP_TABLE -104 /* move to 1st image when opening file */ #define SKIP_IMAGE -103 /* move to 1st table when opening file */ #define SKIP_NULL_PRIMARY -102 /* skip null primary array when opening file */ #define USE_MEM_BUFF -101 /* use memory buffer when opening file */ #define OVERFLOW_ERR -11 /* overflow during datatype conversion */ #define PREPEND_PRIMARY -9 /* used in ffiimg to insert new primary array */ #define SAME_FILE 101 /* input and output files are the same */ #define TOO_MANY_FILES 103 /* tried to open too many FITS files */ #define FILE_NOT_OPENED 104 /* could not open the named file */ #define FILE_NOT_CREATED 105 /* could not create the named file */ #define WRITE_ERROR 106 /* error writing to FITS file */ #define END_OF_FILE 107 /* tried to move past end of file */ #define READ_ERROR 108 /* error reading from FITS file */ #define FILE_NOT_CLOSED 110 /* could not close the file */ #define ARRAY_TOO_BIG 111 /* array dimensions exceed internal limit */ #define READONLY_FILE 112 /* Cannot write to readonly file */ #define MEMORY_ALLOCATION 113 /* Could not allocate memory */ #define BAD_FILEPTR 114 /* invalid fitsfile pointer */ #define NULL_INPUT_PTR 115 /* NULL input pointer to routine */ #define SEEK_ERROR 116 /* error seeking position in file */ #define BAD_URL_PREFIX 121 /* invalid URL prefix on file name */ #define TOO_MANY_DRIVERS 122 /* tried to register too many IO drivers */ #define DRIVER_INIT_FAILED 123 /* driver initialization failed */ #define NO_MATCHING_DRIVER 124 /* matching driver is not registered */ #define URL_PARSE_ERROR 125 /* failed to parse input file URL */ #define RANGE_PARSE_ERROR 126 /* failed to parse input file URL */ #define SHARED_ERRBASE (150) #define SHARED_BADARG (SHARED_ERRBASE + 1) #define SHARED_NULPTR (SHARED_ERRBASE + 2) #define SHARED_TABFULL (SHARED_ERRBASE + 3) #define SHARED_NOTINIT (SHARED_ERRBASE + 4) #define SHARED_IPCERR (SHARED_ERRBASE + 5) #define SHARED_NOMEM (SHARED_ERRBASE + 6) #define SHARED_AGAIN (SHARED_ERRBASE + 7) #define SHARED_NOFILE (SHARED_ERRBASE + 8) #define SHARED_NORESIZE (SHARED_ERRBASE + 9) #define HEADER_NOT_EMPTY 201 /* header already contains keywords */ #define KEY_NO_EXIST 202 /* keyword not found in header */ #define KEY_OUT_BOUNDS 203 /* keyword record number is out of bounds */ #define VALUE_UNDEFINED 204 /* keyword value field is blank */ #define NO_QUOTE 205 /* string is missing the closing quote */ #define BAD_INDEX_KEY 206 /* illegal indexed keyword name */ #define BAD_KEYCHAR 207 /* illegal character in keyword name or card */ #define BAD_ORDER 208 /* required keywords out of order */ #define NOT_POS_INT 209 /* keyword value is not a positive integer */ #define NO_END 210 /* couldn't find END keyword */ #define BAD_BITPIX 211 /* illegal BITPIX keyword value*/ #define BAD_NAXIS 212 /* illegal NAXIS keyword value */ #define BAD_NAXES 213 /* illegal NAXISn keyword value */ #define BAD_PCOUNT 214 /* illegal PCOUNT keyword value */ #define BAD_GCOUNT 215 /* illegal GCOUNT keyword value */ #define BAD_TFIELDS 216 /* illegal TFIELDS keyword value */ #define NEG_WIDTH 217 /* negative table row size */ #define NEG_ROWS 218 /* negative number of rows in table */ #define COL_NOT_FOUND 219 /* column with this name not found in table */ #define BAD_SIMPLE 220 /* illegal value of SIMPLE keyword */ #define NO_SIMPLE 221 /* Primary array doesn't start with SIMPLE */ #define NO_BITPIX 222 /* Second keyword not BITPIX */ #define NO_NAXIS 223 /* Third keyword not NAXIS */ #define NO_NAXES 224 /* Couldn't find all the NAXISn keywords */ #define NO_XTENSION 225 /* HDU doesn't start with XTENSION keyword */ #define NOT_ATABLE 226 /* the CHDU is not an ASCII table extension */ #define NOT_BTABLE 227 /* the CHDU is not a binary table extension */ #define NO_PCOUNT 228 /* couldn't find PCOUNT keyword */ #define NO_GCOUNT 229 /* couldn't find GCOUNT keyword */ #define NO_TFIELDS 230 /* couldn't find TFIELDS keyword */ #define NO_TBCOL 231 /* couldn't find TBCOLn keyword */ #define NO_TFORM 232 /* couldn't find TFORMn keyword */ #define NOT_IMAGE 233 /* the CHDU is not an IMAGE extension */ #define BAD_TBCOL 234 /* TBCOLn keyword value < 0 or > rowlength */ #define NOT_TABLE 235 /* the CHDU is not a table */ #define COL_TOO_WIDE 236 /* column is too wide to fit in table */ #define COL_NOT_UNIQUE 237 /* more than 1 column name matches template */ #define BAD_ROW_WIDTH 241 /* sum of column widths not = NAXIS1 */ #define UNKNOWN_EXT 251 /* unrecognizable FITS extension type */ #define UNKNOWN_REC 252 /* unrecognizable FITS record */ #define END_JUNK 253 /* END keyword is not blank */ #define BAD_HEADER_FILL 254 /* Header fill area not blank */ #define BAD_DATA_FILL 255 /* Data fill area not blank or zero */ #define BAD_TFORM 261 /* illegal TFORM format code */ #define BAD_TFORM_DTYPE 262 /* unrecognizable TFORM datatype code */ #define BAD_TDIM 263 /* illegal TDIMn keyword value */ #define BAD_HEAP_PTR 264 /* invalid BINTABLE heap address */ #define BAD_HDU_NUM 301 /* HDU number < 1 or > MAXHDU */ #define BAD_COL_NUM 302 /* column number < 1 or > tfields */ #define NEG_FILE_POS 304 /* tried to move before beginning of file */ #define NEG_BYTES 306 /* tried to read or write negative bytes */ #define BAD_ROW_NUM 307 /* illegal starting row number in table */ #define BAD_ELEM_NUM 308 /* illegal starting element number in vector */ #define NOT_ASCII_COL 309 /* this is not an ASCII string column */ #define NOT_LOGICAL_COL 310 /* this is not a logical datatype column */ #define BAD_ATABLE_FORMAT 311 /* ASCII table column has wrong format */ #define BAD_BTABLE_FORMAT 312 /* Binary table column has wrong format */ #define NO_NULL 314 /* null value has not been defined */ #define NOT_VARI_LEN 317 /* this is not a variable length column */ #define BAD_DIMEN 320 /* illegal number of dimensions in array */ #define BAD_PIX_NUM 321 /* first pixel number greater than last pixel */ #define ZERO_SCALE 322 /* illegal BSCALE or TSCALn keyword = 0 */ #define NEG_AXIS 323 /* illegal axis length < 1 */ #define NOT_GROUP_TABLE 340 #define HDU_ALREADY_MEMBER 341 #define MEMBER_NOT_FOUND 342 #define GROUP_NOT_FOUND 343 #define BAD_GROUP_ID 344 #define TOO_MANY_HDUS_TRACKED 345 #define HDU_ALREADY_TRACKED 346 #define BAD_OPTION 347 #define IDENTICAL_POINTERS 348 #define BAD_GROUP_ATTACH 349 #define BAD_GROUP_DETACH 350 #define BAD_I2C 401 /* bad int to formatted string conversion */ #define BAD_F2C 402 /* bad float to formatted string conversion */ #define BAD_INTKEY 403 /* can't interprete keyword value as integer */ #define BAD_LOGICALKEY 404 /* can't interprete keyword value as logical */ #define BAD_FLOATKEY 405 /* can't interprete keyword value as float */ #define BAD_DOUBLEKEY 406 /* can't interprete keyword value as double */ #define BAD_C2I 407 /* bad formatted string to int conversion */ #define BAD_C2F 408 /* bad formatted string to float conversion */ #define BAD_C2D 409 /* bad formatted string to double conversion */ #define BAD_DATATYPE 410 /* bad keyword datatype code */ #define BAD_DECIM 411 /* bad number of decimal places specified */ #define NUM_OVERFLOW 412 /* overflow during datatype conversion */ # define DATA_COMPRESSION_ERR 413 /* error in imcompress routines */ # define DATA_DECOMPRESSION_ERR 414 /* error in imcompress routines */ # define NO_COMPRESSED_TILE 415 /* compressed tile doesn't exist */ #define BAD_DATE 420 /* error in date or time conversion */ #define PARSE_SYNTAX_ERR 431 /* syntax error in parser expression */ #define PARSE_BAD_TYPE 432 /* expression did not evaluate to desired type */ #define PARSE_LRG_VECTOR 433 /* vector result too large to return in array */ #define PARSE_NO_OUTPUT 434 /* data parser failed not sent an out column */ #define PARSE_BAD_COL 435 /* bad data encounter while parsing column */ #define PARSE_BAD_OUTPUT 436 /* Output file not of proper type */ #define ANGLE_TOO_BIG 501 /* celestial angle too large for projection */ #define BAD_WCS_VAL 502 /* bad celestial coordinate or pixel value */ #define WCS_ERROR 503 /* error in celestial coordinate calculation */ #define BAD_WCS_PROJ 504 /* unsupported type of celestial projection */ #define NO_WCS_KEY 505 /* celestial coordinate keywords not found */ #define APPROX_WCS_KEY 506 /* approximate WCS keywords were calculated */ #define NO_CLOSE_ERROR 999 /* special value used internally to switch off */ /* the error message from ffclos and ffchdu */ /*------- following error codes are used in the grparser.c file -----------*/ #define NGP_ERRBASE (360) /* base chosen so not to interfere with CFITSIO */ #define NGP_OK (0) #define NGP_NO_MEMORY (NGP_ERRBASE + 0) /* malloc failed */ #define NGP_READ_ERR (NGP_ERRBASE + 1) /* read error from file */ #define NGP_NUL_PTR (NGP_ERRBASE + 2) /* null pointer passed as argument */ #define NGP_EMPTY_CURLINE (NGP_ERRBASE + 3) /* line read seems to be empty */ #define NGP_UNREAD_QUEUE_FULL (NGP_ERRBASE + 4) /* cannot unread more then 1 line (or single line twice) */ #define NGP_INC_NESTING (NGP_ERRBASE + 5) /* too deep include file nesting (inf. loop ?) */ #define NGP_ERR_FOPEN (NGP_ERRBASE + 6) /* fopen() failed, cannot open file */ #define NGP_EOF (NGP_ERRBASE + 7) /* end of file encountered */ #define NGP_BAD_ARG (NGP_ERRBASE + 8) /* bad arguments passed */ #define NGP_TOKEN_NOT_EXPECT (NGP_ERRBASE + 9) /* token not expected here */ /* The following exclusion if __CINT__ is defined is needed for ROOT */ #ifndef __CINT__ /* the following 3 lines are needed to support C++ compilers */ #ifdef __cplusplus extern "C" { #endif #endif int CFITS2Unit( fitsfile *fptr ); fitsfile* CUnit2FITS(int unit); /*---------------- FITS file URL parsing routines -------------*/ int fits_get_token(char **ptr, char *delimiter, char *token, int *isanumber); char *fits_split_names(char *list); int ffiurl( char *url, char *urltype, char *infile, char *outfile, char *extspec, char *rowfilter, char *binspec, char *colspec, int *status); int ffifile (char *url, char *urltype, char *infile, char *outfile, char *extspec, char *rowfilter, char *binspec, char *colspec, char *pixfilter, int *status); int ffrtnm(char *url, char *rootname, int *status); int ffexist(const char *infile, int *exists, int *status); int ffexts(char *extspec, int *extnum, char *extname, int *extvers, int *hdutype, char *colname, char *rowexpress, int *status); int ffextn(char *url, int *extension_num, int *status); int ffurlt(fitsfile *fptr, char *urlType, int *status); int ffbins(char *binspec, int *imagetype, int *haxis, char colname[4][FLEN_VALUE], double *minin, double *maxin, double *binsizein, char minname[4][FLEN_VALUE], char maxname[4][FLEN_VALUE], char binname[4][FLEN_VALUE], double *weight, char *wtname, int *recip, int *status); int ffbinr(char **binspec, char *colname, double *minin, double *maxin, double *binsizein, char *minname, char *maxname, char *binname, int *status); int fits_copy_cell2image(fitsfile *fptr, fitsfile *newptr, char *colname, long rownum, int *status); int fits_copy_image2cell(fitsfile *fptr, fitsfile *newptr, char *colname, long rownum, int copykeyflag, int *status); int ffimport_file( char *filename, char **contents, int *status ); int ffrwrg( char *rowlist, LONGLONG maxrows, int maxranges, int *numranges, long *minrow, long *maxrow, int *status); int ffrwrgll( char *rowlist, LONGLONG maxrows, int maxranges, int *numranges, LONGLONG *minrow, LONGLONG *maxrow, int *status); /*---------------- FITS file I/O routines -------------*/ int ffomem(fitsfile **fptr, const char *name, int mode, void **buffptr, size_t *buffsize, size_t deltasize, void *(*mem_realloc)(void *p, size_t newsize), int *status); int ffopen(fitsfile **fptr, const char *filename, int iomode, int *status); int ffopentest(double version, fitsfile **fptr, const char *filename, int iomode, int *status); int ffdopn(fitsfile **fptr, const char *filename, int iomode, int *status); int fftopn(fitsfile **fptr, const char *filename, int iomode, int *status); int ffiopn(fitsfile **fptr, const char *filename, int iomode, int *status); int ffdkopn(fitsfile **fptr, const char *filename, int iomode, int *status); int ffreopen(fitsfile *openfptr, fitsfile **newfptr, int *status); int ffinit( fitsfile **fptr, const char *filename, int *status); int ffdkinit(fitsfile **fptr, const char *filename, int *status); int ffimem(fitsfile **fptr, void **buffptr, size_t *buffsize, size_t deltasize, void *(*mem_realloc)(void *p, size_t newsize), int *status); int fftplt(fitsfile **fptr, const char *filename, const char *tempname, int *status); int ffflus(fitsfile *fptr, int *status); int ffflsh(fitsfile *fptr, int clearbuf, int *status); int ffclos(fitsfile *fptr, int *status); int ffdelt(fitsfile *fptr, int *status); int ffflnm(fitsfile *fptr, char *filename, int *status); int ffflmd(fitsfile *fptr, int *filemode, int *status); /*---------------- utility routines -------------*/ float ffvers(float *version); void ffupch(char *string); void ffgerr(int status, char *errtext); void ffpmsg(const char *err_message); void ffpmrk(void); int ffgmsg(char *err_message); void ffcmsg(void); void ffcmrk(void); void ffrprt(FILE *stream, int status); void ffcmps(char *templt, char *colname, int casesen, int *match, int *exact); int fftkey(char *keyword, int *status); int fftrec(char *card, int *status); int ffnchk(fitsfile *fptr, int *status); int ffkeyn(char *keyroot, int value, char *keyname, int *status); int ffnkey(int value, char *keyroot, char *keyname, int *status); int ffgkcl(char *card); int ffdtyp(char *cval, char *dtype, int *status); int ffpsvc(char *card, char *value, char *comm, int *status); int ffgknm(char *card, char *name, int *length, int *status); int ffgthd(char *tmplt, char *card, int *hdtype, int *status); int fits_translate_keyword(char *inrec, char *outrec, char *patterns[][2], int npat, int n_value, int n_offset, int n_range, int *pat_num, int *i, int *j, int *m, int *n, int *status); int fits_translate_keywords(fitsfile *infptr, fitsfile *outfptr, int firstkey, char *patterns[][2], int npat, int n_value, int n_offset, int n_range, int *status); int ffasfm(char *tform, int *datacode, long *width, int *decim, int *status); int ffbnfm(char *tform, int *datacode, long *repeat, long *width, int *status); int ffbnfmll(char *tform, int *datacode, LONGLONG *repeat, long *width, int *status); int ffgabc(int tfields, char **tform, int space, long *rowlen, long *tbcol, int *status); int fits_get_section_range(char **ptr,long *secmin,long *secmax,long *incre, int *status); /* ffmbyt should not normally be used in application programs, but it is defined here as a publicly available routine because there are a few rare cases where it is needed */ int ffmbyt(fitsfile *fptr, LONGLONG bytpos, int ignore_err, int *status); /*----------------- write single keywords --------------*/ int ffpky(fitsfile *fptr, int datatype, char *keyname, void *value, char *comm, int *status); int ffprec(fitsfile *fptr, const char *card, int *status); int ffpcom(fitsfile *fptr, const char *comm, int *status); int ffpunt(fitsfile *fptr, char *keyname, char *unit, int *status); int ffphis(fitsfile *fptr, const char *history, int *status); int ffpdat(fitsfile *fptr, int *status); int ffverifydate(int year, int month, int day, int *status); int ffgstm(char *timestr, int *timeref, int *status); int ffgsdt(int *day, int *month, int *year, int *status); int ffdt2s(int year, int month, int day, char *datestr, int *status); int fftm2s(int year, int month, int day, int hour, int minute, double second, int decimals, char *datestr, int *status); int ffs2dt(char *datestr, int *year, int *month, int *day, int *status); int ffs2tm(char *datestr, int *year, int *month, int *day, int *hour, int *minute, double *second, int *status); int ffpkyu(fitsfile *fptr, char *keyname, char *comm, int *status); int ffpkys(fitsfile *fptr, char *keyname, char *value, char *comm,int *status); int ffpkls(fitsfile *fptr, char *keyname, char *value, char *comm,int *status); int ffplsw(fitsfile *fptr, int *status); int ffpkyl(fitsfile *fptr, char *keyname, int value, char *comm, int *status); int ffpkyj(fitsfile *fptr, char *keyname, LONGLONG value, char *comm, int *status); int ffpkyf(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffpkye(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffpkyg(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffpkyd(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffpkyc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffpkym(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); int ffpkfc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffpkfm(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); int ffpkyt(fitsfile *fptr, char *keyname, long intval, double frac, char *comm, int *status); int ffptdm( fitsfile *fptr, int colnum, int naxis, long naxes[], int *status); int ffptdmll( fitsfile *fptr, int colnum, int naxis, LONGLONG naxes[], int *status); /*----------------- write array of keywords --------------*/ int ffpkns(fitsfile *fptr, char *keyroot, int nstart, int nkey, char *value[], char *comm[], int *status); int ffpknl(fitsfile *fptr, char *keyroot, int nstart, int nkey, int *value, char *comm[], int *status); int ffpknj(fitsfile *fptr, char *keyroot, int nstart, int nkey, long *value, char *comm[], int *status); int ffpknjj(fitsfile *fptr, char *keyroot, int nstart, int nkey, LONGLONG *value, char *comm[], int *status); int ffpknf(fitsfile *fptr, char *keyroot, int nstart, int nkey, float *value, int decim, char *comm[], int *status); int ffpkne(fitsfile *fptr, char *keyroot, int nstart, int nkey, float *value, int decim, char *comm[], int *status); int ffpkng(fitsfile *fptr, char *keyroot, int nstart, int nkey, double *value, int decim, char *comm[], int *status); int ffpknd(fitsfile *fptr, char *keyroot, int nstart, int nkey, double *value, int decim, char *comm[], int *status); int ffcpky(fitsfile *infptr,fitsfile *outfptr,int incol,int outcol, char *rootname, int *status); /*----------------- write required header keywords --------------*/ int ffphps( fitsfile *fptr, int bitpix, int naxis, long naxes[], int *status); int ffphpsll( fitsfile *fptr, int bitpix, int naxis, LONGLONG naxes[], int *status); int ffphpr( fitsfile *fptr, int simple, int bitpix, int naxis, long naxes[], LONGLONG pcount, LONGLONG gcount, int extend, int *status); int ffphprll( fitsfile *fptr, int simple, int bitpix, int naxis, LONGLONG naxes[], LONGLONG pcount, LONGLONG gcount, int extend, int *status); int ffphtb(fitsfile *fptr, LONGLONG naxis1, LONGLONG naxis2, int tfields, char **ttype, long *tbcol, char **tform, char **tunit, char *extname, int *status); int ffphbn(fitsfile *fptr, LONGLONG naxis2, int tfields, char **ttype, char **tform, char **tunit, char *extname, LONGLONG pcount, int *status); int ffphext( fitsfile *fptr, char *xtension, int bitpix, int naxis, long naxes[], LONGLONG pcount, LONGLONG gcount, int *status); /*----------------- write template keywords --------------*/ int ffpktp(fitsfile *fptr, const char *filename, int *status); /*------------------ get header information --------------*/ int ffghsp(fitsfile *fptr, int *nexist, int *nmore, int *status); int ffghps(fitsfile *fptr, int *nexist, int *position, int *status); /*------------------ move position in header -------------*/ int ffmaky(fitsfile *fptr, int nrec, int *status); int ffmrky(fitsfile *fptr, int nrec, int *status); /*------------------ read single keywords -----------------*/ int ffgnxk(fitsfile *fptr, char **inclist, int ninc, char **exclist, int nexc, char *card, int *status); int ffgrec(fitsfile *fptr, int nrec, char *card, int *status); int ffgcrd(fitsfile *fptr, char *keyname, char *card, int *status); int ffgunt(fitsfile *fptr, char *keyname, char *unit, int *status); int ffgkyn(fitsfile *fptr, int nkey, char *keyname, char *keyval, char *comm, int *status); int ffgkey(fitsfile *fptr, char *keyname, char *keyval, char *comm, int *status); int ffgky( fitsfile *fptr, int datatype, char *keyname, void *value, char *comm, int *status); int ffgkys(fitsfile *fptr, char *keyname, char *value, char *comm, int *status); int ffgkls(fitsfile *fptr, char *keyname, char **value, char *comm, int *status) ; int ffgkyl(fitsfile *fptr, char *keyname, int *value, char *comm, int *status); int ffgkyj(fitsfile *fptr, char *keyname, long *value, char *comm, int *status); int ffgkyjj(fitsfile *fptr, char *keyname, LONGLONG *value, char *comm, int *status); int ffgkye(fitsfile *fptr, char *keyname, float *value, char *comm,int *status); int ffgkyd(fitsfile *fptr, char *keyname, double *value,char *comm,int *status); int ffgkyc(fitsfile *fptr, char *keyname, float *value, char *comm,int *status); int ffgkym(fitsfile *fptr, char *keyname, double *value,char *comm,int *status); int ffgkyt(fitsfile *fptr, char *keyname, long *ivalue, double *dvalue, char *comm, int *status); int ffgtdm(fitsfile *fptr, int colnum, int maxdim, int *naxis, long naxes[], int *status); int ffgtdmll(fitsfile *fptr, int colnum, int maxdim, int *naxis, LONGLONG naxes[], int *status); int ffdtdm(fitsfile *fptr, char *tdimstr, int colnum, int maxdim, int *naxis, long naxes[], int *status); int ffdtdmll(fitsfile *fptr, char *tdimstr, int colnum, int maxdim, int *naxis, LONGLONG naxes[], int *status); /*------------------ read array of keywords -----------------*/ int ffgkns(fitsfile *fptr, char *keyname, int nstart, int nmax, char *value[], int *nfound, int *status); int ffgknl(fitsfile *fptr, char *keyname, int nstart, int nmax, int *value, int *nfound, int *status); int ffgknj(fitsfile *fptr, char *keyname, int nstart, int nmax, long *value, int *nfound, int *status); int ffgknjj(fitsfile *fptr, char *keyname, int nstart, int nmax, LONGLONG *value, int *nfound, int *status); int ffgkne(fitsfile *fptr, char *keyname, int nstart, int nmax, float *value, int *nfound, int *status); int ffgknd(fitsfile *fptr, char *keyname, int nstart, int nmax, double *value, int *nfound, int *status); int ffh2st(fitsfile *fptr, char **header, int *status); int ffhdr2str( fitsfile *fptr, int exclude_comm, char **exclist, int nexc, char **header, int *nkeys, int *status); /*----------------- read required header keywords --------------*/ int ffghpr(fitsfile *fptr, int maxdim, int *simple, int *bitpix, int *naxis, long naxes[], long *pcount, long *gcount, int *extend, int *status); int ffghprll(fitsfile *fptr, int maxdim, int *simple, int *bitpix, int *naxis, LONGLONG naxes[], long *pcount, long *gcount, int *extend, int *status); int ffghtb(fitsfile *fptr,int maxfield, long *naxis1, long *naxis2, int *tfields, char **ttype, long *tbcol, char **tform, char **tunit, char *extname, int *status); int ffghtbll(fitsfile *fptr,int maxfield, LONGLONG *naxis1, LONGLONG *naxis2, int *tfields, char **ttype, LONGLONG *tbcol, char **tform, char **tunit, char *extname, int *status); int ffghbn(fitsfile *fptr, int maxfield, long *naxis2, int *tfields, char **ttype, char **tform, char **tunit, char *extname, long *pcount, int *status); int ffghbnll(fitsfile *fptr, int maxfield, LONGLONG *naxis2, int *tfields, char **ttype, char **tform, char **tunit, char *extname, LONGLONG *pcount, int *status); /*--------------------- update keywords ---------------*/ int ffuky(fitsfile *fptr, int datatype, char *keyname, void *value, char *comm, int *status); int ffucrd(fitsfile *fptr, char *keyname, char *card, int *status); int ffukyu(fitsfile *fptr, char *keyname, char *comm, int *status); int ffukys(fitsfile *fptr, char *keyname, char *value, char *comm, int *status); int ffukls(fitsfile *fptr, char *keyname, char *value, char *comm, int *status); int ffukyl(fitsfile *fptr, char *keyname, int value, char *comm, int *status); int ffukyj(fitsfile *fptr, char *keyname, LONGLONG value, char *comm, int *status); int ffukyf(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffukye(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffukyg(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffukyd(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffukyc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffukym(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); int ffukfc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffukfm(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); /*--------------------- modify keywords ---------------*/ int ffmrec(fitsfile *fptr, int nkey, char *card, int *status); int ffmcrd(fitsfile *fptr, char *keyname, char *card, int *status); int ffmnam(fitsfile *fptr, char *oldname, char *newname, int *status); int ffmcom(fitsfile *fptr, char *keyname, char *comm, int *status); int ffmkyu(fitsfile *fptr, char *keyname, char *comm, int *status); int ffmkys(fitsfile *fptr, char *keyname, char *value, char *comm,int *status); int ffmkls(fitsfile *fptr, char *keyname, char *value, char *comm,int *status); int ffmkyl(fitsfile *fptr, char *keyname, int value, char *comm, int *status); int ffmkyj(fitsfile *fptr, char *keyname, LONGLONG value, char *comm, int *status); int ffmkyf(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffmkye(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffmkyg(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffmkyd(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffmkyc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffmkym(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); int ffmkfc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffmkfm(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); /*--------------------- insert keywords ---------------*/ int ffirec(fitsfile *fptr, int nkey, char *card, int *status); int ffikey(fitsfile *fptr, char *card, int *status); int ffikyu(fitsfile *fptr, char *keyname, char *comm, int *status); int ffikys(fitsfile *fptr, char *keyname, char *value, char *comm,int *status); int ffikls(fitsfile *fptr, char *keyname, char *value, char *comm,int *status); int ffikyl(fitsfile *fptr, char *keyname, int value, char *comm, int *status); int ffikyj(fitsfile *fptr, char *keyname, LONGLONG value, char *comm, int *status); int ffikyf(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffikye(fitsfile *fptr, char *keyname, float value, int decim, char *comm, int *status); int ffikyg(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffikyd(fitsfile *fptr, char *keyname, double value, int decim, char *comm, int *status); int ffikyc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffikym(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); int ffikfc(fitsfile *fptr, char *keyname, float *value, int decim, char *comm, int *status); int ffikfm(fitsfile *fptr, char *keyname, double *value, int decim, char *comm, int *status); /*--------------------- delete keywords ---------------*/ int ffdkey(fitsfile *fptr, char *keyname, int *status); int ffdrec(fitsfile *fptr, int keypos, int *status); /*--------------------- get HDU information -------------*/ int ffghdn(fitsfile *fptr, int *chdunum); int ffghdt(fitsfile *fptr, int *exttype, int *status); int ffghad(fitsfile *fptr, long *headstart, long *datastart, long *dataend, int *status); int ffghadll(fitsfile *fptr, LONGLONG *headstart, LONGLONG *datastart, LONGLONG *dataend, int *status); int ffghof(fitsfile *fptr, OFF_T *headstart, OFF_T *datastart, OFF_T *dataend, int *status); int ffgipr(fitsfile *fptr, int maxaxis, int *imgtype, int *naxis, long *naxes, int *status); int ffgiprll(fitsfile *fptr, int maxaxis, int *imgtype, int *naxis, LONGLONG *naxes, int *status); int ffgidt(fitsfile *fptr, int *imgtype, int *status); int ffgiet(fitsfile *fptr, int *imgtype, int *status); int ffgidm(fitsfile *fptr, int *naxis, int *status); int ffgisz(fitsfile *fptr, int nlen, long *naxes, int *status); int ffgiszll(fitsfile *fptr, int nlen, LONGLONG *naxes, int *status); /*--------------------- HDU operations -------------*/ int ffmahd(fitsfile *fptr, int hdunum, int *exttype, int *status); int ffmrhd(fitsfile *fptr, int hdumov, int *exttype, int *status); int ffmnhd(fitsfile *fptr, int exttype, char *hduname, int hduvers, int *status); int ffthdu(fitsfile *fptr, int *nhdu, int *status); int ffcrhd(fitsfile *fptr, int *status); int ffcrim(fitsfile *fptr, int bitpix, int naxis, long *naxes, int *status); int ffcrimll(fitsfile *fptr, int bitpix, int naxis, LONGLONG *naxes, int *status); int ffcrtb(fitsfile *fptr, int tbltype, LONGLONG naxis2, int tfields, char **ttype, char **tform, char **tunit, char *extname, int *status); int ffiimg(fitsfile *fptr, int bitpix, int naxis, long *naxes, int *status); int ffiimgll(fitsfile *fptr, int bitpix, int naxis, LONGLONG *naxes, int *status); int ffitab(fitsfile *fptr, LONGLONG naxis1, LONGLONG naxis2, int tfields, char **ttype, long *tbcol, char **tform, char **tunit, char *extname, int *status); int ffibin(fitsfile *fptr, LONGLONG naxis2, int tfields, char **ttype, char **tform, char **tunit, char *extname, LONGLONG pcount, int *status); int ffrsim(fitsfile *fptr, int bitpix, int naxis, long *naxes, int *status); int ffrsimll(fitsfile *fptr, int bitpix, int naxis, LONGLONG *naxes, int *status); int ffdhdu(fitsfile *fptr, int *hdutype, int *status); int ffcopy(fitsfile *infptr, fitsfile *outfptr, int morekeys, int *status); int ffcpfl(fitsfile *infptr, fitsfile *outfptr, int prev, int cur, int follow, int *status); int ffcphd(fitsfile *infptr, fitsfile *outfptr, int *status); int ffcpdt(fitsfile *infptr, fitsfile *outfptr, int *status); int ffchfl(fitsfile *fptr, int *status); int ffcdfl(fitsfile *fptr, int *status); int ffwrhdu(fitsfile *fptr, FILE *outstream, int *status); int ffrdef(fitsfile *fptr, int *status); int ffhdef(fitsfile *fptr, int morekeys, int *status); int ffpthp(fitsfile *fptr, long theap, int *status); int ffcsum(fitsfile *fptr, long nrec, unsigned long *sum, int *status); void ffesum(unsigned long sum, int complm, char *ascii); unsigned long ffdsum(char *ascii, int complm, unsigned long *sum); int ffpcks(fitsfile *fptr, int *status); int ffupck(fitsfile *fptr, int *status); int ffvcks(fitsfile *fptr, int *datastatus, int *hdustatus, int *status); int ffgcks(fitsfile *fptr, unsigned long *datasum, unsigned long *hdusum, int *status); /*--------------------- define scaling or null values -------------*/ int ffpscl(fitsfile *fptr, double scale, double zero, int *status); int ffpnul(fitsfile *fptr, LONGLONG nulvalue, int *status); int fftscl(fitsfile *fptr, int colnum, double scale, double zero, int *status); int fftnul(fitsfile *fptr, int colnum, LONGLONG nulvalue, int *status); int ffsnul(fitsfile *fptr, int colnum, char *nulstring, int *status); /*--------------------- get column information -------------*/ int ffgcno(fitsfile *fptr, int casesen, char *templt, int *colnum, int *status); int ffgcnn(fitsfile *fptr, int casesen, char *templt, char *colname, int *colnum, int *status); int ffgtcl(fitsfile *fptr, int colnum, int *typecode, long *repeat, long *width, int *status); int ffgtclll(fitsfile *fptr, int colnum, int *typecode, LONGLONG *repeat, LONGLONG *width, int *status); int ffeqty(fitsfile *fptr, int colnum, int *typecode, long *repeat, long *width, int *status); int ffeqtyll(fitsfile *fptr, int colnum, int *typecode, LONGLONG *repeat, LONGLONG *width, int *status); int ffgncl(fitsfile *fptr, int *ncols, int *status); int ffgnrw(fitsfile *fptr, long *nrows, int *status); int ffgnrwll(fitsfile *fptr, LONGLONG *nrows, int *status); int ffgacl(fitsfile *fptr, int colnum, char *ttype, long *tbcol, char *tunit, char *tform, double *tscal, double *tzero, char *tnull, char *tdisp, int *status); int ffgbcl(fitsfile *fptr, int colnum, char *ttype, char *tunit, char *dtype, long *repeat, double *tscal, double *tzero, long *tnull, char *tdisp, int *status); int ffgbclll(fitsfile *fptr, int colnum, char *ttype, char *tunit, char *dtype, LONGLONG *repeat, double *tscal, double *tzero, LONGLONG *tnull, char *tdisp, int *status); int ffgrsz(fitsfile *fptr, long *nrows, int *status); int ffgcdw(fitsfile *fptr, int colnum, int *width, int *status); /*--------------------- read primary array or image elements -------------*/ int ffgpxv(fitsfile *fptr, int datatype, long *firstpix, LONGLONG nelem, void *nulval, void *array, int *anynul, int *status); int ffgpxvll(fitsfile *fptr, int datatype, LONGLONG *firstpix, LONGLONG nelem, void *nulval, void *array, int *anynul, int *status); int ffgpxf(fitsfile *fptr, int datatype, long *firstpix, LONGLONG nelem, void *array, char *nullarray, int *anynul, int *status); int ffgpxfll(fitsfile *fptr, int datatype, LONGLONG *firstpix, LONGLONG nelem, void *array, char *nullarray, int *anynul, int *status); int ffgsv(fitsfile *fptr, int datatype, long *blc, long *trc, long *inc, void *nulval, void *array, int *anynul, int *status); int ffgpv(fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelem, void *nulval, void *array, int *anynul, int *status); int ffgpf(fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelem, void *array, char *nullarray, int *anynul, int *status); int ffgpvb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned char nulval, unsigned char *array, int *anynul, int *status); int ffgpvsb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, signed char nulval, signed char *array, int *anynul, int *status); int ffgpvui(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned short nulval, unsigned short *array, int *anynul, int *status); int ffgpvi(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, short nulval, short *array, int *anynul, int *status); int ffgpvuj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned long nulval, unsigned long *array, int *anynul, int *status); int ffgpvj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, long nulval, long *array, int *anynul, int *status); int ffgpvjj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, LONGLONG nulval, LONGLONG *array, int *anynul, int *status); int ffgpvuk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned int nulval, unsigned int *array, int *anynul, int *status); int ffgpvk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int nulval, int *array, int *anynul, int *status); int ffgpve(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, float nulval, float *array, int *anynul, int *status); int ffgpvd(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, double nulval, double *array, int *anynul, int *status); int ffgpfb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, char *nularray, int *anynul, int *status); int ffgpfsb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, signed char *array, char *nularray, int *anynul, int *status); int ffgpfui(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, char *nularray, int *anynul, int *status); int ffgpfi(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, short *array, char *nularray, int *anynul, int *status); int ffgpfuj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, char *nularray, int *anynul, int *status); int ffgpfj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, long *array, char *nularray, int *anynul, int *status); int ffgpfjj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, char *nularray, int *anynul, int *status); int ffgpfuk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, char *nularray, int *anynul, int *status); int ffgpfk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int *array, char *nularray, int *anynul, int *status); int ffgpfe(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, float *array, char *nularray, int *anynul, int *status); int ffgpfd(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, double *array, char *nularray, int *anynul, int *status); int ffg2db(fitsfile *fptr, long group, unsigned char nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned char *array, int *anynul, int *status); int ffg2dsb(fitsfile *fptr, long group, signed char nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, signed char *array, int *anynul, int *status); int ffg2dui(fitsfile *fptr, long group, unsigned short nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned short *array, int *anynul, int *status); int ffg2di(fitsfile *fptr, long group, short nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, short *array, int *anynul, int *status); int ffg2duj(fitsfile *fptr, long group, unsigned long nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned long *array, int *anynul, int *status); int ffg2dj(fitsfile *fptr, long group, long nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, long *array, int *anynul, int *status); int ffg2djj(fitsfile *fptr, long group, LONGLONG nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, LONGLONG *array, int *anynul, int *status); int ffg2duk(fitsfile *fptr, long group, unsigned int nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned int *array, int *anynul, int *status); int ffg2dk(fitsfile *fptr, long group, int nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, int *array, int *anynul, int *status); int ffg2de(fitsfile *fptr, long group, float nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, float *array, int *anynul, int *status); int ffg2dd(fitsfile *fptr, long group, double nulval, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, double *array, int *anynul, int *status); int ffg3db(fitsfile *fptr, long group, unsigned char nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned char *array, int *anynul, int *status); int ffg3dsb(fitsfile *fptr, long group, signed char nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, signed char *array, int *anynul, int *status); int ffg3dui(fitsfile *fptr, long group, unsigned short nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned short *array, int *anynul, int *status); int ffg3di(fitsfile *fptr, long group, short nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, short *array, int *anynul, int *status); int ffg3duj(fitsfile *fptr, long group, unsigned long nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned long *array, int *anynul, int *status); int ffg3dj(fitsfile *fptr, long group, long nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, long *array, int *anynul, int *status); int ffg3djj(fitsfile *fptr, long group, LONGLONG nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, LONGLONG *array, int *anynul, int *status); int ffg3duk(fitsfile *fptr, long group, unsigned int nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned int *array, int *anynul, int *status); int ffg3dk(fitsfile *fptr, long group, int nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, int *array, int *anynul, int *status); int ffg3de(fitsfile *fptr, long group, float nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, float *array, int *anynul, int *status); int ffg3dd(fitsfile *fptr, long group, double nulval, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, double *array, int *anynul, int *status); int ffgsvb(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned char nulval, unsigned char *array, int *anynul, int *status); int ffgsvsb(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, signed char nulval, signed char *array, int *anynul, int *status); int ffgsvui(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned short nulval, unsigned short *array, int *anynul, int *status); int ffgsvi(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, short nulval, short *array, int *anynul, int *status); int ffgsvuj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned long nulval, unsigned long *array, int *anynul, int *status); int ffgsvj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, long nulval, long *array, int *anynul, int *status); int ffgsvjj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, LONGLONG nulval, LONGLONG *array, int *anynul, int *status); int ffgsvuk(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned int nulval, unsigned int *array, int *anynul, int *status); int ffgsvk(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, int nulval, int *array, int *anynul, int *status); int ffgsve(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, float nulval, float *array, int *anynul, int *status); int ffgsvd(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, double nulval, double *array, int *anynul, int *status); int ffgsfb(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned char *array, char *flagval, int *anynul, int *status); int ffgsfsb(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, signed char *array, char *flagval, int *anynul, int *status); int ffgsfui(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned short *array, char *flagval, int *anynul, int *status); int ffgsfi(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, short *array, char *flagval, int *anynul, int *status); int ffgsfuj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned long *array, char *flagval, int *anynul, int *status); int ffgsfj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, long *array, char *flagval, int *anynul, int *status); int ffgsfjj(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, LONGLONG *array, char *flagval, int *anynul, int *status); int ffgsfuk(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, unsigned int *array, char *flagval, int *anynul, int *status); int ffgsfk(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, int *array, char *flagval, int *anynul, int *status); int ffgsfe(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, float *array, char *flagval, int *anynul, int *status); int ffgsfd(fitsfile *fptr, int colnum, int naxis, long *naxes, long *blc, long *trc, long *inc, double *array, char *flagval, int *anynul, int *status); int ffggpb(fitsfile *fptr, long group, long firstelem, long nelem, unsigned char *array, int *status); int ffggpsb(fitsfile *fptr, long group, long firstelem, long nelem, signed char *array, int *status); int ffggpui(fitsfile *fptr, long group, long firstelem, long nelem, unsigned short *array, int *status); int ffggpi(fitsfile *fptr, long group, long firstelem, long nelem, short *array, int *status); int ffggpuj(fitsfile *fptr, long group, long firstelem, long nelem, unsigned long *array, int *status); int ffggpj(fitsfile *fptr, long group, long firstelem, long nelem, long *array, int *status); int ffggpjj(fitsfile *fptr, long group, long firstelem, long nelem, LONGLONG *array, int *status); int ffggpuk(fitsfile *fptr, long group, long firstelem, long nelem, unsigned int *array, int *status); int ffggpk(fitsfile *fptr, long group, long firstelem, long nelem, int *array, int *status); int ffggpe(fitsfile *fptr, long group, long firstelem, long nelem, float *array, int *status); int ffggpd(fitsfile *fptr, long group, long firstelem, long nelem, double *array, int *status); /*--------------------- read column elements -------------*/ int ffgcv( fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, void *nulval, void *array, int *anynul, int *status); int ffgcf( fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, void *array, char *nullarray, int *anynul, int *status); int ffgcvs(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *nulval, char **array, int *anynul, int *status); int ffgcl (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *array, int *status); int ffgcvl (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char nulval, char *array, int *anynul, int *status); int ffgcvb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned char nulval, unsigned char *array, int *anynul, int *status); int ffgcvsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, signed char nulval, signed char *array, int *anynul, int *status); int ffgcvui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned short nulval, unsigned short *array, int *anynul, int *status); int ffgcvi(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, short nulval, short *array, int *anynul, int *status); int ffgcvuj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned long nulval, unsigned long *array, int *anynul, int *status); int ffgcvj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long nulval, long *array, int *anynul, int *status); int ffgcvjj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, LONGLONG nulval, LONGLONG *array, int *anynul, int *status); int ffgcvuk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned int nulval, unsigned int *array, int *anynul, int *status); int ffgcvk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int nulval, int *array, int *anynul, int *status); int ffgcve(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float nulval, float *array, int *anynul, int *status); int ffgcvd(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double nulval, double *array, int *anynul, int *status); int ffgcvc(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float nulval, float *array, int *anynul, int *status); int ffgcvm(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double nulval, double *array, int *anynul, int *status); int ffgcx(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstbit, LONGLONG nbits, char *larray, int *status); int ffgcxui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows, long firstbit, int nbits, unsigned short *array, int *status); int ffgcxuk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows, long firstbit, int nbits, unsigned int *array, int *status); int ffgcfs(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char **array, char *nularray, int *anynul, int *status); int ffgcfl(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *array, char *nularray, int *anynul, int *status); int ffgcfb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, char *nularray, int *anynul, int *status); int ffgcfsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, signed char *array, char *nularray, int *anynul, int *status); int ffgcfui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, char *nularray, int *anynul, int *status); int ffgcfi(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, short *array, char *nularray, int *anynul, int *status); int ffgcfuj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, char *nularray, int *anynul, int *status); int ffgcfj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long *array, char *nularray, int *anynul, int *status); int ffgcfjj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, char *nularray, int *anynul, int *status); int ffgcfuk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, char *nularray, int *anynul, int *status); int ffgcfk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *array, char *nularray, int *anynul, int *status); int ffgcfe(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, char *nularray, int *anynul, int *status); int ffgcfd(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, char *nularray, int *anynul, int *status); int ffgcfc(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, char *nularray, int *anynul, int *status); int ffgcfm(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, char *nularray, int *anynul, int *status); int ffgdes(fitsfile *fptr, int colnum, LONGLONG rownum, long *length, long *heapaddr, int *status); int ffgdesll(fitsfile *fptr, int colnum, LONGLONG rownum, LONGLONG *length, LONGLONG *heapaddr, int *status); int ffgdess(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows, long *length, long *heapaddr, int *status); int ffgdessll(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows, LONGLONG *length, LONGLONG *heapaddr, int *status); int ffpdes(fitsfile *fptr, int colnum, LONGLONG rownum, LONGLONG length, LONGLONG heapaddr, int *status); int fftheap(fitsfile *fptr, LONGLONG *heapsize, LONGLONG *unused, LONGLONG *overlap, int *valid, int *status); int ffcmph(fitsfile *fptr, int *status); int ffgtbb(fitsfile *fptr, LONGLONG firstrow, LONGLONG firstchar, LONGLONG nchars, unsigned char *values, int *status); int ffgextn(fitsfile *fptr, LONGLONG offset, LONGLONG nelem, void *array, int *status); int ffpextn(fitsfile *fptr, LONGLONG offset, LONGLONG nelem, void *array, int *status); /*------------ write primary array or image elements -------------*/ int ffppx(fitsfile *fptr, int datatype, long *firstpix, LONGLONG nelem, void *array, int *status); int ffppxll(fitsfile *fptr, int datatype, LONGLONG *firstpix, LONGLONG nelem, void *array, int *status); int ffppxn(fitsfile *fptr, int datatype, long *firstpix, LONGLONG nelem, void *array, void *nulval, int *status); int ffppxnll(fitsfile *fptr, int datatype, LONGLONG *firstpix, LONGLONG nelem, void *array, void *nulval, int *status); int ffppr(fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelem, void *array, int *status); int ffpprb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, int *status); int ffpprsb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, signed char *array, int *status); int ffpprui(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, int *status); int ffppri(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, short *array, int *status); int ffppruj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, int *status); int ffpprj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, long *array, int *status); int ffppruk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, int *status); int ffpprk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int *array, int *status); int ffppre(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, float *array, int *status); int ffpprd(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, double *array, int *status); int ffpprjj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, int *status); int ffppru(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int *status); int ffpprn(fitsfile *fptr, LONGLONG firstelem, LONGLONG nelem, int *status); int ffppn(fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelem, void *array, void *nulval, int *status); int ffppnb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, unsigned char nulval, int *status); int ffppnsb(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, signed char *array, signed char nulval, int *status); int ffppnui(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, unsigned short nulval, int *status); int ffppni(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, short *array, short nulval, int *status); int ffppnj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, long *array, long nulval, int *status); int ffppnuj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, unsigned long nulval, int *status); int ffppnuk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, unsigned int nulval, int *status); int ffppnk(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, int *array, int nulval, int *status); int ffppne(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, float *array, float nulval, int *status); int ffppnd(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, double *array, double nulval, int *status); int ffppnjj(fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, LONGLONG nulval, int *status); int ffp2db(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned char *array, int *status); int ffp2dsb(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, signed char *array, int *status); int ffp2dui(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned short *array, int *status); int ffp2di(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, short *array, int *status); int ffp2duj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned long *array, int *status); int ffp2dj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, long *array, int *status); int ffp2duk(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, unsigned int *array, int *status); int ffp2dk(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, int *array, int *status); int ffp2de(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, float *array, int *status); int ffp2dd(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, double *array, int *status); int ffp2djj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG naxis1, LONGLONG naxis2, LONGLONG *array, int *status); int ffp3db(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned char *array, int *status); int ffp3dsb(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, signed char *array, int *status); int ffp3dui(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned short *array, int *status); int ffp3di(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, short *array, int *status); int ffp3duj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned long *array, int *status); int ffp3dj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, long *array, int *status); int ffp3duk(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, unsigned int *array, int *status); int ffp3dk(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, int *array, int *status); int ffp3de(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, float *array, int *status); int ffp3dd(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, double *array, int *status); int ffp3djj(fitsfile *fptr, long group, LONGLONG ncols, LONGLONG nrows, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3, LONGLONG *array, int *status); int ffpss(fitsfile *fptr, int datatype, long *fpixel, long *lpixel, void *array, int *status); int ffpssb(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, unsigned char *array, int *status); int ffpsssb(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, signed char *array, int *status); int ffpssui(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, unsigned short *array, int *status); int ffpssi(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, short *array, int *status); int ffpssuj(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, unsigned long *array, int *status); int ffpssj(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, long *array, int *status); int ffpssuk(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, unsigned int *array, int *status); int ffpssk(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, int *array, int *status); int ffpsse(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, float *array, int *status); int ffpssd(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, double *array, int *status); int ffpssjj(fitsfile *fptr, long group, long naxis, long *naxes, long *fpixel, long *lpixel, LONGLONG *array, int *status); int ffpgpb(fitsfile *fptr, long group, long firstelem, long nelem, unsigned char *array, int *status); int ffpgpsb(fitsfile *fptr, long group, long firstelem, long nelem, signed char *array, int *status); int ffpgpui(fitsfile *fptr, long group, long firstelem, long nelem, unsigned short *array, int *status); int ffpgpi(fitsfile *fptr, long group, long firstelem, long nelem, short *array, int *status); int ffpgpuj(fitsfile *fptr, long group, long firstelem, long nelem, unsigned long *array, int *status); int ffpgpj(fitsfile *fptr, long group, long firstelem, long nelem, long *array, int *status); int ffpgpuk(fitsfile *fptr, long group, long firstelem, long nelem, unsigned int *array, int *status); int ffpgpk(fitsfile *fptr, long group, long firstelem, long nelem, int *array, int *status); int ffpgpe(fitsfile *fptr, long group, long firstelem, long nelem, float *array, int *status); int ffpgpd(fitsfile *fptr, long group, long firstelem, long nelem, double *array, int *status); int ffpgpjj(fitsfile *fptr, long group, long firstelem, long nelem, LONGLONG *array, int *status); /*--------------------- iterator functions -------------*/ int fits_iter_set_by_name(iteratorCol *col, fitsfile *fptr, char *colname, int datatype, int iotype); int fits_iter_set_by_num(iteratorCol *col, fitsfile *fptr, int colnum, int datatype, int iotype); int fits_iter_set_file(iteratorCol *col, fitsfile *fptr); int fits_iter_set_colname(iteratorCol *col, char *colname); int fits_iter_set_colnum(iteratorCol *col, int colnum); int fits_iter_set_datatype(iteratorCol *col, int datatype); int fits_iter_set_iotype(iteratorCol *col, int iotype); fitsfile * fits_iter_get_file(iteratorCol *col); char * fits_iter_get_colname(iteratorCol *col); int fits_iter_get_colnum(iteratorCol *col); int fits_iter_get_datatype(iteratorCol *col); int fits_iter_get_iotype(iteratorCol *col); void * fits_iter_get_array(iteratorCol *col); long fits_iter_get_tlmin(iteratorCol *col); long fits_iter_get_tlmax(iteratorCol *col); long fits_iter_get_repeat(iteratorCol *col); char * fits_iter_get_tunit(iteratorCol *col); char * fits_iter_get_tdisp(iteratorCol *col); int ffiter(int ncols, iteratorCol *data, long offset, long nPerLoop, int (*workFn)( long totaln, long offset, long firstn, long nvalues, int narrays, iteratorCol *data, void *userPointer), void *userPointer, int *status); /*--------------------- write column elements -------------*/ int ffpcl(fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, void *array, int *status); int ffpcls(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char **array, int *status); int ffpcll(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *array, int *status); int ffpclb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, int *status); int ffpclsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, signed char *array, int *status); int ffpclui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, int *status); int ffpcli(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, short *array, int *status); int ffpcluj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, int *status); int ffpclj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long *array, int *status); int ffpcluk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, int *status); int ffpclk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *array, int *status); int ffpcle(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, int *status); int ffpcld(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, int *status); int ffpclc(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, int *status); int ffpclm(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, int *status); int ffpclu(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *status); int ffprwu(fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, int *status); int ffpcljj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, int *status); int ffpclx(fitsfile *fptr, int colnum, LONGLONG frow, long fbit, long nbit, char *larray, int *status); int ffpcn(fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, void *array, void *nulval, int *status); int ffpcns( fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char **array, char *nulvalue, int *status); int ffpcnl( fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, char *array, char nulvalue, int *status); int ffpcnb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned char *array, unsigned char nulvalue, int *status); int ffpcnsb(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, signed char *array, signed char nulvalue, int *status); int ffpcnui(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned short *array, unsigned short nulvalue, int *status); int ffpcni(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, short *array, short nulvalue, int *status); int ffpcnuj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned long *array, unsigned long nulvalue, int *status); int ffpcnj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, long *array, long nulvalue, int *status); int ffpcnuk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, unsigned int *array, unsigned int nulvalue, int *status); int ffpcnk(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, int *array, int nulvalue, int *status); int ffpcne(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, float *array, float nulvalue, int *status); int ffpcnd(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, double *array, double nulvalue, int *status); int ffpcnjj(fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelem, LONGLONG *array, LONGLONG nulvalue, int *status); int ffptbb(fitsfile *fptr, LONGLONG firstrow, LONGLONG firstchar, LONGLONG nchars, unsigned char *values, int *status); int ffirow(fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, int *status); int ffdrow(fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, int *status); int ffdrrg(fitsfile *fptr, char *ranges, int *status); int ffdrws(fitsfile *fptr, long *rownum, long nrows, int *status); int ffdrwsll(fitsfile *fptr, LONGLONG *rownum, LONGLONG nrows, int *status); int fficol(fitsfile *fptr, int numcol, char *ttype, char *tform, int *status); int fficls(fitsfile *fptr, int firstcol, int ncols, char **ttype, char **tform, int *status); int ffmvec(fitsfile *fptr, int colnum, LONGLONG newveclen, int *status); int ffdcol(fitsfile *fptr, int numcol, int *status); int ffcpcl(fitsfile *infptr, fitsfile *outfptr, int incol, int outcol, int create_col, int *status); /*--------------------- WCS Utilities ------------------*/ int ffgics(fitsfile *fptr, double *xrval, double *yrval, double *xrpix, double *yrpix, double *xinc, double *yinc, double *rot, char *type, int *status); int ffgtcs(fitsfile *fptr, int xcol, int ycol, double *xrval, double *yrval, double *xrpix, double *yrpix, double *xinc, double *yinc, double *rot, char *type, int *status); int ffwldp(double xpix, double ypix, double xref, double yref, double xrefpix, double yrefpix, double xinc, double yinc, double rot, char *type, double *xpos, double *ypos, int *status); int ffxypx(double xpos, double ypos, double xref, double yref, double xrefpix, double yrefpix, double xinc, double yinc, double rot, char *type, double *xpix, double *ypix, int *status); /* WCS support routines (provide interface to Doug Mink's WCS library */ int ffgiwcs(fitsfile *fptr, char **header, int *status); int ffgtwcs(fitsfile *fptr, int xcol, int ycol, char **header, int *status); /*--------------------- lexical parsing routines ------------------*/ int fftexp( fitsfile *fptr, char *expr, int maxdim, int *datatype, long *nelem, int *naxis, long *naxes, int *status ); int fffrow( fitsfile *infptr, char *expr, long firstrow, long nrows, long *n_good_rows, char *row_status, int *status); int ffffrw( fitsfile *fptr, char *expr, long *rownum, int *status); int fffrwc( fitsfile *fptr, char *expr, char *timeCol, char *parCol, char *valCol, long ntimes, double *times, char *time_status, int *status ); int ffsrow( fitsfile *infptr, fitsfile *outfptr, char *expr, int *status); int ffcrow( fitsfile *fptr, int datatype, char *expr, long firstrow, long nelements, void *nulval, void *array, int *anynul, int *status ); int ffcalc_rng( fitsfile *infptr, char *expr, fitsfile *outfptr, char *parName, char *parInfo, int nRngs, long *start, long *end, int *status ); int ffcalc( fitsfile *infptr, char *expr, fitsfile *outfptr, char *parName, char *parInfo, int *status ); /* ffhist is not really intended as a user-callable routine */ /* but it may be useful for some specialized applications */ int ffhist(fitsfile **fptr, char *outfile, int imagetype, int naxis, char colname[4][FLEN_VALUE], double *minin, double *maxin, double *binsizein, char minname[4][FLEN_VALUE], char maxname[4][FLEN_VALUE], char binname[4][FLEN_VALUE], double weightin, char wtcol[FLEN_VALUE], int recip, char *rowselect, int *status); int fits_select_image_section(fitsfile **fptr, char *outfile, char *imagesection, int *status); int fits_copy_image_section(fitsfile *infptr, fitsfile *outfile, char *imagesection, int *status); typedef struct { /* input(s) */ int count; char ** path; char ** tag; fitsfile ** ifptr; char * expression; /* output control */ int bitpix; long blank; fitsfile * ofptr; char keyword[FLEN_KEYWORD]; char comment[FLEN_COMMENT]; } PixelFilter; int fits_pixel_filter (PixelFilter * filter, int * status); /*--------------------- grouping routines ------------------*/ int ffgtcr(fitsfile *fptr, char *grpname, int grouptype, int *status); int ffgtis(fitsfile *fptr, char *grpname, int grouptype, int *status); int ffgtch(fitsfile *gfptr, int grouptype, int *status); int ffgtrm(fitsfile *gfptr, int rmopt, int *status); int ffgtcp(fitsfile *infptr, fitsfile *outfptr, int cpopt, int *status); int ffgtmg(fitsfile *infptr, fitsfile *outfptr, int mgopt, int *status); int ffgtcm(fitsfile *gfptr, int cmopt, int *status); int ffgtvf(fitsfile *gfptr, long *firstfailed, int *status); int ffgtop(fitsfile *mfptr,int group,fitsfile **gfptr,int *status); int ffgtam(fitsfile *gfptr, fitsfile *mfptr, int hdupos, int *status); int ffgtnm(fitsfile *gfptr, long *nmembers, int *status); int ffgmng(fitsfile *mfptr, long *nmembers, int *status); int ffgmop(fitsfile *gfptr, long member, fitsfile **mfptr, int *status); int ffgmcp(fitsfile *gfptr, fitsfile *mfptr, long member, int cpopt, int *status); int ffgmtf(fitsfile *infptr, fitsfile *outfptr, long member, int tfopt, int *status); int ffgmrm(fitsfile *fptr, long member, int rmopt, int *status); /*--------------------- group template parser routines ------------------*/ int fits_execute_template(fitsfile *ff, char *ngp_template, int *status); /*--------------------- image compression routines ------------------*/ int fits_set_compression_type(fitsfile *fptr, int ctype, int *status); int fits_set_tile_dim(fitsfile *fptr, int ndim, long *dims, int *status); int fits_set_noise_bits(fitsfile *fptr, int noisebits, int *status); int fits_set_hcomp_scale(fitsfile *fptr, int scale, int *status); int fits_set_hcomp_smooth(fitsfile *fptr, int smooth, int *status); int fits_get_compression_type(fitsfile *fptr, int *ctype, int *status); int fits_get_tile_dim(fitsfile *fptr, int ndim, long *dims, int *status); int fits_get_noise_bits(fitsfile *fptr, int *noisebits, int *status); int fits_get_hcomp_scale(fitsfile *fptr, int *scale, int *status); int fits_get_hcomp_smooth(fitsfile *fptr, int *smooth, int *status); int fits_img_compress(fitsfile *infptr, fitsfile *outfptr, int *status); int fits_compress_img(fitsfile *infptr, fitsfile *outfptr, int compress_type, long *tilesize, int parm1, int parm2, int *status); int fits_is_compressed_image(fitsfile *fptr, int *status); int fits_decompress_img (fitsfile *infptr, fitsfile *outfptr, int *status); int fits_img_decompress (fitsfile *infptr, fitsfile *outfptr, int *status); /* H-compress routines */ int fits_hcompress(int *a, int nx, int ny, int scale, char *output, long *nbytes, int *status); int fits_hcompress64(LONGLONG *a, int nx, int ny, int scale, char *output, long *nbytes, int *status); int fits_hdecompress(unsigned char *input, int smooth, int *a, int *nx, int *ny, int *scale, int *status); int fits_hdecompress64(unsigned char *input, int smooth, LONGLONG *a, int *nx, int *ny, int *scale, int *status); int fits_rms_float (float fdata[], int nx, float in_null_value, double *rms, int *status); int fits_rms_short (short fdata[], int nx, short in_null_value, double *rms, int *status); /* The following exclusion if __CINT__ is defined is needed for ROOT */ #ifndef __CINT__ #ifdef __cplusplus } #endif #endif #endif indi-0.5/src/cfitsio/putcolj.c0000644000175000017500000021002310610474375014171 0ustar jrjr/* This file, putcolj.c, contains routines that write data elements to */ /* a FITS image or table, with long datatype. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include #include "fitsio2.h" /*--------------------------------------------------------------------------*/ int ffpprj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ long *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; long nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_pixels(fptr, TLONG, firstelem, nelem, 0, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpclj(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ long *array, /* I - array of values that are written */ long nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; long nullvalue; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ nullvalue = nulval; /* set local variable */ fits_write_compressed_pixels(fptr, TLONG, firstelem, nelem, 1, array, &nullvalue, status); return(*status); } row=maxvalue(1,group); ffpcnj(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2dj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3dj(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3dj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; long fpixel[3]= {1,1,1}, lpixel[3]; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ lpixel[0] = (long) ncols; lpixel[1] = (long) nrows; lpixel[2] = (long) naxis3; fits_write_compressed_img(fptr, TLONG, fpixel, lpixel, 0, array, NULL, status); return(*status); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpclj(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpclj(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ long *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ fits_write_compressed_img(fptr, TLONG, fpixel, lpixel, 0, array, NULL, status); return(*status); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpclj(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpj( fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ long *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpclj(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpclj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ long *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TLONG && LONGSIZE == 32) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONG): if (writeraw) { /* write raw input bytes without conversion */ ffpi4b(fptr, ntodo, incre, (INT32BIT *) &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffi4fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); } break; case (TLONGLONG): fflongfi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); break; case (TBYTE): ffi4fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffi4fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffi4fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffi4fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffi4fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpclj).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnj( fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ long *array, /* I - array of values to write */ long nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpclj(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood + 1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpclj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpclj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fi1(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fi2(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fi4(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (INT32BIT) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int fflongfi8(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fr4(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fr8(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffi4fstr(long *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } /* ======================================================================== */ /* the following routines support the 'long long' data type */ /* ======================================================================== */ /*--------------------------------------------------------------------------*/ int ffpprjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } row=maxvalue(1,group); ffpcljj(fptr, 2, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffppnjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG firstelem, /* I - first vector element to write(1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values that are written */ LONGLONG nulval, /* I - undefined pixel value */ int *status) /* IO - error status */ /* Write an array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). Any array values that are equal to the value of nulval will be replaced with the null pixel value that is appropriate for this column. */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } row=maxvalue(1,group); ffpcnjj(fptr, 2, row, firstelem, nelem, array, nulval, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp2djj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 2-D array of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { /* call the 3D writing routine, with the 3rd dimension = 1 */ ffp3djj(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffp3djj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ LONGLONG ncols, /* I - number of pixels in each row of array */ LONGLONG nrows, /* I - number of rows in each plane of array */ LONGLONG naxis1, /* I - FITS image NAXIS1 value */ LONGLONG naxis2, /* I - FITS image NAXIS2 value */ LONGLONG naxis3, /* I - FITS image NAXIS3 value */ LONGLONG *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write an entire 3-D cube of values to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow, ii, jj; LONGLONG nfits, narray; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } tablerow=maxvalue(1,group); if (ncols == naxis1 && nrows == naxis2) /* arrays have same size? */ { /* all the image pixels are contiguous, so write all at once */ ffpcljj(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status); return(*status); } if (ncols < naxis1 || nrows < naxis2) return(*status = BAD_DIMEN); nfits = 1; /* next pixel in FITS image to write to */ narray = 0; /* next pixel in input array to be written */ /* loop over naxis3 planes in the data cube */ for (jj = 0; jj < naxis3; jj++) { /* loop over the naxis2 rows in the FITS image, */ /* writing naxis1 pixels to each row */ for (ii = 0; ii < naxis2; ii++) { if (ffpcljj(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0) return(*status); nfits += naxis1; narray += ncols; } narray += (nrows - naxis2) * ncols; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpssjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long naxis, /* I - number of data axes in array */ long *naxes, /* I - size of each FITS axis */ long *fpixel, /* I - 1st pixel in each axis to write (1=1st) */ long *lpixel, /* I - last pixel in each axis to write */ LONGLONG *array, /* I - array to be written */ int *status) /* IO - error status */ /* Write a subsection of pixels to the primary array or image. A subsection is defined to be any contiguous rectangular array of pixels within the n-dimensional FITS data file. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long tablerow; LONGLONG fpix[7], dimen[7], astart, pstart; LONGLONG off2, off3, off4, off5, off6, off7; LONGLONG st10, st20, st30, st40, st50, st60, st70; LONGLONG st1, st2, st3, st4, st5, st6, st7; long ii, i1, i2, i3, i4, i5, i6, i7, irange[7]; if (*status > 0) return(*status); if (fits_is_compressed_image(fptr, status)) { /* this is a compressed image in a binary table */ ffpmsg("writing to compressed image is not supported"); return(*status = DATA_COMPRESSION_ERR); } if (naxis < 1 || naxis > 7) return(*status = BAD_DIMEN); tablerow=maxvalue(1,group); /* calculate the size and number of loops to perform in each dimension */ for (ii = 0; ii < 7; ii++) { fpix[ii]=1; irange[ii]=1; dimen[ii]=1; } for (ii = 0; ii < naxis; ii++) { fpix[ii]=fpixel[ii]; irange[ii]=lpixel[ii]-fpixel[ii]+1; dimen[ii]=naxes[ii]; } i1=irange[0]; /* compute the pixel offset between each dimension */ off2 = dimen[0]; off3 = off2 * dimen[1]; off4 = off3 * dimen[2]; off5 = off4 * dimen[3]; off6 = off5 * dimen[4]; off7 = off6 * dimen[5]; st10 = fpix[0]; st20 = (fpix[1] - 1) * off2; st30 = (fpix[2] - 1) * off3; st40 = (fpix[3] - 1) * off4; st50 = (fpix[4] - 1) * off5; st60 = (fpix[5] - 1) * off6; st70 = (fpix[6] - 1) * off7; /* store the initial offset in each dimension */ st1 = st10; st2 = st20; st3 = st30; st4 = st40; st5 = st50; st6 = st60; st7 = st70; astart = 0; for (i7 = 0; i7 < irange[6]; i7++) { for (i6 = 0; i6 < irange[5]; i6++) { for (i5 = 0; i5 < irange[4]; i5++) { for (i4 = 0; i4 < irange[3]; i4++) { for (i3 = 0; i3 < irange[2]; i3++) { pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7; for (i2 = 0; i2 < irange[1]; i2++) { if (ffpcljj(fptr, 2, tablerow, pstart, i1, &array[astart], status) > 0) return(*status); astart += i1; pstart += off2; } st2 = st20; st3 = st3+off3; } st3 = st30; st4 = st4+off4; } st4 = st40; st5 = st5+off5; } st5 = st50; st6 = st6+off6; } st6 = st60; st7 = st7+off7; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpgpjj(fitsfile *fptr, /* I - FITS file pointer */ long group, /* I - group to write(1 = 1st group) */ long firstelem, /* I - first vector element to write(1 = 1st) */ long nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values that are written */ int *status) /* IO - error status */ /* Write an array of group parameters to the primary array. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being written). */ { long row; /* the primary array is represented as a binary table: each group of the primary array is a row in the table, where the first column contains the group parameters and the second column contains the image itself. */ row=maxvalue(1,group); ffpcljj(fptr, 1L, row, firstelem, nelem, array, status); return(*status); } /*--------------------------------------------------------------------------*/ int ffpcljj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values to write */ int *status) /* IO - error status */ /* Write an array of values to a column in the current FITS HDU. The column number may refer to a real column in an ASCII or binary table, or it may refer to a virtual column in a 1 or more grouped FITS primary array. FITSIO treats a primary array as a binary table with 2 vector columns: the first column contains the group parameters (often with length = 0) and the second column contains the array of image pixels. Each row of the table represents a group in the case of multigroup FITS images. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary. */ { int tcode, maxelem, hdutype, writeraw; long twidth, incre; long ntodo; LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull; double scale, zero; char tform[20], cform[20]; char message[FLEN_ERRMSG]; char snull[20]; /* the FITS null value */ double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */ void *buffer; if (*status > 0) /* inherit input status value if > 0 */ return(*status); buffer = cbuff; /*---------------------------------------------------*/ /* Check input and get parameters about the column: */ /*---------------------------------------------------*/ if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero, tform, &twidth, &tcode, &maxelem, &startpos, &elemnum, &incre, &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0) return(*status); if (tcode == TSTRING) ffcfmt(tform, cform); /* derive C format for writing strings */ /* if there is no scaling and the native machine format is not byteswapped then we can simply write the raw data bytes into the FITS file if the datatype of the FITS column is the same as the input values. Otherwise we must convert the raw values into the scaled and/or machine dependent format in a temporary buffer that has been allocated for this purpose. */ if (scale == 1. && zero == 0. && MACHINE == NATIVE && tcode == TLONGLONG) { writeraw = 1; maxelem = (int) nelem; /* we can write the entire array at one time */ } else writeraw = 0; /*---------------------------------------------------------------------*/ /* Now write the pixels to the FITS column. */ /* First call the ffXXfYY routine to (1) convert the datatype */ /* if necessary, and (2) scale the values by the FITS TSCALn and */ /* TZEROn linear scaling parameters into a temporary buffer. */ /*---------------------------------------------------------------------*/ remain = nelem; /* remaining number of values to write */ next = 0; /* next element in array to be written */ rownum = 0; /* row number, relative to firstrow */ while (remain) { /* limit the number of pixels to process a one time to the number that will fit in the buffer space or to the number of pixels that remain in the current vector, which ever is smaller. */ ntodo = (long) minvalue(remain, maxelem); ntodo = (long) minvalue(ntodo, (repeat - elemnum)); wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre); ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */ switch (tcode) { case (TLONGLONG): if (writeraw) { /* write raw input bytes without conversion */ ffpi8b(fptr, ntodo, incre, (long *) &array[next], status); } else { /* convert the raw data before writing to FITS file */ ffi8fi8(&array[next], ntodo, scale, zero, (LONGLONG *) buffer, status); ffpi8b(fptr, ntodo, incre, (long *) buffer, status); } break; case (TLONG): ffi8fi4(&array[next], ntodo, scale, zero, (INT32BIT *) buffer, status); ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status); break; case (TBYTE): ffi8fi1(&array[next], ntodo, scale, zero, (unsigned char *) buffer, status); ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status); break; case (TSHORT): ffi8fi2(&array[next], ntodo, scale, zero, (short *) buffer, status); ffpi2b(fptr, ntodo, incre, (short *) buffer, status); break; case (TFLOAT): ffi8fr4(&array[next], ntodo, scale, zero, (float *) buffer, status); ffpr4b(fptr, ntodo, incre, (float *) buffer, status); break; case (TDOUBLE): ffi8fr8(&array[next], ntodo, scale, zero, (double *) buffer, status); ffpr8b(fptr, ntodo, incre, (double *) buffer, status); break; case (TSTRING): /* numerical column in an ASCII table */ if (cform[1] != 's') /* "%s" format is a string */ { ffi8fstr(&array[next], ntodo, scale, zero, cform, twidth, (char *) buffer, status); if (incre == twidth) /* contiguous bytes */ ffpbyt(fptr, ntodo * twidth, buffer, status); else ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer, status); break; } /* can't write to string column, so fall thru to default: */ default: /* error trap */ sprintf(message, "Cannot write numbers to column %d which has format %s", colnum,tform); ffpmsg(message); if (hdutype == ASCII_TBL) return(*status = BAD_ATABLE_FORMAT); else return(*status = BAD_BTABLE_FORMAT); } /* End of switch block */ /*-------------------------*/ /* Check for fatal error */ /*-------------------------*/ if (*status > 0) /* test for error during previous write operation */ { sprintf(message, "Error writing elements %.0f thru %.0f of input data array (ffpclj).", (double) (next+1), (double) (next+ntodo)); ffpmsg(message); return(*status); } /*--------------------------------------------*/ /* increment the counters for the next loop */ /*--------------------------------------------*/ remain -= ntodo; if (remain) { next += ntodo; elemnum += ntodo; if (elemnum == repeat) /* completed a row; start on next row */ { elemnum = 0; rownum++; } } } /* End of main while Loop */ /*--------------------------------*/ /* check for numerical overflow */ /*--------------------------------*/ if (*status == OVERFLOW_ERR) { ffpmsg( "Numerical overflow during type conversion while writing FITS data."); *status = NUM_OVERFLOW; } return(*status); } /*--------------------------------------------------------------------------*/ int ffpcnjj(fitsfile *fptr, /* I - FITS file pointer */ int colnum, /* I - number of column to write (1 = 1st col) */ LONGLONG firstrow, /* I - first row to write (1 = 1st row) */ LONGLONG firstelem, /* I - first vector element to write (1 = 1st) */ LONGLONG nelem, /* I - number of values to write */ LONGLONG *array, /* I - array of values to write */ LONGLONG nulvalue, /* I - value used to flag undefined pixels */ int *status) /* IO - error status */ /* Write an array of elements to the specified column of a table. Any input pixels equal to the value of nulvalue will be replaced by the appropriate null value in the output FITS file. The input array of values will be converted to the datatype of the column and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary */ { tcolumn *colptr; long ngood = 0, nbad = 0, ii; LONGLONG repeat, first, fstelm, fstrow; int tcode, overflow = 0; if (*status > 0) return(*status); /* reset position to the correct HDU if necessary */ if (fptr->HDUposition != (fptr->Fptr)->curhdu) { ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status); } else if ((fptr->Fptr)->datastart == DATA_UNDEFINED) { if ( ffrdef(fptr, status) > 0) /* rescan header */ return(*status); } colptr = (fptr->Fptr)->tableptr; /* point to first column */ colptr += (colnum - 1); /* offset to correct column structure */ tcode = colptr->tdatatype; if (tcode > 0) repeat = colptr->trepeat; /* repeat count for this column */ else repeat = firstelem -1 + nelem; /* variable length arrays */ /* if variable length array, first write the whole input vector, then go back and fill in the nulls */ if (tcode < 0) { if (ffpcljj(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) { if (*status == NUM_OVERFLOW) { /* ignore overflows, which are possibly the null pixel values */ /* overflow = 1; */ *status = 0; } else { return(*status); } } } /* absolute element number in the column */ first = (firstrow - 1) * repeat + firstelem; for (ii = 0; ii < nelem; ii++) { if (array[ii] != nulvalue) /* is this a good pixel? */ { if (nbad) /* write previous string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0) return(*status); nbad=0; } ngood = ngood +1; /* the consecutive number of good pixels */ } else { if (ngood) /* write previous string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ if (ffpcljj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status) > 0) { if (*status == NUM_OVERFLOW) { overflow = 1; *status = 0; } else { return(*status); } } } ngood=0; } nbad = nbad +1; /* the consecutive number of bad pixels */ } } /* finished loop; now just write the last set of pixels */ if (ngood) /* write last string of good pixels */ { fstelm = ii - ngood + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ if (tcode > 0) { /* variable length arrays have already been written */ ffpcljj(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status); } } else if (nbad) /* write last string of bad pixels */ { fstelm = ii - nbad + first; /* absolute element number */ fstrow = (fstelm - 1) / repeat + 1; /* starting row number */ fstelm = fstelm - (fstrow - 1) * repeat; /* relative number */ ffpclu(fptr, colnum, fstrow, fstelm, nbad, status); } if (*status <= 0) { if (overflow) { *status = NUM_OVERFLOW; } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fi1(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ unsigned char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < 0) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (input[ii] > UCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DUCHAR_MIN) { *status = OVERFLOW_ERR; output[ii] = 0; } else if (dvalue > DUCHAR_MAX) { *status = OVERFLOW_ERR; output[ii] = UCHAR_MAX; } else output[ii] = (unsigned char) (dvalue + .5); } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fi2(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ short *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < SHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (input[ii] > SHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else output[ii] = (short) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DSHRT_MIN) { *status = OVERFLOW_ERR; output[ii] = SHRT_MIN; } else if (dvalue > DSHRT_MAX) { *status = OVERFLOW_ERR; output[ii] = SHRT_MAX; } else { if (dvalue >= 0) output[ii] = (short) (dvalue + .5); else output[ii] = (short) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fi4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ INT32BIT *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { if (input[ii] < INT32_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (input[ii] > INT32_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else output[ii] = (INT32BIT) input[ii]; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DINT_MIN) { *status = OVERFLOW_ERR; output[ii] = INT32_MIN; } else if (dvalue > DINT_MAX) { *status = OVERFLOW_ERR; output[ii] = INT32_MAX; } else { if (dvalue >= 0) output[ii] = (INT32BIT) (dvalue + .5); else output[ii] = (INT32BIT) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fi8(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ LONGLONG *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = input[ii]; } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; if (dvalue < DLONGLONG_MIN) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MIN; } else if (dvalue > DLONGLONG_MAX) { *status = OVERFLOW_ERR; output[ii] = LONGLONG_MAX; } else { if (dvalue >= 0) output[ii] = (LONGLONG) (dvalue + .5); else output[ii] = (LONGLONG) (dvalue - .5); } } } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fr4(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ float *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (float) ((input[ii] - zero) / scale); } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fr8(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ double *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do datatype conversion and scaling if required. */ { long ii; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) output[ii] = (double) input[ii]; } else { for (ii = 0; ii < ntodo; ii++) output[ii] = (input[ii] - zero) / scale; } return(*status); } /*--------------------------------------------------------------------------*/ int ffi8fstr(LONGLONG *input, /* I - array of values to be converted */ long ntodo, /* I - number of elements in the array */ double scale, /* I - FITS TSCALn or BSCALE value */ double zero, /* I - FITS TZEROn or BZERO value */ char *cform, /* I - format for output string values */ long twidth, /* I - width of each field, in chars */ char *output, /* O - output array of converted values */ int *status) /* IO - error status */ /* Copy input to output prior to writing output to a FITS file. Do scaling if required. */ { long ii; double dvalue; if (scale == 1. && zero == 0.) { for (ii = 0; ii < ntodo; ii++) { sprintf(output, cform, (double) input[ii]); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } else { for (ii = 0; ii < ntodo; ii++) { dvalue = (input[ii] - zero) / scale; sprintf(output, cform, dvalue); output += twidth; if (*output) /* if this char != \0, then overflow occurred */ *status = OVERFLOW_ERR; } } return(*status); } indi-0.5/src/cfitsio/checksum.c0000644000175000017500000004226410610474374014324 0ustar jrjr/* This file, checksum.c, contains the checksum-related routines in the */ /* FITSIO library. */ /* The FITSIO software was written by William Pence at the High Energy */ /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */ /* Goddard Space Flight Center. */ #include #include #include "fitsio2.h" /*------------------------------------------------------------------------*/ int ffcsum(fitsfile *fptr, /* I - FITS file pointer */ long nrec, /* I - number of 2880-byte blocks to sum */ unsigned long *sum, /* IO - accumulated checksum */ int *status) /* IO - error status */ /* Calculate a 32-bit 1's complement checksum of the FITS 2880-byte blocks. This routine is based on the C algorithm developed by Rob Seaman at NOAO that was presented at the 1994 ADASS conference, published in the Astronomical Society of the Pacific Conference Series. This uses a 32-bit 1's complement checksum in which the overflow bits are permuted back into the sum and therefore all bit positions are sampled evenly. */ { long ii, jj; unsigned short sbuf[1440]; unsigned long hi, lo, hicarry, locarry; if (*status > 0) return(*status); /* Sum the specified number of FITS 2880-byte records. This assumes that the FITSIO file pointer points to the start of the records to be summed. Read each FITS block as 1440 short values (do byte swapping if needed). */ for (jj = 0; jj < nrec; jj++) { ffgbyt(fptr, 2880, sbuf, status); #if BYTESWAPPED ffswap2( (short *)sbuf, 1440); /* reverse order of bytes in each value */ #endif hi = (*sum >> 16); lo = *sum & 0xFFFF; for (ii = 0; ii < 1440; ii += 2) { hi += sbuf[ii]; lo += sbuf[ii+1]; } hicarry = hi >> 16; /* fold carry bits in */ locarry = lo >> 16; while (hicarry | locarry) { hi = (hi & 0xFFFF) + locarry; lo = (lo & 0xFFFF) + hicarry; hicarry = hi >> 16; locarry = lo >> 16; } *sum = (hi << 16) + lo; } return(*status); } /*-------------------------------------------------------------------------*/ void ffesum(unsigned long sum, /* I - accumulated checksum */ int complm, /* I - = 1 to encode complement of the sum */ char *ascii) /* O - 16-char ASCII encoded checksum */ /* encode the 32 bit checksum by converting every 2 bits of each byte into an ASCII character (32 bit word encoded as 16 character string). Only ASCII letters and digits are used to encode the values (no ASCII punctuation characters). If complm=TRUE, then the complement of the sum will be encoded. This routine is based on the C algorithm developed by Rob Seaman at NOAO that was presented at the 1994 ADASS conference, published in the Astronomical Society of the Pacific Conference Series. */ { unsigned int exclude[13] = { 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60 }; unsigned long mask[4] = { 0xff000000, 0xff0000, 0xff00, 0xff }; int offset = 0x30; /* ASCII 0 (zero) */ unsigned long value; int byte, quotient, remainder, ch[4], check, ii, jj, kk; char asc[32]; if (complm) value = 0xFFFFFFFF - sum; /* complement each bit of the value */ else value = sum; for (ii = 0; ii < 4; ii++) { byte = (value & mask[ii]) >> (24 - (8 * ii)); quotient = byte / 4 + offset; remainder = byte % 4; for (jj = 0; jj < 4; jj++) ch[jj] = quotient; ch[0] += remainder; for (check = 1; check;) /* avoid ASCII punctuation */ for (check = 0, kk = 0; kk < 13; kk++) for (jj = 0; jj < 4; jj += 2) if ((unsigned char) ch[jj] == exclude[kk] || (unsigned char) ch[jj+1] == exclude[kk]) { ch[jj]++; ch[jj+1]--; check++; } for (jj = 0; jj < 4; jj++) /* assign the bytes */ asc[4*jj+ii] = ch[jj]; } for (ii = 0; ii < 16; ii++) /* shift the bytes 1 to the right */ ascii[ii] = asc[(ii+15)%16]; ascii[16] = '\0'; } /*-------------------------------------------------------------------------*/ unsigned long ffdsum(char *ascii, /* I - 16-char ASCII encoded checksum */ int complm, /* I - =1 to decode complement of the */ unsigned long *sum) /* O - 32-bit checksum */ /* decode the 16-char ASCII encoded checksum into an unsigned 32-bit long. If complm=TRUE, then the complement of the sum will be decoded. This routine is based on the C algorithm developed by Rob Seaman at NOAO that was presented at the 1994 ADASS conference, published in the Astronomical Society of the Pacific Conference Series. */ { char cbuf[16]; unsigned long hi = 0, lo = 0, hicarry, locarry; int ii; /* remove the permuted FITS byte alignment and the ASCII 0 offset */ for (ii = 0; ii < 16; ii++) { cbuf[ii] = ascii[(ii+1)%16]; cbuf[ii] -= 0x30; } for (ii = 0; ii < 16; ii += 4) { hi += (cbuf[ii] << 8) + cbuf[ii+1]; lo += (cbuf[ii+2] << 8) + cbuf[ii+3]; } hicarry = hi >> 16; locarry = lo >> 16; while (hicarry || locarry) { hi = (hi & 0xFFFF) + locarry; lo = (lo & 0xFFFF) + hicarry; hicarry = hi >> 16; locarry = lo >> 16; } *sum = (hi << 16) + lo; if (complm) *sum = 0xFFFFFFFF - *sum; /* complement each bit of the value */ return(*sum); } /*------------------------------------------------------------------------*/ int ffpcks(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Create or update the checksum keywords in the CHDU. These keywords provide a checksum verification of the FITS HDU based on the ASCII coded 1's complement checksum algorithm developed by Rob Seaman at NOAO. */ { char datestr[20], checksum[FLEN_VALUE], datasum[FLEN_VALUE]; char comm[FLEN_COMMENT], chkcomm[FLEN_COMMENT], datacomm[FLEN_COMMENT]; int tstatus; long nrec; LONGLONG headstart, datastart, dataend; unsigned long dsum, olddsum, sum; double tdouble; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* generate current date string and construct the keyword comments */ ffgstm(datestr, NULL, status); strcpy(chkcomm, "HDU checksum updated "); strcat(chkcomm, datestr); strcpy(datacomm, "data unit checksum updated "); strcat(datacomm, datestr); /* write the CHECKSUM keyword if it does not exist */ tstatus = *status; if (ffgkys(fptr, "CHECKSUM", checksum, comm, status) == KEY_NO_EXIST) { *status = tstatus; strcpy(checksum, "0000000000000000"); ffpkys(fptr, "CHECKSUM", checksum, chkcomm, status); } /* write the DATASUM keyword if it does not exist */ tstatus = *status; if (ffgkys(fptr, "DATASUM", datasum, comm, status) == KEY_NO_EXIST) { *status = tstatus; olddsum = 0; ffpkys(fptr, "DATASUM", " 0", datacomm, status); /* set the CHECKSUM keyword as undefined, if it isn't already */ if (strcmp(checksum, "0000000000000000") ) { strcpy(checksum, "0000000000000000"); ffmkys(fptr, "CHECKSUM", checksum, chkcomm, status); } } else { /* decode the datasum into an unsigned long variable */ /* olddsum = strtoul(datasum, 0, 10); doesn't work on SUN OS */ tdouble = atof(datasum); olddsum = (unsigned long) tdouble; } /* close header: rewrite END keyword and following blank fill */ /* and re-read the required keywords to determine the structure */ if (ffrdef(fptr, status) > 0) return(*status); if ((fptr->Fptr)->heapsize > 0) ffuptf(fptr, status); /* update the variable length TFORM values */ /* write the correct data fill values, if they are not already correct */ if (ffpdfl(fptr, status) > 0) return(*status); /* calc size of data unit, in FITS 2880-byte blocks */ if (ffghadll(fptr, &headstart, &datastart, &dataend, status) > 0) return(*status); nrec = (long) ((dataend - datastart) / 2880); dsum = 0; if (nrec > 0) { /* accumulate the 32-bit 1's complement checksum */ ffmbyt(fptr, datastart, REPORT_EOF, status); if (ffcsum(fptr, nrec, &dsum, status) > 0) return(*status); } if (dsum != olddsum) { /* update the DATASUM keyword with the correct value */ sprintf(datasum, "%lu", dsum); ffmkys(fptr, "DATASUM", datasum, datacomm, status); /* set the CHECKSUM keyword as undefined, if it isn't already */ if (strcmp(checksum, "0000000000000000") ) { strcpy(checksum, "0000000000000000"); ffmkys(fptr, "CHECKSUM", checksum, chkcomm, status); } } if (strcmp(checksum, "0000000000000000") ) { /* check if CHECKSUM is still OK; move to the start of the header */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* accumulate the header checksum into the previous data checksum */ nrec = (long) ((datastart - headstart) / 2880); sum = dsum; if (ffcsum(fptr, nrec, &sum, status) > 0) return(*status); if (sum == 0 || sum == 0xFFFFFFFF) return(*status); /* CHECKSUM is correct */ /* Zero the CHECKSUM and recompute the new value */ ffmkys(fptr, "CHECKSUM", "0000000000000000", chkcomm, status); } /* move to the start of the header */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* accumulate the header checksum into the previous data checksum */ nrec = (long) ((datastart - headstart) / 2880); sum = dsum; if (ffcsum(fptr, nrec, &sum, status) > 0) return(*status); /* encode the COMPLEMENT of the checksum into a 16-character string */ ffesum(sum, TRUE, checksum); /* update the CHECKSUM keyword value with the new string */ ffmkys(fptr, "CHECKSUM", checksum, "&", status); return(*status); } /*------------------------------------------------------------------------*/ int ffupck(fitsfile *fptr, /* I - FITS file pointer */ int *status) /* IO - error status */ /* Update the CHECKSUM keyword value. This assumes that the DATASUM keyword exists and has the correct value. */ { char datestr[20], chkcomm[FLEN_COMMENT], comm[FLEN_COMMENT]; char checksum[FLEN_VALUE], datasum[FLEN_VALUE]; int tstatus; long nrec; LONGLONG headstart, datastart, dataend; unsigned long sum, dsum; double tdouble; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* generate current date string and construct the keyword comments */ ffgstm(datestr, NULL, status); strcpy(chkcomm, "HDU checksum updated "); strcat(chkcomm, datestr); /* get the DATASUM keyword and convert it to a unsigned long */ if (ffgkys(fptr, "DATASUM", datasum, comm, status) == KEY_NO_EXIST) { ffpmsg("DATASUM keyword not found (ffupck"); return(*status); } tdouble = atof(datasum); /* read as a double as a workaround */ dsum = (unsigned long) tdouble; /* get size of the HDU */ if (ffghadll(fptr, &headstart, &datastart, &dataend, status) > 0) return(*status); /* get the checksum keyword, if it exists */ tstatus = *status; if (ffgkys(fptr, "CHECKSUM", checksum, comm, status) == KEY_NO_EXIST) { *status = tstatus; strcpy(checksum, "0000000000000000"); ffpkys(fptr, "CHECKSUM", checksum, chkcomm, status); } else { /* check if CHECKSUM is still OK */ /* rewrite END keyword and following blank fill */ if (ffwend(fptr, status) > 0) return(*status); /* move to the start of the header */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* accumulate the header checksum into the previous data checksum */ nrec = (long) ((datastart - headstart) / 2880); sum = dsum; if (ffcsum(fptr, nrec, &sum, status) > 0) return(*status); if (sum == 0 || sum == 0xFFFFFFFF) return(*status); /* CHECKSUM is already correct */ /* Zero the CHECKSUM and recompute the new value */ ffmkys(fptr, "CHECKSUM", "0000000000000000", chkcomm, status); } /* move to the start of the header */ ffmbyt(fptr, headstart, REPORT_EOF, status); /* accumulate the header checksum into the previous data checksum */ nrec = (long) ((datastart - headstart) / 2880); sum = dsum; if (ffcsum(fptr, nrec, &sum, status) > 0) return(*status); /* encode the COMPLEMENT of the checksum into a 16-character string */ ffesum(sum, TRUE, checksum); /* update the CHECKSUM keyword value with the new string */ ffmkys(fptr, "CHECKSUM", checksum, "&", status); return(*status); } /*------------------------------------------------------------------------*/ int ffvcks(fitsfile *fptr, /* I - FITS file pointer */ int *datastatus, /* O - data checksum status */ int *hdustatus, /* O - hdu checksum status */ /* 1 verification is correct */ /* 0 checksum keyword is not present */ /* -1 verification not correct */ int *status) /* IO - error status */ /* Verify the HDU by comparing the value of the computed checksums against the values of the DATASUM and CHECKSUM keywords if they are present. */ { int tstatus; double tdouble; unsigned long datasum, hdusum, olddatasum; char chksum[FLEN_VALUE], comm[FLEN_COMMENT]; if (*status > 0) /* inherit input status value if > 0 */ return(*status); *datastatus = -1; *hdustatus = -1; tstatus = *status; if (ffgkys(fptr, "CHECKSUM", chksum, comm, status) == KEY_NO_EXIST) { *hdustatus = 0; /* CHECKSUM keyword does not exist */ *status = tstatus; } if (chksum[0] == '\0') *hdustatus = 0; /* all blank checksum means it is undefined */ if (ffgkys(fptr, "DATASUM", chksum, comm, status) == KEY_NO_EXIST) { *datastatus = 0; /* DATASUM keyword does not exist */ *status = tstatus; } if (chksum[0] == '\0') *datastatus = 0; /* all blank checksum means it is undefined */ if ( *status > 0 || (!(*hdustatus) && !(*datastatus)) ) return(*status); /* return if neither keywords exist */ /* convert string to unsigned long */ /* olddatasum = strtoul(chksum, 0, 10); doesn't work w/ gcc on SUN OS */ /* sscanf(chksum, "%u", &olddatasum); doesn't work w/ cc on VAX/VMS */ tdouble = atof(chksum); /* read as a double as a workaround */ olddatasum = (unsigned long) tdouble; /* calculate the data checksum and the HDU checksum */ if (ffgcks(fptr, &datasum, &hdusum, status) > 0) return(*status); if (*datastatus) if (datasum == olddatasum) *datastatus = 1; if (*hdustatus) if (hdusum == 0 || hdusum == 0xFFFFFFFF) *hdustatus = 1; return(*status); } /*------------------------------------------------------------------------*/ int ffgcks(fitsfile *fptr, /* I - FITS file pointer */ unsigned long *datasum, /* O - data checksum */ unsigned long *hdusum, /* O - hdu checksum */ int *status) /* IO - error status */ /* calculate the checksums of the data unit and the total HDU */ { long nrec; LONGLONG headstart, datastart, dataend; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get size of the HDU */ if (ffghadll(fptr, &headstart, &datastart, &dataend, status) > 0) return(*status); nrec = (long) ((dataend - datastart) / 2880); *datasum = 0; if (nrec > 0) { /* accumulate the 32-bit 1's complement checksum */ ffmbyt(fptr, datastart, REPORT_EOF, status); if (ffcsum(fptr, nrec, datasum, status) > 0) return(*status); } /* move to the start of the header and calc. size of header */ ffmbyt(fptr, headstart, REPORT_EOF, status); nrec = (long) ((datastart - headstart) / 2880); /* accumulate the header checksum into the previous data checksum */ *hdusum = *datasum; ffcsum(fptr, nrec, hdusum, status); return(*status); } indi-0.5/src/examples/0000755000175000017500000000000011017761434012522 5ustar jrjrindi-0.5/src/examples/ngc1316o.fits0000644000175000017500000103400010605175713014651 0ustar jrjrSIMPLE = T / file does conform to FITS standard BITPIX = 16 / number of bits per data pixel NAXIS = 2 / number of data axes NAXIS1 = 440 / length of data axis 1 NAXIS2 = 300 / length of data axis 2 EXTEND = T / FITS dataset may contain extensions COMMENT FITS (Flexible Image Transport System) format defined in Astronomy andCOMMENT Astrophysics Supplement Series v44/p363, v44/p371, v73/p359, v73/p365.COMMENT Contact the NASA Science Office of Standards and Technology for the COMMENT FITS Definition document #100 and other FITS information. COMMENT FITS (Flexible Image Transport System) format defined in Astronomy andCOMMENT Astrophysics Supplement Series v44/p363, v44/p371, v73/p359, v73/p365.COMMENT Contact the NASA Science Office of Standards and Technology for the COMMENT FITS Definition document #100 and other FITS information. OBJECT = 'NGC 1316' TELESCOP= 'Optical ' INSTRUME= ' ' OBSERVER= ' ' DATE-MAP= '24/03/94' EQUINOX = 1950.0 / EPOCH OF RA DEC DATAMAX = 1.037890381E+03 /MAX PIXEL VALUE DATAMIN = -5.450668335E+00 /MIN PIXEL VALUE CTYPE1 = 'RA---SIN' CRVAL1 = 5.01966661513E+01 / CDELT1 = -1.944444492E-03 / CRPIX1 = 2.260000000000000E+02 CROTA1 = 0.000000000E+00 / CTYPE2 = 'DEC--SIN' CRVAL2 = -3.73856168315E+01 / CDELT2 = 1.944444492E-03 / CRPIX2 = 1.470000000000000E+02 CROTA2 = 0.000000000E+00 / HISTORY -------------------------------------------------------------------- HISTORY /Begin "HISTORY" information found in fits tape header by IMLOD HISTORY BLOCKED = T /TAPE MAY BE BLOCKED HISTORY /-------------------------------------------------------------------- HISTORY /BEGIN "HISTORY" INFORMATION FOUND IN FITS TAPE HEADER BY IMLOD HISTORY /END FITS TAPE HEADER "HISTORY" INFORMATION HISTORY /-------------------------------------------------------------------- HISTORY IMLOD OUTNAME ='NGC1316 ' OUTCLASS ='OPT ' HISTORY IMLOD OUTSEQ = 1 INTAPE = 3 OUTDISK= 1 HISTORY IMLOD RELEASE = '15APR89' HISTORY TRANS RELEASE ='15APR89 ' /********* START 17-FEB-1989 08:47:28 HISTORY TRANS INNAME='NGC1316 ' INCLASS='OPT ' HISTORY TRANS INSEQ= 1 INDISK= 1 HISTORY TRANS OUTNAME='NGC1316/G ' OUTCLASS='OPT ' HISTORY TRANS OUTSEQ= 1 OUTDISK= 1 HISTORY TRANS BLC= 1., 1., 1., 1., 1., 1., 1. / INPUT IMAGE HISTORY TRANS TRC= 2001.,1401., 1., 1., 1., 1., 1. / INPUT IMAGE HISTORY TRANS TRANCOD='1-2 ' / OUTPUT AXIS ORDER HISTORY CNTR VERSION= 1 / PLOT FILE CREATED 17-FEB-1989 14:03:52 HISTORY CNTR VERSION= 2 / PLOT FILE CREATED 17-FEB-1989 14:07:08 HISTORY CNTR VERSION= 3 / PLOT FILE CREATED 17-FEB-1989 14:08:35 HISTORY PUTHEAD CTYPE1 =' ' / OLD HISTORY PUTHEAD CTYPE1 ='RA--TAN ' / NEW HISTORY PUTHEAD CTYPE1 ='RA--TAN ' / OLD HISTORY PUTHEAD CTYPE1 ='RA---TAN' / NEW HISTORY PUTHEAD CTYPE2 =' ' / OLD HISTORY PUTHEAD CTYPE2 ='DEC--TAN' / NEW HISTORY PUTHEAD CRVAL1 = 0.000000000E+00 / OLD HISTORY PUTHEAD CRVAL1 = 5.019667053E+01 / NEW HISTORY PUTHEAD CRVAL2 = 0.000000000E+00 / OLD HISTORY PUTHEAD CRVAL2 = -3.738555908E+01 / NEW HISTORY PUTHEAD CRPIX1 = 1.00000E+03 / OLD HISTORY PUTHEAD CRPIX1 = 7.02000E+02 / NEW HISTORY PUTHEAD CRPIX1 = 7.02000E+02 / OLD HISTORY PUTHEAD CRPIX1 = 9.97000E+02 / NEW HISTORY PUTHEAD CDELT1 = 1.00000E+00 / OLD HISTORY PUTHEAD CDELT1 = 3.05600E-02 / NEW HISTORY PUTHEAD CDELT2 = -1.00000E+00 / OLD HISTORY PUTHEAD CDELT2 = 3.05600E-02 / NEW HISTORY PUTHEAD CDELT2 = 3.05600E-02 / OLD HISTORY PUTHEAD CDELT2 = 5.09333E-04 / NEW HISTORY PUTHEAD CDELT2 = 5.09333E-04 / OLD HISTORY PUTHEAD CDELT2 = 5.09333E-04 / NEW HISTORY PUTHEAD CDELT1 = 3.05600E-02 / OLD HISTORY PUTHEAD CDELT1 = -5.09333E-04 / NEW HISTORY PUTHEAD CROTA1 = 0.00000E+00 / OLD HISTORY PUTHEAD CROTA1 = 3.00000E-01 / NEW HISTORY PUTHEAD CROTA1 = 3.00000E-01 / OLD HISTORY PUTHEAD CROTA1 = 0.00000E+00 / NEW HISTORY PUTHEAD CROTA1 = 0.00000E+00 / OLD HISTORY PUTHEAD CROTA1 = 3.00000E-01 / NEW HISTORY PUTHEAD CROTA1 = 3.00000E-01 / OLD HISTORY PUTHEAD CROTA1 = 5.00000E+00 / NEW HISTORY PUTHEAD CROTA2 = 0.00000E+00 / OLD HISTORY PUTHEAD CROTA2 = 5.00000E+00 / NEW HISTORY PUTHEAD CROTA1 = 5.00000E+00 / OLD HISTORY PUTHEAD CROTA1 = 0.00000E+00 / NEW HISTORY PUTHEAD CROTA1 = 0.00000E+00 / OLD HISTORY PUTHEAD CROTA1 = 0.00000E+00 / NEW HISTORY PUTHEAD CROTA2 = 5.00000E+00 / OLD HISTORY PUTHEAD CROTA2 = 0.00000E+00 / NEW HISTORY PUTHEAD CROTA1 = 0.00000E+00 / OLD HISTORY PUTHEAD CROTA1 = 1.00000E+00 / NEW HISTORY PUTHEAD CROTA1 = 1.00000E+00 / OLD HISTORY PUTHEAD CROTA1 = 0.00000E+00 / NEW HISTORY PUTHEAD CROTA2 = 0.00000E+00 / OLD HISTORY PUTHEAD CROTA2 = 1.00000E+00 / NEW HISTORY PUTHEAD CROTA2 = 1.00000E+00 / OLD HISTORY PUTHEAD CROTA2 = 3.00000E-01 / NEW HISTORY AIPS IMNAME='NGC1316/G ' IMCLASS='OPT ' IMSEQ= 1 / HISTORY AIPS USERNO= 51 / HISTORY /END FITS tape header "HISTORY" information HISTORY -------------------------------------------------------------------- HISTORY IMLOD OUTNAME =' HISTORY IMLOD OUTSEQ = 0 INTAPE = 1 OUTDISK= 3 HISTORY IMLOD RELEASE = '15JUL94' HISTORY SUBIM RELEASE ='15JUL94 ' /********* Start 24-MAR-1994 10:58:33 HISTORY SUBIM INNAME='NGC1316/G ' INCLASS='OPT ' HISTORY SUBIM INSEQ= 1 INDISK= 1 HISTORY SUBIM INTYPE ='MA' USERID= 100 HISTORY SUBIM OUTNAME='NGC1316/G ' OUTCLASS='SMOOTH' HISTORY SUBIM OUTSEQ= 1 OUTDISK= 1 HISTORY SUBIM BLC = 1, 1, 1, 1, 1, 1, 1 HISTORY SUBIM TRC = 2001, 1401, 1, 1, 1, 1, 1 HISTORY SUBIM XINC = 4 YINC = 4 HISTORY SUBIM OPCODE = 'AVE ' HISTORY HGEOM RELEASE ='15JUL94 ' /********* Start 24-MAR-1994 10:59:29 HISTORY HGEOM INNAME='NGC1316/G ' INCLASS='SMOOTH' HISTORY HGEOM INSEQ= 1 INDISK= 1 HISTORY HGEOM IN2NAME='FORNAX ' IN2CLASS='I ' HISTORY HGEOM IN2SEQ= 2 IN2DISK= 1 HISTORY HGEOM OUTNAME=' ' OUTCLASS='Optic ' HISTORY HGEOM OUTSEQ= 1 OUTDISK= 1 HISTORY HGEOM BLC = 1, 1, 1, 1, 1, 1, 1 HISTORY HGEOM TRC = 501, 351, 1, 1, 1, 1, 1 HISTORY HGEOM IMSIZE = 512, 512 / Output image size HISTORY HGEOM / Interpolation order used was BiCubic HISTORY HGEOM / Indeterminate pixels filled with magic values HISTORY HGEOM / 74383 Pixels blanked due to memory limits or geometry HISTORY HGEOM / 0 Pixels blanked due to input blanked pixels ORIGIN = 'AIPSGorilla (NRAOCV IPX) 15JUL94' / DATE = '24/03/94' / File written on dd/mm/yy HISTORY AIPS IMNAME='NGC1316/G ' IMCLASS='Optic ' IMSEQ= 1 / HISTORY AIPS USERNO= 100 / END  $0;J{²Y_diou}…“›¦¯¹ÁÀÄÇÈÈÈÈËÌÌÏÏÏÓÓÑÒÓÓÕÖÕÖ×ØØØÙÚÚÛÚÜÝÝÜÛÜÝÜÝÝßáÞßàßßáàßàááâáÝàáâäçèéëæååääãããæäéäâãäãääââãåãããããäãááàßàáàáâääååääåææççéìíïììëèçæçèçæåäåæååäåãååãèåãâåçããäãäåçæçèççèææçèæèáãèèææææèèæçæååååäçåææææéæäåäåååæåäææåååæææåçæææçææçåçèèèèççééææååæéèæéèçèèçæååçèæåãäååäääåääãäåäãââäãàáâáààáâããâãããããäãääååäâåèýçâãäâãââãàßâãäààààÞààáßàÞààÝÝÞàáàààßÞßåõÜÞÞÞÞÜÞÞÞÝÛÛÞßÝÜÜÛÚÚÙÝÙØØØ×Ø×Ö×ÖÕÓÔÖÔÓÑÒÓÊÊÊÊÇÆÅÅý·°¦Ÿ—‡}wrnhc`[VN ".9EVZc^chnsz€‰’𥱷»ÁÅÅÇÈÉÊÊËÌÎÎÑÐÓÓÒÒÒÔÕÕÖ××ÙØÙÚÙÚÝÝÞÜÞÝÝÜÝÞÞÞßßÝàæáÞàáÞàààáãáãâáâêêåçääåâââáãáâáãããââäãâãããââãââãâáâáààâãâããããäääåååçééèêêééèççççéèèéæåååææåææçòçäâãæääääæçèççèççéçèçëçãVæççççççæççæçéææææçæææåæçååæååææåæååçååèèççæçéèççèèçèéêèééèççæéèæåëìçøöééæççæååååçåååæåääæååååçäããããåãâãäáâãâääãäæåäääåæææäåäååßãâãääãããðøìâåæáââáàâàáàßßàÞõôÞáààáàßßßÞÞßáÞÞÝÞÞßÝÝÜÞâáÞÝÜÛÝáßÛÚÚÚÙÙÙ×ÜÙØÖÖáâ×ÓÓ×ÍÍËÊÉÊÈÌÈý¶®¥•‡‚|vrmgb^ZT*6AJSUXbflsx~†–œ¡¬´¹¿ÃÆÇÇÈÌËÏÓÜÑÐÑÑÖÔÓÔÔÔÕÕÖ×ÖרÚÚÚÛÜÛÞßÞÝÜÜÝÞßàÞÜÝÞÞßÞàáßàààââáâââáâãããããããäâããâáâãâãããääääãããããââÞããâåäããæäââäããååååæèééèééééèéêéèéèèéçæææççåççèíçæåäåæææææçèèèèèçèíèèèèåþçèçæçéèæææçæéèççæççææææççççåææåççæêçæåèéçèèéééèèèééèêîïéèçèçêéìèææëíéèéíñëèæçæçæåçåæçææåæææåãäååãääååâääääääçèäæéçåæææçæèååæååæãããääååãÿR8ÜäãâããâáäâáàÞàáÞù÷ÞààßààààßÝàßàÞÞßÞÞÞÝÝÞàáßÞÝÜÜÝáßÜÚÜÜÛÚØ×ÛÙØ×ÚáßÖÔÓ×ÏÍÌÌËÊÈÉÇÄÁº³«¢›”†€zvusfb^Y '4?GNUZ_flrw}„Œš¡¦²º¿ÄÅÆÈÉÉÊËÎÏÒÓÑÑÒÖÕÕÖÕÕÖØàâÙÙÚÚÛÝÜÜÝÝáßÜÜÝßÞÞÝÞßßßßßÞßàáááâãäâââããããããääãâãäääãââãããæææææåãäåääãëåãâéæåãâããääääåååæèêççèèèéèéêêèææççåææåææçææççêèæçèèæèèçæåæèèèèëçê íèééèãæééèçæçèæçççççèçææææççççææææææææèççèæçéçèèèçèéççèèèèéìëëêéçèèééëèèççççèå;èæææçææåäåææåçæåææåäääääääåäååäåææçéæäææåæææååæååæååæääääãäéåðVOÙäããäãââãâááßàáàßàááààààáàáàÞàßàßàßßßßÞÞÞâàÜÝÝÞÞßßÝÝÛÝÜÜÜÛÛÛÚÙÙÛÛØÖÕÔÔÒÎÍÍËÊÉÈÇÆÃÀ¹²ª¡š“‹„zwvkgb^ #.;EMSX^cjov{ƒ‹’œ¤ºÀ½ÄÆÆÇÊÊÉËÍÎÏÎÐÑÒÒÖÕÔÕÖÖÖÖßãØÙÚÛÜÜÛÜÝÝÞÝÝÝÞÞÞÝÝÝßßàßßßàßàáâäâáââãããääããçêääâããâãââããäæåææåäãããäåäùSåãâçääãâããäãäæåäæççéçæçèçëêéèéççæçæåææåääçææçéíìèççèæèèææççééèèêçêýìéêéèèèãåéêéèéèèçççæççææçêèçèçææååæææææçççéêééçêéèìêçèèèèèêìêèêçêèêêéêèéçèèçççîöñéççççææååèçåäæååççåååæçèåååææççåææåççåäæææèéççæææèæåæåååæåäèèäÞÞåäååçæäãâááâáàáàááààààááááàáßáßààààààààßÞááÞÞßßàßßÝÞÞÞßßßßÞÜÛÛÛÚÚÙ××ÔÓÔÒÏÍÍÊËÊÈÈÆÃ¾·±¨ ™‘Œ†~yvojfa  +7BKQW\chntzˆ‘™£¬»ÂÃÆÇÈÌÏÊËÌÎÑÐÐÏÔÕÔÕÖÕÖÖÕÖØÛÚÙÛÜÜÝÚÛÜÞßßÞÞÞßàÞÝÞÞÞßààßßàââááâáâäèåããååãããâããããâäæãåääääääääåäääåææéûåäãäääãååäåååççæèéæçèçççéíîèèèççèçççççæïÿæèèèêêìéèæææèèççèèêéèêééêæèêêîóë:åêééêëéèèçèçèçèçêéçèçææíîççèçæçèçèééêéìëéóïèèéééêëêéçèéêéëèèçèèêëéèèèçèèèèçççéèæåççèççååçèçææçèèææçóééææäççææææçççææçæååææææåæääææääåååååäåæççåããáâáãââááááááàáááâàáàáßáàßáááßáàßààßÞàßàßßÞßààãâáàßßÞÝÜÛÜÛר×ÖÔÓÑÏÎÌËÍÊÉÈÆÂ¼¶®¦Ÿ—‰ƒ}wtnjd (3?HOTZagmsx€†Ž˜ ©³ºÂÆÈÊËËËÉËÍÏÓÒÒÑÖÙ×ÕÙØÖÛÜÙÚÛÛÝÛÛÛà ðÞÝÞÞÞÞßßßßßàààáàáààçâáãâããáòêáãææããääååäåãåäîåãäåææååæååæååææåäåæçåãääåæçæççæææççèèèèæççèèééèèèççééèçèåøæêèéèéêééèçåçéèèéêêêéêéêìéèééøB æéçèêëéééêééééççèèèèèêéììææèéçèççèèèéëéëêîìééééêëééééèééééêèéçèëêèèéçèèççæèèêççææèçççææçèççëìæäææäé íèèæäåæççæççççææåæçåååçìåäåääåæææååææåæçäåååãáãããââáááááâââââââááááâààáâáààáãáßàßßßàßàáàââäãäãàââàßßßÝÙØØÙÖÓÓÑÑÎÍÍËËÉÈÅÁ»´­¥œ“‡|yrmh $0<FNSX^ejqw~†Œ•ž§¯¸¿ÆÊÈÉÊËÎÌÎÎÏÒÔÓÓÔ×ÖÕÚÙ×ÜÝÙÚÛÛÜÛÛÜÞìçáßàßÝÞßÞáààãâßàßàáàáââäááãåæäâãååååääãääåããäææäåäåææææåäæçæææææçæêçäåèææçæççççççççèëæèèèèèééèééèèéèçççæì÷èèèèçéééèéíøðééêìêêëëêêêìéééöû% ÷óíêéèéìíéêííêêééèèéêéééïíèèççèèèèéèëëêêìêêëëéèéêêëëéêêêéééêèëêéèééééèèèéèèèéèçççèçççèéèçæèèèçèéæçèéìçéëçêèæååéèæéëëêææçåæåååçôëçæåæèççæåæææåææææååãããåäãâáâãáâäãâãááââáâááààáâàààâåãàâáááááâãããäæåçåääåäââàÞÜÛÚÚØ×ÖÓÒÏÎÍÌÍËÉÐËÀ¹³¬£›“Œ‡€|wpk  +8CKQW\cinu}ƒŽ“›¤­¶½ÃÌÏÌÌÊÌÏÎÑÏÐÔÚÕÕ××ÕÖÚÙØÚÚÚÛÛÜÜÛÜÞàÜÞàßáßðæßàâáßèõìàáâäââáãâãæäæäããääååæåæåæôõäåçååååæææöñãåææçæçæèææççççèåæèçççççæççççéîçèëééêèéêééèçèèçèèèèééèéçèèëêééò øèëììèîöìêííëêëêûð÷õìêëëëëêìíéêíìéêêéêèéìêééíìéééèèèéèèêìëêíìëëëêééééëìêêëëëëêêëñéèééèéééèéêêêêíèèèççèççèèèçèèçæææçæåççéèèèçéççèçççæçêêéçåæåæççæèêíççåææåæææççææçææåäåããååãâââãããääããââáâáâáâááâãáàááâââââãââããäæäéêçèèéèèçåãâáßÝÜÜßâØÔÒÑÏÎÍÌËÊÒÏĽ¸±©¡™‘Œ…zuq '3?HOU[`gms{ˆ’™¢ª³»ÂÆËÎÔÕÌÌÌÏÐÏÑÕØÕÔØ×Ö×ÛÛÚÙÙÛÜÜÜÜÛÝßßßåèáààçãááááÞð üâããäââââãâæäããåããääåääåååèìíåèåäåæåçïìæåååìðåææææççæèèéíêèèéèççèéçèèèçççêééééèèèèèèèèçèéèééééééééðêëééëêêììéçöìéîóëëëëéëëêêêéêëìëééêééêèêëêéééêéèéêêêééèéëéêëééëììëêëêêëëééëêéêêëëëééí¶)ìçêëèèêêèèêêèéëèèêìéèçææèçççççèèèçæçççæçççêéææéèççèèéèèéèæçèçèæêèêçæçæåæåäåæææäæèæææääããääâãâááâããââãäãâãâááââàâãâááâáâãáâäãâääæçæìëêìííåçìêçåäâàßÞâçØÔÔÒÑÐÍÌÌËÌËÉüµ¯¦ž–Šƒ}yw ".<FMSX^djpw…Œ”ž¨±¸¿ÆÇÇÊÑÒËÌÍÎÎÏÑÒÒÕÕÖ×רÛÛÙÚÚÜÝÝÜÝÞÞÞÞÞéëáàáßßàáááàçñíââãããâáããâääãäæääääååäåæèååðçèååãåæççææççæççåèêèæææèêéâÃOéæèèççèèèèèéçèéèìéèèéééèéêèèèèéêêêêêéêçèéêééêéêëëëêéðúëéíôëñíìëìëëêééêêëëêéêéãêêëêêêêéêéééêêééééêìèêëçèìììîëêêëëêêêéòúîëêëëêéíYëéëêèèééééêéèéêéçêíóèèæçèæåèèèéêêèççéîæèêééèççèéêèççèéèèçææèèççççéçççææçæææææææçèçææåääååääãâãââääâáããâãääãæââââââáââããããââèðææêêéëíïðôú ññìèèåäâàÞÞ×ÕÔÒÒÒÏÍÌÌËËÊÇÁ»µ­¥•އ‚~z *6CLQV[ahmtz‚Б𤮶½ÃÆÇÈÊÊÊËÍÏÏÏÐÑÐÓ×ÖÖרÙÛÝÙÙÜÝÝÞÞÝÞÞßáåãçáàâááááááçíçáãâãæäâããäãâýóäçåäæåçêèççääæåæäæååèìèååææææçéçéçèççèìå`%ëèèèèèèççèèèééèèééèèêëééëêéèêìéêééééêêéêêìêêéêêêëëêëëëììííìøîììììðìéëíêéëëéê$éëìêêêìëìëêêëëëìëêêêêêéêìììíðîííììëëìéóþñëêëìïëêßëëëììéêêêëëêêéêêéééêîéèèééèçèéééêêèèéèêçèééêêéèèéèééèèèèèèèçèéêçèæèèèèçééèéèææçèééççèæåäåãääæääåäâãäââãâäæãããââââââáâãååäääãñ æéëíîñôô÷û ™XõöúþòêèãàßÝÙ×ÕÒÓÒÐÍÍÌÌËÉÈÅÀ»³«¤›”Œ†‚} &2>HOUZ`gmsy€‡Ž˜¢«³»ÂÇÈÉÊËËÌÍÎÑÒÑÒÒÓÕרØÙÛÛÛÝÛÜÝÞàÞßßàáæáäâäãâââäåäçìèäæååçåèäæäääôïåææææçèééçæåååçææçæçééèîìæçèçèèèèèèééììêéôðëðîéééééêèéêéêéêëêêêêììïøñêëíîêéêìéêîééêêéêëííìëììëìîíîíëíëîííòîíùòëìîöõêììéjèêëëëìïîìëëëìëìíëëìëìíìíîíîîíîîíîíëëîíëïîëëëìïëìíììëëìêééêëêéééééééèééèèèéèééèèèèèççêëçèèèèëéèèèèëêèééèçèèçççèçéèçïõëèèèèééèèèçèçééççççæåæääãåãåìèâãäåäâããäãââáááâããââãåæääääçìèéìîñõøúý wMþÿðëæáàÜÛÙÕÕÔÒÐÎÍÍÌËÊÊÈÅÀ¹±ª¢š‘Š…€ ".;EMRX_dkry~…—Ÿ¨±¸ÀÆËËÉÊËËÎÐÐÐÑÑÓÕÔÖÙÛÚÛÜÛÛÜÛÝÞÞßáááààáâáâæãããâäæçåäåååäåçåçåæåääæååæåæçççæææææçææçåååæææææééææçæçèçèèçèèçèèèåççþöèéèèéêèéêéèèèêééêêéèêëêêëêêêéééìêèéééêðíë÷ñêêëëëêêéêëéëéîêíðóîìïîêì  èììììëìéêìëîííëìêêééëëíïïííîîìïðîîîííííðïìîïêêëëëëëëëíîìëëêêêêéêêééééèéëééêéçéèèéêééééêèíòêíçèèèéêèèèèèëéççèèçèèçççæçèçè6¿áèèêèèèçççèèêèèçèèååæäãäåãáíøîâããäââãâãáâáäáâåæäãäåääææåæèêìïñõüþ  þôîéâàÜÚÛרÔÓÒÐÏÎÍÌÌËÉÉÆ¾·±¦Ÿ–ˆƒ )6AIPUZagnt{„Š“¢®®¶¾ÃÆÎÌÈÊÌÌÎÑÏÐÐÓÖÔÔÖØÚÚÚÚÚÛÝÝÝÞÞßÞßááæààááàáããâããâäåäãåååååæäãååäãäääåæååæççåæåçèçæçæääåæçææææçççççççéèççèéèéèèèèèîìëêèéééééèëëîëêêêëêêêêéëëêêêëëëëêêìëëêæLíëëëëëíìêëëëêëëðëììííîëðïëìíììëììëëëêëëìíìëëëêíëëëìñöóðîîïñòîíïííïê'èìîîëëëëëëìííëêëëëëêééêéêéèêéëééëèèééèêëêêêéêéìïëêéèéíêéééééééééèééééééì÷èéééé/÷çêéêïæãéèéèééêêééèèæåääååääæèççèääääääããååäããëçäååäåææèçèëîîñõúÿ (01) ÷ðêåáßÜÛÛÚÖÕÓÑÑÐÏÎÍÍÌËǾ¸¬¥•ŽŠ $1=GOUY_flsy‡’™¦¾·ºÂÅÆÉÊÊÌÍÍÏÏÏÒÒÔÚ֨רÚÚÛÛØÙïüéÜÞÞßààáçáâáâáâãâáãääããâäèéèêææååäääæåäåæååææççèèçèèçæççååæççèééèçììçèêíéèéèéçéèçéééêêòðêéçêêééêîíëëêéêêëéëëêêëëëëìëëììëëëëêéòôïìëììììëëííëëìíòìììíïíììîíìììëëìëëëìëëììíìëëëìòðìííïððòðïïõñîîðïñóî=èìðòìëëìíìíìëêìðíìêêëëëéëèåëëëêêêéééééêêêìëééèèéìëéêìñëëëééééééêêêéééêêìðééêêêêäéìëëê鹩âèéêêëîììççèèçæåæçåååääåææääæãããããæçäãäååååååçèêìêìíñôúý !-@WjgQ=*úóîêæãßÝÛÚØÕÕÓÓÒÐÏÍÌÌËÉÅÁ»³©£›”‘  ,9DLSY^ekpw~…– ¨°½ÁÅÈÉÍÍÍÍÎÐÏÎÒÓÔÓÕØÚØÙÚÜÛéì#ýÛßàááááâäâáâäãããããäääããåéêèêæèæçåååçåååååæçççèéèèèççææççæèéèèéêéèêëééîóêêééèéììéêêêëëðîéþ ðììëëìíéêëêêéëêëíëëìííìíìíììììíëìëìïíìîîíìëìîìììííîííííî ÷ëìïïîííìíììììììììííìëëììðïîïðòðïïíïïïëíïññññôóíêëíííìííìííììëëêîóïìêëììëêèþìêìíëéíêéèééêêêêêéèèèêìéêëìêëêèåèééèèëìêéèéêêééêêéêêëéêêéêè‚sçéééééìëïþëèæééçåååäåååæäãääããããåååäâáãåååååççæèêëîñöü&WžÐüí´p8 ýôîìçââÜÛØ×ÕÕ×ÙÓÎÎÎÍÌËËÈľ·°¨ž™” '4@KRV]cjou|‚Š“¥¯·¾ÆÈÌÌËÌÍÏÐÐÙåÙÔÔÖ×ÙÚÙÜÛÛÚúIÛãààààâââââããâäåäãäääåååääåååææåææææçæææåæåæçèèççèèçççççéèèíéèêèçêëêèéêéìðêééèèéêëééêêéêëëÜæçëêêééêééêêêìëëíìêëìîîëëììêìíìíìëêëììíîîíìííìëëëìñðòîììíñïíììíëíîëììîëëëîêëëëêëííìííîñòïîîîííðíííïññîíííììîíííììîìììëëëëðííìëëëìëêæ 0íéëîêëðìêéêêêéééêêèèééêéêêééêéêûèêééëëêééêêêéééêèêêìêíìëêêÿþêééêéêêå ¤óæççççáâäãåååååãê÷ããäâååääääæååææçèèèéííðóùþ8s)Õ0f¨F%ÿðìçáÞÜÛÚØÕÖÕÒÑÐÏÎÎÎÌÌËȽ¸®¤• #.:FMRX`gmrx€‡˜¡«µ¼ÂÆÇËÌËÌÎÎÏËý5åÓÕ×ÚÙØÙÜÜÛÜÜÚÜßááàáàáäââáàãâäãäããæåææååääåääæåååæçéæççæèææçèççææéèçççèîêéîéçééçéëêèééêëëééêéëéêéééêéèéêêã5eëîêêéèëéèêêëëëìïíêêìîíëìëììíïøîíìììëìïñòïííîîïîíòöõóñîðìïøõíììíïíëííììíéêëëêëìíïñøõðññðïïðïìíîïðóððîìíííìíîííííëííõììîìïìëëëëëìëêëïîëêêëëíîìëêëêèèééêêééêêëììêêêêéë.ÿçêêêêêééêëéìóéêéèëêêéëêééêææêééêêêêéþ„Iïçèçæä ãäååååäãèíæåäãäåâäåæçååèèæççâ Z ïôû 'K¦ ’ãÃÞÏX+ùñìçâÞßÝÚØ×ÖÓÔÓÑÐÏÏÎÍÌÍËÇÁ¼²«¤›)6BJQW]cluw}„•Ÿ§°»ÂÆÉÈÉËËÏÑÐÑÑÕÙÕÕÖ×ÙØÛÚÛÜÝÞÞÞÝÞããáããàááãââäãâãäääêèçåäåäääääææåèèèèçèççèçæççèçææèèçèèèëêèçèèèìêéêêëëééëìééêêêêêêéééèééééëåßéìíìéêéêêéêêêêêëíìëêëîìëêëìíëíñìëëìíììðöúøñîòóððîöðîòðïîîíòòíêêîðíîíëíìëêèïìêéìììëíïðïîîíîïîííîíòôëîíìëìëìíìììïòëìïìí÷ðëìëìîíëêêêíîéëëêêëêëêëëëëëìêééêêééêíñðéêêëêêôïëêëêêëêêêëêíóëëêëéêêêééèëëêëêéêëëêììíéèéêéèçã0äåææååååææçæååäåäääææçççèçèééóõîö ,U½Ô½õÆßÍX-ûñìèäßßÜÚÙØÖÔÓÓÒÐÐÐÐÎÏÏÍÊÄ¿¸°º¢$1<FNT[agnsz‰‘›¥±¶¼ÃÇÈÈÊÍÎÍÎÐÏÑÓÓÓÔÕØØÜåÞÛÛÞßßßßßââàâááßÛâåäæãââããåæåååäääääååååæëéèæçèëèææççèçççèéèæäçèçéçèéåçíêéêéëìíëêìêêééèéêëêêééééèèëìëêêëìëêêêíëëêêêêêëëëëìëìëêëìíììêëììììïüëïDLéîðòðïðúž ðíîîîòôïìëíïìîïîíìêëììííëëìíïññîîïðïíîîîîïïïíîìîîîíìííîîðòîîìííìííñìïîííììííìííîîìëìíêêìêìíìîòïìêêëêêêíðñéìêëëíòïìëëêêììêêëëëêëëììîíëëëïëëêéëêêêêêêëëëêëéêéççåþöååææååææååææççååççææåæççåæççêéèíðõû *L§£uš8]–E"ùðìåâáÞÝÚÙÙ×ÔÔÔÑÏÏÏÏÏÎÍÍÌÉÅÁ³«¤+7CLRX^dkqw€ˆŽ™¢ª´¼ÂÇÈÉÉÌÐÔÐÏÑÑÑÒÔÕÖØÚÛñþæÝÞÞßàßßàãåããâàìþñ åãåãäèåääääååææääåçææçëèêèèîòëçççêìéçèèèçîééééçêéâæèçèèðóíííêéêêêêêéêêêëëêêéèéëìëëêêììëêëíëëëêììììëëìëêìíìîîëììêìììííñüó•Í-êîïïðïïóGÐ5îìñðîîðîíîîîìíííìêéêììíîìíííîïïððîíîïîîïïïíîîðïîíîîîíííëý ñðîíìíìëìëììííììííìííïðìëìîíêêìêëëëëïðìéëêêêëêëëîíííëððéêëêëëìëëíëéëëëìíðñëéëïëèéêêéêêéêêêêêêìîëéççêçååççåååæåååååççååææèæååææååèéèêëïïõ÷þ%>‰Yj#¼h0ÿøðëåâàÛÛÚ×ר×ÖÓÒÐÏÏÏÍËÌËÊÊÇÀ·±ª&2?IOV[ahnu{‰˜’ž§¯¸ÀÅÇÉÉÌÌÏÔÔÑÑÑÒÔÔרØÙÚÜÝÞÞÞÝÜÝßààããáâáÙG!.Mæäãåãïéäåååæççååäåæææèççòìçòêèëéìñëçççèæö)íêìèèéêêééêêéîéêëêêêêêêèéêêìëêêêééëìëëëêëëìêììëëììíîììëëëêëëíìííìììëììííííñó øïîîïðîðñŒ ïíñîíîðïîðïííííìëéééíìîíëîîîïîíïïîïñðïîïïñïïñðîìîîìëëìíìõÿóññììíììììíìíîíððíííí÷ýëìëìîìêìëëêêñîëëêêëêêìëêíõïïïêíöîêòïëëìììííëéêëìëìêïêêêéééêêêêêêêëêêéêééíêèççêéçæêêæåååçêçæååææåææçæååèéçæéìéëìîðóöý9Yr“{X=%úõîëèãá@ïØØ×××ÖÓÔÒÐÑÏÍÌÊËÉÊÇý·± ,:EMTY_ekrz€‰“™¥¬´ÄÃÇÉÉÊÎÍÍÏÑÐÑÒÒÔÖÖ×ÙÙÜÜÞÝÝÝÜÜÜâåãååãââÞ*Àäååäääåèæååäåçæåæææçæåææçíêéîìêèóïæççèèçèééêëéíèèêëééêìêìêèêëëéèêëêééëëëëëêêêéíîëëëëëëíìíììîç÷ììëëëëëìëìììïîìììíììííìíïìêîïíîðñïïññàñóïïîíîïîîðïíííííìëéëíííìîíìííììííïðñòðïîòñïîììíìííìëìííìíîïðïíìííìîìíîíîîíìíïðîý ëíííîìíìëëëìðîìëëëëêëììêëîììëëëïíëùìììíìëëëêêêëëêëêéììêéêêêêéêëêêêëêêêéêêééèçééèêéæçççèìèççæææåçèçæååèèççéìêêëîðó÷û +17?A:, øóîêæãáÿäÚÚØ××ÖÔÔÓÒÑÐÍÍÌÌËËÈÆÃ»´'4@KRW^dipv}…Œ– ©²¹ÇÈÈÊËËÍÍÎÐÒÑÑÓÔ֨רÚÚàÝßàÜÛÛÜßâã ðãæåäèðéäãääãäåäåæääåååååççèçççççìéèççççéééççéèèéëééìëìéêêêéëëëëêêêëêêììêêëìêëëîììëìëëëíòôñììììîïìïííòùììëëëììììíïíïîëììïîíííôòððïïîíîîñðïñòððóðïîïîïññððïîîïîîìììïîìëíííííòñììîïîïððñðîìíîïíìîíììííîííîïððîíîííïïïîïîïîîïîððìíîîñìííìíìëëîìíîíííìíííîììñììîíîííïý÷íììíîíëëëêëìîíìëëëììììììëêéëëëêëêëëêêëéêéèêëêèçèéèèèèçééçççææçèçççççæèéééêëíîò÷ú $! ýõðëèäãàÝÜÛÛ×ÖÕÕÖÖÕÓÑÐÎÎÍÍÎÏÉÉÆÀ¸.<GOUZagmtz‰“ž¥¯¼¿ÅÉÉÊÍÌÍÏÑÒÑÒÓÓÔÖרØÞÛÝáéÛÜÜÞàßàêñëääæäåáåååãæçìêææææææçæåêñïìçççèëçêçèèèèèéêèèéèéééëêéìëêìêëëíìëìëðòìíìììíïëììëìñíìììííìñôôôíîííïïíïïîúýqóëíííìììììíðííííììîîîíîóòïïîîîîîîñòíïñïïñòñòñðñññò÷õïïïîïîíííîíìîíïïïñðíííîîîòóðïïðíîîìíííîííîíííðóïîîîîîïîïíïïîïïíííîîîðôìîííïìíííëìììííîíììííîìííììíìííìîîííììîîíëêëìêìïìêëëëëìììììëêèêëìëêéêêëëêéìêééééèèêëèéèææçéçççèæææêéæçæåæèèèêìììîóùÿ þû÷òð÷èâáßÝÛÚÚØÖÕÔÔÕÕÓÒÑÐÐÍÑÏÎËÍËÆ½5CLRW^dkqw}…˜¢ª´¾ÂÈÌØÎÌÎÎÏÑÒÒÔÕÔÕרØÙÛÛÝÞðàÜÞßàààßáåçæãåæäåæåäääææåèçæèçæææææçèçççæçéêéçæçèéèèéééêêéèéêééîìëêííëëììëé ëîíëìó÷ïíìííííîîìîïîîíëìîîíííîîîðïüN—÷îðííííííììîîíìíìíííííîíïïîîîïïïïñðîîñîïïòòòðïððñóõõñðîïïððïíîíîîîîîðîííííîîïïïîííðîîíííìîîíìëýíïïðîïïîîïïðíîïóóðîîîïïîîîííííìëëëíïíìëëììëëìííðîííëíìíííììíííîíìîìêêëëëëëëíëêëëëêëëêëêéêêëëêéëêëëêéîëêéçèéèèêéêççæççççæéææåëéåææææèèèêíìììðõùÿ  üøõñîðüéâßÞÛÛÚÚÙØ×ÖÕÔÓÕÖÒÛþúÑÏÎÌÍËÈÂ>HOU[bhov{‚Š“¨°¸¿ÇÍÌÕÍÌÏÐÐÑÒÔÕÔÕרÚÚÛÜÜÞÜÛÚÜßâääßÞáãåæãäåäåçãääæçøææåæææææçæçççèèçèïíéèèçêêèééèéíîêêêèéèéêëëïðíìíìëë÷ùìíðíëîùóëëðíîíîíìîîíìëíîîïíîîîðîðïôìðóõñîîîîíïîîïïíííííìîíííîððîïïïðïïïïïïòòðïðððððññññððòðïñðññðîîíïïññïîîííîïðïñöóîíîíïîîíîîîòðìëòíîððììðïîðîîîðòñïïðîîïîìïñîîîìëìííììîîíííìëìííîííëîîîííîíîîîîííìììììîìíìêëîììëêììíìííëììëëëëëìëìììéëêëêéêêéèéééééçççæçèêèçæçèçæçéçéëìêìîííïòó÷úüþÿþþû÷õñîëêíçãáÞÜÜÚÛÚÚØ××ÔÔÖ×ÕØöÏÎÏÍÔÑËÇDLRW]emsy€†Ž™¦®µ¼ÄÒÌËÌÍÍÏÐÑÒÒÔÔÔÖ×ÙÛÛÜÞÞßâÚÚÜáâäâíéáãæåâäæäçæãåãéçõëåçèèçæççççææçæèçèçèèèêèæççééçðùñêéêììéêêëìí ûîïñîííìììëìíìëëêíîîïîìíííííííîððïïîîïðîïïððïïððñðïîîïïïðïîíîîîííïïïïððóóïïðððïñïïòôñóòðñóóòòñòóóòòóññññññïïððñòòðïïïïðñïñôôñöðîðïïïïòòòðîî÷üòðñîÿO7ôïñðïðñóóñúùïïðñîðîïðïñïïîïîîïïîîííîïñïïîïðíïóñïïïîïððïîîíìíîíîîììîííììîïïíïðìììíëìëìììììììéêëììêêêêêêéêéèèèèèéêêêçæçççééèèëïêêíìíîíïõööøùùù÷õóñïìçñæãáÞÝÜÙÙÙÙØ×ÖÖÕÕÕÔÒØÝÏÏÐÎÖÑÍÊIQW\aiqx~…Œ”Ÿª³ºÁÉÒËËÌÏÏÑÒÓÔÕÕÖ×רÚÛÝÝÝÜë áÛÞàããàçæãäççäææææææçåæçåæææééèèééèèçæôíéëêéééïëëêééééíïéêìíëìíîîñïîü÷öóðïííîîîíîìíïìíôîïîîîïïîîîïïðñññíñððððòòñïòòóñðððïïðððïïïïñïïððïðññûüïððïððññðñññóóôôõõóòòóôôóôôññððððððððïðóñïïïðñðððïññóðïïîîïïñðððîïðñðððë Ì¿öîðïñððòñð÷÷ïðññöúïïïïïîóðîììïííîîîíîîíîïîîîñîíïïîïïîðñðïïïîììíííìëíîíììììíîîíìëëêêëìëìêêëëêëééêéêéèèéëêèèèéççççèèéêèæææçèééçèêéééìëìëïññòóóôôñïîìëìèð åâàßÝÜÙÝÚרר×ÖÕÔÓÒÒÐÏÐÐÏÑÏÓÎNTZ`fmt{ƒŠ’›¶Ò·¿ÅÉÊÊËÍÎáÙÔÔÕÖØÙÙÙØÚÛÜÝáôèûáàßßáààáãååèéæåååæçäåæççæçææçèçæçèèéèéðêèéèèèéìêéèèèèéêéééêëëëëìíïîïó øóòîïñîïîííîíìí%úëíïððîíîïððïîòdùïòððñòððððððððððïïðððððîñðïïññððòúúñðïððñññððïðñòöõóõôòòòòñóòòòõðóòîñîðïïïðïîïïððïïïïïðîïîðîïððïðïððïðïððïïüA@óððïñððòñðòñððððñðïïïîðîððîíìîîîîððîïïîîñðòòðïïðïïïïîîïðöòîìîððíììíîìíîíîîíìëìíìêëëìëëëëìëêéêëëéêêééëíêéçèèèççèèçíêçæææèééêèèéèéëëëìîìíïïïñïíìêèèìëçáâáàßÜÛÙÞÛ××××ÙØÖÖÕÔÓÒÑÑÐÐÑÐÓÐQU\bjpw~…–¤Ìë»ÃÈÊËÊÌÎÏáÙÓÕÕÕØÚÙØØÙÛÜÝãõàÛÞáßßàÞàâååæèéçåæçäêüææçææççææåäéêçèéééééèééçèêéééééèéêééëëìîììíîììòðñóžËëòñïïîîïîñíñîîîñöïíîîîññðïðññî÷ÅñóòñóòñòòñðññïîòôñððòñõðñññððöóñóòòôñññòññòñðññòõõôóòôôòòòòóòñòöòôòðñïïïïïïîððïïïïîîïïððïððïññòñðïïòòïððñññðçëññððñòñðïððñòðïïïðïïïîïîïïñîüîîîïðîíïîîðñðñïïððîïòñïïòæW:ûäîíîïîìíëîììïíîñîíðïîìíìêëììëëêñîìêéëëéêêèééëíèèèíêéêçèéûïæèççççêëèçèçéëéëìëêìííìíììïìæçèèçæáàßÞÜÚÚÚÚÙ×××ÚÚ×ÖÕÕÔÔÓÑÑÑÒÐÐÐUYbiot{‚‰’œ«ÀÃÁËÊÌËÌÔÐÐÏÒÔ×ÙØ×ÙÚÙÙÚÝÞÞàãáàßßßàààâãåååçèèäæçäçõêêæçæçæååäãæèçèèéêéèçèêèéêêèééëêéêêêëëìïìíîíëíïïñöwŽqîòðñóñîðîïïîîíïîîîðïïðòñïïðñòðóøðññññññññðñññðîôüòððñóòñòòðôôñòññòñòòòôôòññóóòõóôôó÷öòòòòóññððóóîðòñðïïïððððïððïððñðñòðòððòðóóñðïòòððððññïðóòðñôôôóñòñðòòñññïððïðñîðòññíñðïððïïïîîððððòïñðïïðñððñí •~ìðîïïííîïïîíïîîîííððíîïîîìììíëëîïíëêêëëëêçèëìêèéêñééìèèçòìèêéèçèéèçèéêêîééìêèììëëëéëðíåååäååáààÞÞÜßÝÛÚÚÚÙÚÙÖÕÕÕÕÔÓÒÒÑÑÏÏÑWaluux†—¢«³¼ÈÑÊËÊÍ×ÒÏÑÒÔÖÚÙÖØÚÛÛÜÜÜÞáààááãâÝàãååäæçåçéæäãäääìíèççèáâååååèêéééêêêéìêêéêëîëéëëêëììííìîíðîììíïïñöEHöòððïïðïïðïîíðïñóñïïïïðððïðôóñóõôôñðõóóôóòñððñòòñðññòñóòøñòóóñòòõõññòôòóôòóóñòõöóòòòóóóóóôóóññòñòõððòññðïððððððððñòñòññóñòòñññññðððïðñññðññððòòñóôóôôóóòñòòòòòððïðïñïððóïîúñððñðïîîîîñïñðñðïðïïîïïðððöóîîîðîïîïôõðîíîííìíîëóýõ÷ìëììêêéìêééêêëëêëìëêééêêêèèèèèèêëéèèéêèççèéêéðééêçèêëêéèèêééîëåääâáãàÞßÞìæÛØÜÛÙØÖÖÖÖÕÔÓÓÒÒÑÒÐÏÐZhp~}|ƒŠ”§°¹ÁÆÊÊËËÎÏÐÐÑÒÕÕÖÖØÙÙÚÛÜÛÜÞáßßàâæéøëáåæåæéêêèåâãäääèéèçççûãæçèéèéìéêêêêìêêéìëïëééêëìëéììêîïíìîðñý÷ðïôõóñïîïïïïîïðððîðññïðððñðïðñðððòòññòòòò÷ôñðððñóóññòñóöóññððóòòòòòöôðòóòóóòóóóòöóòóóòññññòòòòôóòóòóñññðïïððððïðððññðñòñññññòñòòñññððïïïïððòóññññðñññòññôóóóòñññòñðòõòðïñòðïòððîîðððïïïïðïððîðñððïðïîïïïîïððíìððíîïîîííï÷ñííïïîìííëìè¤_êìëêìëêëééèéêïðéêéêéèèèééèéçèéèêêééëêæçèéççèèççèèçèçéççéèèåíûòãããáâíàÝÜÝëèÛÙØØØ×ÕÔÕÕÕÔÔÔÓÒÑÒÑÑÑ^gs†Ž™£­µ¾ÄËÉÊËËÎÏÐÑÓÔÔÕרØÙÚÜÛÜÝãçÞàààáäëš7ééæåäíòêæãäææåæååçèçæÿâèííèæèëéêêêììììêëììëêêêëéòêõêíïíïíïó%õôóññóñðïîîïñïïïïïðôòñðïïðòðïïðñðññòòñôõóóõôõôòòôôññòóóòñòòòñòòôôòòóóññòóôôòóóóôôôõóóòòññóòòòòóòòóôòòññòîïïïðññðððñòòñòóòñíôòòóòòððððñïïïðññòòòðòòöñóòñòòóòòóòðñòòðòööòðññóðéëðñððððïïïïððñðïïðòïðïïïððïðððñðïîïñîïðîïííîï ùëíîîììîîíêôíìêëîëììêëëëêñòêêêêééèèêèíêèççæèççòöèèèççèçççèççææèðíéçåæäããäãáâäöâÝÜÞÙØÙÚÚÙØ××ÖÕÔÕÕÔÕÕÕÖÓÕÖÔbhry~„‹”ž©²ºÄÌÒÊËÌÍÏÎÐÒÔÕÕÖÜÛØØÚÝÞÜÞèòßßàááãçµ»§/Þæåëíæçäæèèíëæåæêéçîéåèîîèççèêëêêìëìììëíëëëêììéûñììéìíîíðìíñøññõùîðñïîïðñððòñïðñòóóòððññððñòòòòñóøóÿõóúüõñòóõôóôòòòóññòóôóòòóóôýùó÷÷ôøúóôõöõõóôóñòóòóôóòññòñòòóóòñðóïñðïðñòñðñòóóñòòò ?ôóôöõññðñðñððñòõôñññðòóÿòóóòóóòòñòòñòóñòö÷óòòòñòðK:üîòñððððððñðññðñññðððñññðððððñïðññððïïïððïîîøñìðïððííëø òìíïíììïììêëêíìëíìíðíìëêçèéèðèèéèêëêêæ+•dìéèéèèæééèæççææãææåååäâââãäëââàáÞæÞÙÚÚØ×ÚÛÖÖÖÕÔÕÙØÛÕÚÙ×ek|‰…†™£­¶¾ÅÊËÍÍÍÏÑÐÑÑÒÔÕ×ÚÚÙÙÚÜÝÝÞßÞáßâãããåÎXÚæäãäççåæçèðìæçíêééæâæèèêêçèéëëëëìëìììììëíîìììíìëîîííííîïîðîððññðõúïðïîñòòïðñññðòóòòóòòñððòóóóóññô÷óöõóõ üñóôõõôóóóòòóòôóóó÷öôø òicîôöøþõöõôôôôôöõõõôóòóóôôóñòóýòûòññòñïðóòñòñòòï#§òòóõòñòòóòðïñòô÷öñòóðñóüòñóôóóóóòóôóóòñóõóóòóòñòðL<üîòòññðïïðññððññòðññðññðïïðððññðòññòïïîððîíîíîíîïððïîíðöñïîîíìììììëêëëëêêìîîíêéèééééîèéèèéïîëéíøûõéçåçæçééææçéçäãäääéêäâäãàâëòëßÛáìÙÛÙØ×ÚÛÖ××ÕÖØÖ×ÔÔØÔ×io‘°™‰•Ÿ©²ºÂÉËÌÏÐÏÏÒÑÓÒÕÖÕíéÙÚÚÜÞßßßßßàáãâããäèêèèçìûäçéçäççååçêôëèêêýöçèêêèêëëêëììííìðíììîðíëïñííïîîïíîïîîðîðððñòóõþúïðððóñððñðñòòòññóõôòñññóóóôóññòôóóôòóúøòóõôòñòóôóòóòóôôôôôóôõôô÷ò`iìóòóõóõóõóôõôóóôôóôôóóôôóòòòóõóòðñòòôòñûüññòóôõðõóòóïñòõôóòïðòòóóñô÷óóññòñóõôòòóòòóóõöôóóóóñïòóôïñññòñññðððïðññðñññðññññññõôòòññòñðïññððïðððïîîïîîîïïïïïîìðûõîííìììëëëëéêëëîîîíëîêéêëèìêéëéèêééèçèèèèçæçæçêêèååçååæçæååæçååâãäáàåñçÞÜèàÜÛÙÙØ×ØØÖ××ÖØÛ×ÙÖ×ÕÔ×kp —‡š¤¯·¾ÄËÌËÍÐÐÓÑÒÖÔÔ×ÓÕÙÚÛÜÝÞÞàâáââáãäææçææåó#âçééåæçäàæéëééêð'ççççéëììëíìíïîëðïíìììììððíîïïðïîïííîíïðïïðòññóòðñðñòðñññòñòñòòóôôòññòóôóòóòòôñóóõôóôõöõôôôôóñòóóôóóôõôôõôóóôóôôóóöÿÿóóòôóóóóóòô÷ôóóòôò ÷óòóõôóóôõóòóòôóûí!(ðôöò÷ùôóóóññòöõòñïðóóòòòó÷÷ôôóòôôôöóòóòòóò÷üøõôóöûóóöñññòòññññòòðñòñññóñóòññòññôôóòññòøÿðòöñððññïïïîððïïîòóîïïïøîíîíìììëëêêêìíííìëêëëêéèéééêìêèçèçæçèçèééæççèçèæåæåææææåããääããäãáââáßÞßÝéàÜÛÛÛÚÙÙÙ××Ö×רØÚÛÞÛ××qv…Œ•žª´»ÄÉËÌÍÎÐÐÔÓÒÓÖØ××ÖØÜÞÞÝÞààààáâââäãæçäåååææååçééëæåçòêééëëéðêèèéëìíîíîíïððîíïïîíìíîíîðîîïðîîðíîíîïðññðòñòóòòñòóðñóóòóòóóóôóóóóôôôõöóóôôôõôóóöö÷ôôö÷õôôôóòôõõôóôõþõõö÷ôôôôõôõöõïð÷ôóôöôõõôòôõóôóô÷ö÷øõôôööôõöõóóó÷òòóôóòõõôôõó÷ôóõööòòóõôòòòòóóòòóôõ÷øóô÷õóùôòóòóôôóö÷õõó÷Góóðóòòòòóòòóòññòòðñðñôôóóññòòñïðòñðððü5LëòóðððñððñïññóòïïññïñòîïöïîííðììëêëëêìíìëëëééìéêèêééëéêéèçççñöêèçèçæèèèæåäåäåæåääääâáâããâããâáâßßÝÝÝÜÚÛÜÛÚÚØ×ØØÙÙÜÛÙÜàÛ×Ösz‡“𤝏¿ÆËÌÌÎÑÐÐÒÒÓÓÕ×ØØØØáìèÝçñàââáãâââäååååååæçæææçêíèèé fïèêêëêéçèêêëìííííïììîîñïîíîîííîîîñòðîîïïïðîîîðððòñðñòòóòòñòóñòôòóóôóóòóòóóóôôôôôóóôôõõôóôôôõôõöõôôôóöùõõôôôõô÷÷õôõõìïþûóôí%¶©ëôóôôóôõõóóôòòòôööõôõõõööôõþöóò ûòóóòòôóóôõôõööõõô÷óòòòóòóôóòòóòòôôõöôôõôôôóóóóóóôôôóóôôóô Ióôòóòòóñòòòòõùõñ÷þòòñòôñòñòòóòððñðñòí<:ìñïðïðñòòñðõôôòïïððñóôñîíîîîíïíìëêëêêëëëêêêèéíëêëêêëëêìëèçèã ,èíéçãþ‡ðååååååæçåååäâáãåãâããáàààÞÝÝÞÝÜÚÛÝÛÚÙרÙÙÛäèÜÜÚÙØ×v}˜ž™Ÿ©²»ÃÉÌËÍÐÏÑÑÒÔÓÔÕÙÙÙÚÛÛÜßàáçàâááãäââããååæåæçççæççèëçééëëéêêêêêëëêëìíîïííîðíììíííîîîîîíîîîððñðïîïðïïïðððòòððñòóóòòòòóóóôóóôõóôóóóôóóõöôôõõõôôööõôöôõõõø÷õóóóðó÷ôõ÷÷ööõõöõõ÷øñóøøôôðŒíôôõôõûööõóôõóÿû÷ôûõ÷õ÷÷ôõô÷õôõôôóôõõõôóöøõõõöõ÷õöõõóòóóóôòóôõõõõöööõùõööööõööõõôôõôóôôóôôîõõôõôóôòñòóòùÿðû óõòòòóòòòñóòðññòóóðþëññðññññññðñöôòðóóïòõôòóïïîïîìîíìëêêêêêééëêééééééëëêêééêéèèèæóüðèêæåäð(ëçäçääåòíäääææâêòâãáááààáÞÞÜÝÜÛÚÜÛÛÛÚÙÙÛÚßðíÜáÛÙ×Ö€€Œ”𥝷¿ÇÌÐÎÎÏÑÑÓÓÔÔÕÖÚÛÚÚÜÝáãÞÞááäâäéæåäåååæåæçéèçèèèêïééèêïêêëëëêëìììííñõðííîïïíîëçïñðïïîíîððïðððïðñðñòñððòòðñòòôôôóóóôôôõõõöøöõöôôôõ÷ø÷öõ÷÷÷õö÷ööõöõþö÷õôóúñôöûþ÷õööööö ú÷õööõõýõööö÷÷øööôôõôöùùø÷öøø÷øö÷öõôóõóú÷ôôõõõöõôõõõõôüôöõööõôõõõöõõöõôôôõõ÷÷ùúøøø÷öõÿúõööôõöôóóôõôõõõóóôóòòóóòóõÿÿòòñóóôòñòòñòòóòðòñòóòòóòòññðòòððïïïðòñðïôõïïòòïðïôïðîëïìëêéêêéêêèééèèéèççêêêéìéèéééççæãæççæãäåèçåãåäääèæääãääàïÿáááááÞàáßÝÞßÜÜÜÜÛÚÚÚÙØÙÚÞááÚÜÚÙÙØ€„Œ”¡«²¼ÄÉÎÐÏÏÏÐÑÒÒÕ×Ö×ÙÙÚÛÝßàààáàâåáãäñæååæçææææçççèèèêðêééêîêììëêêêìíìëëîòðìîîïïïï-ûîôñïïîïñïïððïïðññðòñïðïññòòóóòóôôôôöõöøööú÷õõöõõøþúõ÷÷÷÷÷úûõõöõõöüôöôôóø òõöùûöõööõ÷õÿüøõõõõöõòò÷õö÷øñòùöõõõôõõõõõööö÷öõõõõôóôóõöõôô÷ö÷öôöõóõõõùöôõõôôóõôôóôõôôôõ÷øùúúúúú÷÷ûöôõôõôóòó÷õõöôòóòóòòòóòóóòñññòõòòôñòññòóóóòñòñññòóóñññððôðíííîíîïðððððïîðòïíðôïðîìïîììëêééçèééëêèéèççêíèèìéêêéççççæåæçæäããååäåææåããääåäããâæêâàááàáóåáâàÞÜÜÜÛÛÛÚÚÙÙÚÛÝÝÛÙÛØÙÙÙ‚ˆ›¦´¼¿ÆËÍÎÎÎÎÐÐÑÐÕÖ֨רÙÛÜÜÞßßààáâââæõçäçåéæççææçççèèéêêèéêëêêëëëêêììëëìîíìíïíðîðïžæþóðïïðïïðñðïðñòñóòñðïðñòòóòòôôõ÷õ÷÷÷ûøôöõ÷õööö÷üùõö÷÷ö÷ýüõõõõöõõòõöù÷ôóóóòõõõö÷õôööõ÷ö÷øøöôôõõööõõöö÷ô ÷âòõõöõôõöø÷ö÷öööõõôõóôóöôõõôôõö÷öóò.óõöõööõõôöõööõîIJööö÷öõ÷úýÿûøôõ÷öõôõ 6ôôõõ÷óôóóòóôòóôóõõóóóòõúôóôóôóòõóòôóôóòññòòóòïïññôðîïïïííïññññðïðòôñïñðïòïîùòîííëéèö÷çîòêëêéêéêìéêêéêêèçèèçææææçåãåææçæååååääååääääãâäääãàßåâàåàÝÝÝÜÜÝÜÛÛÛÚÝßãßàÜÜÜÜÚÙ…‹”¢ª¶¿ÂÉÌÌÍÏÒÐÒÒÒÿÚÕ××ÙÙÝÝÜÝÝßßßàááââãææåæäååéèåæççèèèèéëèêíëêéêëêêìêëìëïòíìîïïîððï öî ÷îïððïïðòðððñòñôòóòóóñòòòòóôôöø÷÷ùùúúüøøøöýúõôôõõööõöø÷öööööõõööøù÷õôôõöôõö÷ø÷÷ö÷÷ööö÷ööõõöõööõööööõ ôçôööõöööõõ÷÷÷ö÷öööõõöõôõõööõõøûöò/ôø÷øõööøõö÷øøøöÿýõö÷øùûüþùöõõööôúøýõõöööôöõôóóóöõóóóôôóõöôóôõôùúõôôóñòôóòñóóôóóüöòðñðñòðîíîðððððïïññðïïîðòïîûòðíìëêç çîñêíêéëééèêêëëêéèççççççææçæäååååååääåãããääããáßãåãéæàßÞÞÞÝÞÞÝÜàßÜÛÚÛÛÛÜÜÜÜÜÚÚÝàÚÚ‰›¦°¸ÀÇÌÍÍÎÐÓÔÔÒÕóÚÖ××ÚÚáàÝáàãèâáââããåãçèæåææçååçèèèéèèêíéêëëëëêëìêëëììëììîïîïîíîðòïðð÷óðïððõõððòôñððóòðòòñùþõòòóóõöõõöøúûþþ~)ýöööþ÷÷öö÷÷÷öö÷÷÷÷ö÷÷öö÷õ÷õôöõôõööõ÷öøø÷÷øøöõôöööööùú÷öõöùûô÷þ21ÿ÷ööööööôþÿõ÷øøûöööõöööõõõö÷öõõööõõûÿõööøõööööõöö÷öõóõöö÷ùú 1PQ/þøöôôõööó7ùõöôõööõôôóóòóóòóóóóòòóôóóòôôòôóòòþõ÷õòòóóñûúñîîïðòðîííïðïððïïðñðïîíððïíííïîìëêèúýéêéêêêééèèçèééëêèèëëèçæææçæææääåäåääãäâããããããáßããâæäáâßÞßÞßÞÝÝßÞÛÛÙÚÛÜÝÜÛÜÝÛÛßÝÛÛŒ”Ÿ©³¼ÃÊÌÍÎÎÐÑÕÓÔÕÙ×ÙØØÙÚÞÞÞáááäâáâáäãääåææçìéæææççèéêééëîéééëìéL èìììëëìííííîïîïððððñï÷îðððïïïðððôñññòïïññ÷øóóòòóõöõöøùþ   ýTÿóöø÷øø÷÷øøùùö÷ö÷÷÷õö÷÷öõõôôõööõö÷÷õööù÷öö÷÷ööõöõõööúû÷õööøÿúøòòøù÷öööööõ÷ù÷÷øúÿ÷öõõööôöööööùøöõõõöõõöõö÷÷÷öö÷ö÷öö÷÷÷öö÷øúþ $V¸ÿ©Aúööõôõõö÷üüöøö÷ôööôôõôôõôóóôõôôøùôõóôóõûô#óóóìWDûóôòòôòñôüùòïïïóòðïíïððññððññòóñïîïïôïîìììíîìêííéëìêèêêçéèéèéèêêèèìòòêæçæçææçåææåæãåääãããããããââäãâãâáàßßÞßßÞÞßÞÜÜÛÚÛÜÜÜÛÜßÞÛÚÜÝÚÜŽ™£­¶ÀÇÊÌÎÏÏÐÑÓÓÔÔÓ×ÙØÚâÞÜßÞßàààààââããääãääåçæçëêçèéêêéêìîèéëíêêõììììíîïîííîîîîïïìñððïñïòòñððððððððñðñóÿ ôòñññòòòõöõööøû_ŠHüüûñö÷ö÷÷÷÷øùø÷÷ø÷÷öö÷÷÷ö÷öööõöõö÷÷øùùø÷ùø÷öö÷öööøøö÷÷÷ö÷÷÷÷ö%ýø÷ö÷øø÷÷ø÷÷öøúø÷øùú÷öø÷÷öõö÷ö÷÷øø÷øöõöøùúüú÷ùøö÷÷÷øøøøøøøøøúþZÙWv+ þüøöõõõ÷÷õöõö÷ööõõõöûôôõõõõõôõõù÷÷ôõöõöùöõôôñ15òôòóóòñòñòòðïïòòïïîïññññððððñòóðñïïòóðíìììîîìëëëìëêéêêæééêéêééêééçîóëçèççæåçèçæåæäåääæäãääãáâããââãááßßÞÞÞÝÞßÞÝÜÜÝÜÛÜÜÜÜÞÞÝÜÜÝßÛܨŸª³»ÃÊÌÍÐÒÑÑÒÔÔÔÕÔרÙÛàÞÝßÞÞßáåëéääãääåääåæççæïïçéééêçæìîêéëêìììíííííîðñðîîííïððòðóðñòñðñòóñðú÷ðððñññø‘ ðôõôóóõõõöýÿþW™[×þûöùùøù÷÷øøøøøøøø÷ù÷øøøøøøøúø÷÷÷÷øùûüû÷ø÷øö÷÷ö÷öøüùøø÷öøùøøöûö÷øøùúøùúù÷ùúùùúùùùù÷ùùû÷÷÷÷øúùøùùù÷ úùûüúùøøùø÷ùùùøøøøùúúûÿ 'rÍÑv1úùøöö÷÷øøööö÷÷÷öõõõ÷÷öö÷õö÷õ÷öçµ óöõõöööôööõôõöôóõöôóôóòòòòòóòïîîïðïïðôùöñòòññòóòòòñððññïîììíëêëëëíêéêêéêééëééèèèééèçççæççææåæèçèæääããåèÛÚääèôõãááââáàßßÞÞÞÞÞÞÝÝÝÝÜÜÛÛÛÛÜßÝÛÜÜÝÝÛÛò¯¸ÀÇÌÏÏÑÓÓÓÕÕÕÖ×ÞÝÚÚÚÛÜÝÞßßâåæêéåääåäæçåæçèèæêëèêêä(­ièõîëëëîíííííððíîïðïñôïïðòñðññðñðòóóóóòôõòóòòóóôô ùóôöõóôöööô*üd߈êþúúúùøùøøùøøùøøøùúùøöøùú÷øøùøøø÷÷÷ö÷øúøø÷øö÷ööøö÷úù÷øù÷øùùùøøôøùùùúúøùùùùúúùùùøùúú÷÷øúø÷÷öøùùúùøø÷ÿøøùùùùùøúùøøøúø÷÷øøüþû?V> þù÷÷÷÷÷÷ö÷÷öö÷õõõôöõ÷õôöõõöøõõöõ!0ýöõôõöôöôôõôôôöõóóõóô÷óñòóðñòòññîîîîññý ðôóòòòòòóñòïðïïîíìììêëëêéêêêìëêìêêëéêéèçèéééçæææçææçååèèçããâãäâsyþÞìãàããáááßßßâßßßÞÝÝÝÞÝÝÝÝÜÜÝÞÝÚÝÝÝÝÝÛð ²»ÄËÏÐÐÐÒÒÓÔÔÕ××ßÞÚÙÚÜÝÝÞàáãäââããåäæëçèçææçççæçéêëè]8êðíêêìîìëìííïíìíîïîïðïïïðñïîòñðñððòòññððñóóññóòóòðóôóòõôôõôùö&F÷ü*r–= ýùø÷øø÷øøøøúûö÷øøùùú÷÷öø÷öö÷÷÷öööõö÷÷ö÷øøú÷÷÷÷úø÷÷ööøøøøøùøøù÷ùûøøø÷øøùúûùøùø÷ùøøøø÷÷÷ø÷øøøøøùøøùø÷÷øøøùúúúùùüúùùúúùøùøþûÿýûúø÷÷÷ö÷ööøøöö÷÷÷õöö÷öôöööýúõöøõôø÷öôö÷ööõö÷õöö÷÷ô÷øûõôôóóóóôóýôñðòôóô ïóóòóóòòóôôòòðïïîííëêììëëëêëìêëéêêééééèèèçííèæçèççæçåæåäåæäãäãßòÝèòòããåäâââáààäáßßãáÞÞÝÞÞÞÝÝÝÝÞÝÜÝÞÝßÞÜŸ¯¶¾ÇÎÐÐÐÐÑÒÒÓÕÖÖØØÙÚÛÛÜàãâßàáâáâãääååìæççèççèçæçéêìíëèéìëîëëëììîíííïííííîïïïïïññòñïñññòðñòòññññóõñòñóóóòóóôôóôóõõôöù÷ü  þýúøùùùøúûùùø÷÷÷ùøøùöø÷÷ø÷ö÷øùøö÷÷öö÷øøøøþùøüúûúøøøøøøùùøø÷÷ùøúúøøùøøùúûù÷øûüýûùùúøùøùúúùùùúùùùúûùùúúúúúýüüüüüûüüûüûûúúþþüÿþüüúùùøøùøøø÷÷øøùú÷ø÷÷÷û÷øøùø  ö÷÷÷÷÷ø÷÷ý÷÷÷õ÷øö÷÷ôÿó÷ööôóóôóóòôõòòòóòðòóóóóôôôôööööôúõññïíììììììëëêëìëíêêëêêééêêéçíîèççèçèåçæèåååèæãäåç<KãäââããääããââáàáàààæãÞßßßÞÝÝÝÝÞßßßÝÞÞßßÞ¦±ºÄÌÐÐÑÐÑÓÔÔÕ×ÙרØÚÜÛÜÝâçãàáââãáÛåäæèçæèéèèèèèèéêíêæëëêìíðìììíîîííîîïïïíïòïïððòòóòðñòòòóóòòóòòòóôòòòóõõõóôóôôôö÷ööøûûùûþþýüúùúùùøùûù÷øøøùùúøùûøøøøúø÷øøúù÷úû÷÷øúúþ÷øùùùøùøùùøùùùùùùùøøøùùúùùúùùùúúúüú øùúûùúùûúüøýüûúúûûüûûüýüüþÿüýúþüüýýüüüüûûûýÿþüûý÷úùùùùùùùùøúýûùûøø÷÷øûûøø÷÷ùú1/øùø÷ùøúøù÷÷úøõöøöûü÷õõóóõóòôôõôôõóôõôóôôõöôôöö÷úúøøöõóóóñïðîíîîîííëêëìêíêêêëîìéèéêèèèéèçèèçèçæçäååçåääåçàÝãåääãââãããåâáàâáàáàáßÞßßßÞÝÝßÞßßàÞÝßàààÞ«µ¾ÆÎÒÒÒÒÔÔÕÖÕÑØÞäÞÛÜÜÞßàáááâãâáý/ãåçèæèèêèééèèéêëâUÖLæëììïëíîïîíííîîîîííðóòðððññòññïõ÷óòòòòôõòòóóñóòóô÷ùóôõôôôõõõ÷øöùýùüüüýüûüüùùûúùúûúùøùûúúùùüúùøûúøøøùùøø÷öûü÷ùùúùúøøùøùùùøùùøùúùúúøùùùùúùúûùùùùúúúøPFòøúüúùùúúùúùýúúúûüüûüüüûþþûþ, îõýýûûûûúûúüþýýüüúÿ×Aû÷úùùùùùøúûùùùø÷öøø÷ùøø÷÷÷÷÷  ùø÷÷÷÷÷÷÷û÷ý4 ÷öõõõôôôôõýóóòôóôõ÷óóóôôñòôóòóóöøúþø÷õõðñðïîëìíììêééëëêèêêêèééééççèèéëêçåæçæèåææåäåäääääåãâãäåãââáââãåâáßáàáàßÞÞßßÞÝÝÝÝßßßßÝÝÝÞßàÞݯ¹ÃÄÈÐÒÑÓÖÔÖÕÚúÙäñäÝÜÝàÞÞßààâãâÞ\ãåçäæçççèêêèèèéêàdóSäêìëðììéîíìîðîíïðîíïñðððïðñòññöññòòòóóòñôóòòóòóõôóôóôôõõõõõ÷÷øùøúüûûúúýüúúüúùúúùøúùùøøøùùúøù üøøûüùøøøøøùùøøøùøùù÷÷ùùùùùùøùûüüùùúùùúúøÿøùùùúüüùŠ}ïøøûüþúùúùúúùúýýùúúüýüûûúüüýýûý=X ûüûûûúûüûüüüüûúüúÿÎAûøùùùùùúùùøö÷ùø÷÷øøööøúøùøøù÷ö÷÷øøø÷ùú÷øûøû þ÷÷ööööööõõóóõøôöõôóôòô÷ôôôóóôöøüû÷ôòòððïîííñ÷òéêëìêêìòìêêééíêççéêêèæçççåæææååäæåääääããããääââââââáâáâßàßáàßßßàßÞÞÞÞÞÞààÜÞÞÞÞÝßÞÞ³¼Ã âÏÒÓÓÔÕÔäFÞØÙÚÞÝÝÝÝÞßááâãâãçëçäçèçæçççèéééèèéìñôòêêìëðììéìííïðîíðñðïðòïïðïðððñðûòòñòññòòòôöòúòòôóòñóóöõôóôõõõö÷ööøùùûúùùúúúúùúúÿûùùù÷ 'ùûùúùøùøøùùùøø÷øùùüúøúùøùùùùüúøúúûú÷øúùùùùûûúùùüüûúûúúúúúõöüúúúûûüûüùüûúúûùúúúûûûûûûüüüÿýýýû(ºùýýûûûûüüüûúûúùúúþøúûúüþüùùùúúþûø÷÷÷ùù÷øùúùùùøùùùøøøûùùø÷øö÷÷õ÷ø÷øöõöööôóùþóóõýõõôóóòòóôôôóôõöúÿ'¥ýaüöóòñðîïîìëëëééêéìñêêèééìééêèççççèçåæççæååçãââåäããããâãææäââááâââááâáààááàßßßßßßßâàáççò ëáÞÞÞßßß·À¹ñÊÒÓÕÕÖÖØéÛÜÛÞÝÝÞÝßááãäâãããåêæåçìéæçèèèééêëëëëëìïëêëêîìëììîîîîîíîððððòòòðððïïðñððòóòññòñòòóóñûñóúóôùöôöõõôõôôõööõö÷úøùøùøùûüúùùöøúùùùúøùúùùøý÷üøúúøøø÷øúøùúúýúøùùúúúúùúúûûúúûüûúùùú ÿúùùýýùùûûûûûüûüüýþûûüûúúúúùûûûûûüüûûüþþþýþY? üýýûûûüýýüúüþûúûûüùùûûþÿüûûúûûÿû÷øùÿúøúúùùúúúùøøùúùûÿúøöøøøýûýùøø÷ööö÷öôôóòóõõöúôòôõôôóóóõõó÷ûøûýdÕ•øõòòðùíîíììëêëëëêêìêììíìêêëëêêèèééèæèçæåæåæäæäääåääãòôäãããâáãçâáäãááäãäâáááàßààßìí € ëâàààáà¼ÅÍîöÜÓÒÓÔÔÖÙØÖØÛÚÝÜÜÞÞßâââãããäåäåèæçæåææçèéèèéìïíéíðìíðëëîïëìíîííïïîïñïïïðôôññðìïïòññõôòòóôóôòðñóøûóôøóõùøõôöõõöôõöõö÷÷öùûùùùùùúýúùøT2óùùùúûüøøúýüüûüøýüúùúûúùùùùûúùúûûùùøøûþþûùúûü ùûúûúûúûÿ þúúùüúûüüüýþýüüüýüýþüúúúúûûüýýüýýüýþþþÿùùÿþýýüüýýýûûüýÿüýúüúûûûûúùûýüúûüûýþüùúûúûúúúüüûüûùùúûûúøûúøúùúüûûøøúù÷÷÷÷÷ööõõöõõóñôôôöõôóóôõõôõ÷÷ýU^䮸ôòòðõñíïïñòíëêêêêêééîìéêéééêëêèæèéèèççæååçåææéååæäãäæåãååäáâãæâáááàáçããâààáààáâåòéû^ óæáßßàßÁÈÎÑÒÓÖØÖÖ×רÙÙÚÜÛàÞÞßßááâãâäåææèëíèçéçççèèéèééêëìëêíìôëìíñîíîîîîðïïñðïïïòõñññô ñïòòòöôòóôôõõóòôöõòôôôô÷ôöõôõöõöõõöõö÷÷öùúùúùùùúûùùøf?óúùùúúúúûüýýùúûúüÿúúúüûûûûùúûüýûúüúúûûüýûûúüùúúüýýüüüüüûüûþþüüýýýþýÿüýýýûýýüûüüüþýüþþýþþÿþÿýÿþþþýÿþþýûýýüüüüþûûýÿþýùüûûüúúûûûûüýûúúúûúûúûüúûûþýûûûûûüûûùúúúùúùûøùø÷øûýùöø÷÷ø÷öõõõõõòô÷õõôóòõõôôóôö÷ú"]r,üöôññðîîíííîíìëéêêêêêíêðêèéèèêèèèççêéçææåæææçåèèååäãåääååäâââââãâãââãããàááááááàáïðãùááåèåæåãâáÃËÐÑÒÓÔÕÕÕ×ÚØÙÙÛÛÝÝßàßàáâããããåååæéåæçêéêéééêéêêéìîìëìëôëìëòïîîïîîîïððïïððñòððïôñõóóôóòòóóóôôóóôôôõóóôõ÷ôôôõõõõõôõõö÷õ÷öøøúýúúùúúùùù øúùùøüúùûúùøùùúúþÿýûûûûüúùùúúûüüúüûúúúüüûûûûûüüúúûüúûýûûüýûúüýýüýþþýýüýÿþýýýüüþýþýüýþþýþþÿýþþÿþþÿþýýüüüüûüýýýþûýýýýþûüüûûúúûúûüûûúúüûûúûûûýüýüûúúûüüúúûúùøùùùúùùûûøøúøö÷ö÷øõõõõôõôòó÷ôõóóóõôóôôõúþúüÿþþ÷õòòïñóïìíîíëìêêëìééèêéìèèéèçéèæèçæçååååäæåäææçèæäããäâãäââãäãâáããäãââåâàáàááàààßæõðàìáßäáàèëçãáÈËÐÑÒÓÕÖÕÖØßÙÙÙÝÛÜÝÞßààáââäåãäãæéäæææçêèèèçêéêêéêììêìëêéìììóîíìííîîîïïîðñððñññïîìïøöñóóòññòóóõôóòóóõö÷óóôõôôõõõõôõõõ÷÷õùü÷÷ùûùùøùùøøùúööúùø÷ýùùùùùøúùùüúûûúúùúûúûûúúúüüþüþùûûúûûûûûýþýüüýüýüûûüûúüýþþþþýýýþþþüþþþýýûûûûþýüüüÿÿþýÿÿÿýþüþþýüýýüÿýýýüýÿýÿþ%úüûûûûûûüýüüüüûúüüûûþüýüýþüÿþûüüúûûúúùúùúùúùüýù÷÷öùùööþôõõõööøôöôõõôôõõôôõ÷üùùúûúøöôòòðñóïíïïîíììììîêêêìêééíêéééèéèëîéçæêõæçæåååççæååæçæäãäåãäçãâãäæåãäíåàááåêæàààßÞßàÞßààààãããââÈÏÕÕÒÓÖÖÕÖÙÛÙÚÚßÝÝÞßÞààáâãäääãäåçææåçææééèééèéêêéóùííìììîîñ÷íííîïîïïðò÷õðññòòñïîïðð÷òïñòòòóôóõõòòóóôø÷óôõõôôñô÷öôõõ÷ø÷øúüø÷øø÷ùùøøøøùùúûûùøø ÷úúùùúùùùúúùûûúüûúüûûûûûûýüþü  þúüýþýûüø? üýýþþþþýýýüýþ  ýýþþÿÿÿþþýþþÿþýýüýÿÿÿÿÿÿþýýþþþþþÿþþþþÿýÿ4üüýüüýýûþÿýüýüýýýýýþýýþýûûüüûúúûúûúúúùúûúúúø÷úú÷öþýöõöööüöõõõõõõôôôõö÷øûþùûùöõöõõòòòñððñðîíììíìììëìëíêêêìêëêëéééìóïççìøççæåååæçæåéïëæåãåçåââãæââããããæãáâáååââááàààáÞÞàßàáâàßàâÑÓÓÓÖØÕÕ×ÙÚÙÚÙÞÞÝÝÞßßààâãäääããååæèíóéèèèêëêéèêëêëíðíëíîíîîòñíìïðñððóòøðóóòñððîïðòôñïòóôóôõôôóóôôóôôõøööõôô÷øõõö÷÷øúùøúùûúùùúúùúúùùúûûúùúûûùúûûúúúúûúúûþýüüüüüýüûýþþüýüýþüýüþþüýüýþþþþþþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿþþÿþþþýýýþþþÿÿýþûüüýüþýüüüýýþüüýýþýýþüýýþþýýýýýüûüüûûúúúûúùúùùúúúùø÷÷øö öõööóøõöööôôôóóôôôõõõö÷÷öôöôóóòññðïïïïíìììììíéêëëììêêêéééêëéèéêéçæçêååææåäåæååë:ÝããäåäâáâæããáâáâáâààßááàßßààßâààÞÝàßååàßßàÐÒÒÔÖÖÕ×רÚÚÛÛÞÜÞÞààßááâããååååæåäì(sòéèèéëêêêêêêëììíîïðîíïíñîïïñññòóòñðñòóóóòòññð÷óöñïôõóø÷ôôôóôôõóôõ÷þþ÷öõõ* ó÷÷ö÷ø÷øù÷øúùýûúøùúúûûúùúúúúúúúùúüúúúúùûüûúûüþþüûýýûüÿþüûüûýýýüýüüýýþþýú ÿýýýÿÿýýÿÿÿþÿþÿþÿýÿþýýÿ ÿÿýþÿÿþýýýýýþþþÿþÿþþýýýþüüüýýýþþüûüýþýþýüþýþþþþýþþýþýûýþúûúûûüøúûùùùùýû÷ö÷ø÷ýõõôøõôöõöõôôóôôóóôôõõôóóóõòòññðððïîííìììììíìëêêëéìééêïìéêëéèèæææææææååçææææåääöâãâãâââááââááââââáàáäãàáâàßßßáßßßÞàßæäàààßÒÒÒÕÕÔÖרØÙÙÚÜÝÞßÝàáààáâããããäæåååçïõèçéèëéêéééééêìììíîîîîìíðñðíïðòòððñððððòôòòñðñ ôôñðòóòóôôóóôôóôõõô÷õöö÷öõööö÷ø÷÷ùø÷ùøúùùùøùùúúùùúûûûûøòöúûùùúøùúûúûûûüýýüüýûúþûûüüüÿþýþþþýýýþþþÿþþþÿþþÿÿÿþÿþþþÿÿþÿþÿÿÿÿþýýýÿÿÿþþÿÿÿÿÿýýýýýýýýüýþþüþþýýþÿÿÿþþþÿÿþþýýþÿýûùûþüúúúùúùùúù÷÷÷øøöõööö÷ öõöõõõööôôôõöõôóõôõöôôòòñññðððïíïïìíîíìììëëìêììðìðíêêëêéèçèèççèèçêçèèçææåäâãæåãäããââáâáââäãåââáâåäââááàÞßâàááààÞæâÞããáÔÓÓÕÔß娨ÙÚÚÜâåßßÞáââââããããääåååæéæåèèèéêêìêêìëéëëëìíîïîííîîòïïððïðñòòññòòóõôóñïñùôòòòóóõöõôôõôôöõõööõõôööõöö÷ø÷öøø÷÷÷øù÷ùùùùûüùùùùúúùûüüüù=ùúûúùùüüûúüüüüüþþýýüþþÿþýýþýüÿÿÿþþþÿÿÿÿüÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿþÿÿÿÿþ ÿÿÿþÿÿÿþÿûûýûüüûûúûüûúùùúù÷øø÷öøûõôööùöö÷ööööõ÷øõôóôôõøõôóòòñòñððñðñðíîîíííëììëìí÷ûïìëêêêéêêèèçéëéèèéééèçæèçææåæåååääãããäâäääåæåâãããääâáááààáßàßáàßâãâââáÓÓÕÖÖÜÞÙÙÛÜÜÝßáßàáááâââãääåæååççæèêèèîéêìïñïìíëÿëíîîõðððñïôðïññðññòòñòôõôóôôôóòöõôóô÷öõööõõöõö÷øöø÷ö÷ö÷÷÷ø÷ùûù÷úûøøøøùúùúûýúùúûúúûûûúûûûö$x=úýýý þýþþüüùúýüþÿþÿýþÿÿþýÿýýþÿÿ(ÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿýüýüûüýýýýüýþüûûúùøø÷÷ö÷ù÷÷ù÷÷öö÷öö÷øöõôõöóòóóîðòóòóðñðïðñðóòîíëìíìëëëêêìôõíëêéêêéêêèççéêççèèééçççèæåçèæåæåãåäãââáåäããäãâäãáãäãâááàààààààáààáâááâÓÓÕ××רÚÚÛÜÝÞÞààááâáäãâäåææææçççèèèéêëêëìëëðîííððíîîïïóðññññõñðñòòòòòóóòòóóóôõôõòõôõøôõõöööõööööõö÷ø÷ö÷÷õöø÷÷ùøøø÷øøøøùùûúúûýúûûüüûûüüüüûüûýþûh üüþüûýþþýþþþþüýþþþþþÿÿÿÿÿJiÿÿÿ ÿþÿÿÿÿÿþþþþþüÿýûþþüýüüûùøùúüø÷ø÷ö÷üøõö÷õõöøøöõôõöôóôùýòñòñððõóñðîóôîìëëëìëëëêêëêéêëëééêéèéêèèèççèççèèæçççæäëëææååäåäãåéáãâââããâãâåäâääáààáààâááßáààáââãÔÕÙÚ××ÙÚÚÛÜÞÞÞßááâàáãâãååççåææææçççèêèéêëêíîìëîíëìíîîïïðððððôðòòñòññ÷þøÿóôôõûöóôöóó÷ôõöõööööö÷øõøýõ÷õõúööøøùùø÷÷÷øøøøùùûùúúûüûûüüûüüûûûüýþýúüüû‡ úüüü&úþþþýþþýþýýþþýþÿÿÿÿÿþþÿÿ"À>ÿ  ÿÿþýýüüýüþýýþüýýýüûúùú÷ùùøøø÷øøøúøóò÷øööõõõôö÷Zòñññðð ÿòôôïíïîííëíëìëêìëêëëìëëêééèéëèéééèéíéçèçççççæêéæçåæåäääæèãäâããåäããâéçâãâââââáãâââáââââããâÕÖÙÙרÙÚÙÚÜÝÞÞÞáâááâââããäåååæææçèèèéëêêéêêìíìíîîííîîîïïñðïñðóòòñòòòòóõò*ôóõö÷õööôóö÷÷÷÷ö÷÷ø÷ö÷øõ÷öø÷÷üù÷÷øøùúùùøøø÷ùúúûþúûûýüüüüüüüüýüûüüýþýýÿÿþõýýýüýýûýÿþþÿþþÿÿýþþþþÿ0°ñÿ  = ÿþþÿÿþþÿÿÿÿüüýûûûù÷øùøùøüùøùüö÷÷÷÷öõóùôòóòóòñõûõîððïîììíîìëìíëìììëëêììéêêééêêçéîëèèèçèçéèæçèçæèæäåääåääããææääããæåããââããááãáââáâáãããããÖ×רÚÚÚÛÛÜÞÞààáâãâãääåäääååçèæçéêéèêëëìëìïîîðïîîïïïïðòòñððñòôóóòóóóóôôôü÷õö÷÷õ÷öööÿ üö÷÷øøùúùùùøúûøùù-ùüûúûúúùùùùúúúúú ûûýûýýýýüûýþýüüüýþþÿÿþÿÿÿÿÿÿÿÿÿÿþþÿ  ÿýþÿÿþþÿþþþþýÿÿúùúùùøùøøûûøøóiÞiõ÷öõöö÷õóòñòôòóñóòññðïòóðîîîîíííïëëêëêëëìêêêîíèêêêéêêéééèèèçççäåææèéâÜåèååäãäãâæãååââããââááááââßàááàâáàáâââããרÙÚÛÜÜÜÝÞßàâááâäæåäåææååææèéèéêëêëíêëëìíïïíïîíîððïïðòôðòñññõôòõôóôóôôôóóõõ÷øö÷öö÷üúýù÷øøøøùùø÷øùùøùùùûúúýûúúúùøøùùùûüúùúúüúüüûûûûûüüûüûüüüýýýÿþþþþÿýþÿþþÿþþÿÿþÿÿÿþÿ#  ý*jÿþþþÿÿÿþýýüüûùúúúøûøøüù÷ùûw&Œéõôõõöøôóôòóòðñòòòòññððñðííííììëììëëêêêëëêêêêéèéëèéëêêèèçèçççèú÷äçâ4)äçåãâãâäçããäâàâãâáàâèéâáßáááßââáããâââãÖרÙÚÛÜÜÝÞÞßáááââæåãääååæçææéìééìëëìêëëëììíííííðîêððïðòñðððïòõòóóóóóôôôõôôôöööúöö÷þø÷÷øþÿù÷÷ö÷÷÷øöøùøøùøùùøùøøùùùùûú÷øùúüúùøûùúüûúúûûüüüûûþþýýþÿýýþþþþþþþÿÿþÿþþÿÿÿÿÿÿÿ  !     %!/ þýýþûüûûúúùúüúùùþÿú÷öõôõõøÿüùóóôòúõòòòóòðïïîíîîíëëìïììëêëëêììêêêèêìêééééèééèèçèèSáèÜ}sßæåäããããäããßJ&éáâáàãíîâáßáááááäãåæäãâãÕØÙÙÙÚÜÜÝÞÞßßáâáâáäääääæçæææéìééìëêëëëìëìììíîííð;f òñññððððññõóñóôòôõôôöõôôö÷øùö÷÷ùøùùùýüþýùøùøøùùúøùøøøùúûùùùùûüûúûýýúûûüýýüûûûüýüûûüýýýýÿþþÿÿÿÿÿÿþÿÿÿÿþþÿþÿþ                     ÿÿþüþþüúùûùùøöøúúúùø÷öö÷öõöûøóõôóùôóóóóñðïïïîíìíëììïëíìëìëêêêêêîîèéêééééèééçéééèî+ ãèå#h*ãååæäããââäãÞ^6êàâáàâååâààáááââäãååäããäÖØÚÚÚÛÜÝÞßßààããâóìãåæææææèééçééêêéêêëëìíìíîïíîñ>pôðððïðññññõóõõôòóôôôõ÷õõö÷øø÷øøùøùùúøúûúùúûùøùúúøøùøùüúúúúûûýýûûû øûüúûüüúúûýûûûûûûýýýþþÿþ&$# ÿÿþÿÿÿÿ                                             ÿþýþûúùùùúø÷øøøø÷÷÷ù&ôöõôõõõõóóññòõóòñððððííîëìëíìëíìëëììëëëéþêêêééêëèçèèéêéêçãæèçéïëáæååååäãâãåãåàÞàââáââáàààààáßáãäãäãâããäרÙÚÜÝÝÞßßààáâáãþñãåæéèææèêêèééììëêëííñîîîîîïñòýÿóððññññøòòöó÷öýùôôõöööööõø÷ùùøúûùúúûûúúúúúúúùúúúùüúúùûûúûûüýýüúúûýÿûûüýüþýüùK#üüüüýþþýýýþÿÿÿ>ÿ6ú                                                          ÿþþýýýûúúøùøø÷ö÷ö÷÷ö÷ø ôôôóóóòóòòòòðòóòøöððîíðòîííìëëííëìììëêñðóÿøíêêèéêéèèéëèçëéèèèçççååæååæèæâãäääããâáåäáâááààáàßáìááâãàáèæãåØÙÚÛÝÞÞÞÞÞááâââãäãæèææëéæçèçèééêìíìììíîñîîííìïðððïñññòõñðñ÷ôòõôöôýúóôö÷õö÷÷öùøúùÿûúùúúûûùøýÿùùùùúúúúúúùúûûüûûûúûûùûùûûüúýûûûø2ÿûüüýþüüüýýýÿÿ %! ÿÿÿÿÿ                  @7                         !G               ÿþüûúúûùøùúøø÷ö÷÷÷ùø÷÷õõöôôôôôòóóöõóôõóòòðïñóôðîïíìííììííììëñòëíñîëëéëêêéêéìêèîðëçêéèèçæææååêæããåãåãâãâêçàáâââáàáàäöâáâàïïêåæ×ÚÛÜÝÝÞÞÝÞßáâäâãåãææææçççèççèèéëééëëêëìëííììíîïïïïðñññóñïñïòñõôôóôôôôööõö÷÷ø÷ùùøþûûùùüüúúúüÿýùùúúûþúúùûúûúûüúúûúûûúûýþúüüúûûûûÿýüüýýýýýýýþýÿÿÿþþ                 ]S                 !E             þüüüûúûúúùøøøö÷÷öøøõõöôóõóõóóôòóööôôôòòòñïîîíîðíîðíììííîïìîîíìëìíëêêìêìêêéèêéîöíçììçèéæäååäççääãääâááâããááâãåáßßáâáãââßüèåååØÙÚÞáÝÞÞßààáâãããéåååæåæçççèééèéêêëëêëìíìííííîïïïïðññóññòññðôòöõôôóóôõöõõö÷øøøøøøùúüüûüüüüüúúûûúûýûúûýúûûùûúüüüûûþþûûüýüüüþýüÿûûüýýýýýýýþÿÿÿÿ                                                 ÿýýýüûüûúûúøùùø÷øø÷õõôôõôóóôôõôôõõõóóóóñðññóòðòîíðïíííîíìíììîíìëìëëêêëñéëìêêéèéêéééêéèçååæååæåååçãââááââäãàáãááàââãæããââçæåææÙÚÜÞàÞÞáßàâââãåçéæåæçççççèéèéêéêììíìëìîííîîîïïïðñòóóôõóòòòò÷ôôõóóóôöøöõ÷÷÷øøøøùøúúüýûúüüüüûüüüûûûûûüüûúúûûûüüüüüýýûüýýüýýýþÿþþÿþýþþýýýýþÿ ÿÿ                     ÿýþýýûüûüúøùøøøøøöõöøõôôôóõõõôôóööôóóòòññòññðððîïíìïîíìíííîíìëëëëìëêëëééìêêéèééééêéèèèçææçæçæååæãäãââââááàßãéãáãâäåäæããäçêéçÙÛÜÜÞßÞààâæáãâåèèèçêêéçæçèéééëêêîëíîìíìíïíïïîîïñòóôôóöôóòòòóôôõþùóôøøõö÷÷÷ùúûùùøúúûüýüýüýüûýýýüüüûûüüýþüýüúûûûüüüûüûüüüýýþýýþýýÿýýýÿÿþþýþÿÿ            ?B       ÿÿþýûüüúúùøøùøø÷÷ö÷ùõöõöôõööõôôö÷öóòòòðòóðïïïðïîìíïîìîîìíîîìêìíìììëëëëëéêëêèéêéééèèçççææçèèåäãâãääãâââáãäàëúßàáâãäçæãääåçèåÛÜÝÝßåèßàãããåäãååèêééèêëéçêëééëëíëìííììíîîðïïïðñòòóóòòôóòóôôôóõ ÿóôõõõööööùûþùùÿûûûýÿþÿþþýüüýüüüüýüýüþÿüþûüüúúüýüüüüüüýþýþýýüýýýýÿþþÿþþþÿÿÿýþ  $:            Š7Ü@           ýþýüûûùøùùùùøøøö÷ö÷ööõö÷õôôôôöõóòóòññññïðððïïîíïîííîííïïíììííìíëëìðììëììêêêéêéèèéèçæèéèçääåãäæãââããâæçããàááâççäåãääåååçèÜÝÝÞßãæàâââãåääåæêéèèéî æëìêêêëëìíòïíîîîïðððððñòóòòóôôóõôö÷õô÷ôôööõõö÷ö÷øùúûúüþýÿÿþý þýýþýýüýýþýüüûûüýûúüýýýýüýýþÿþþþþýþþýþÿÿÿÿ( â3              /!"(âE               ÿþþüýüùøùùøøø÷÷øùøøööôööõóôõóôôòóóòòòñòóñïïïïïîîîîíííííííííîîêëëííííëìììêëèù÷çèéèèèèçççåäãäåäååããããââáâãàáááåöáããããäææéêÜÝÞßàààáäâââääæåççúðççëÿÿïòíëîëìëíììíïïîïïïðððñòòòóòóõóóõõô÷øõøõô÷øöö÷ö÷úùùûûúûýþÿ þÿþýÿþþýþþþþýüüüüüûûþýþýþÿþÿÿÿÿþþÿÿÿ!  ‚C                        ýýúüûùùøøøø÷ö÷ùú÷÷öõôõõõôóôóôõóóòòòñï'ðïñðîîïíîíëþëííìííììêêìïêëîëëîìëìêîïêêéèèèèæåéæääãåâèêçåäããâááàáâãâââãâãäååìëèèÝÝáãàâãæäâãååæ îéçéèèèêëêîòíñþííìîîíïðòðîðððññòòòôóóôõôó÷úöõõôù÷õõõö÷øøøúûúüûúüýÿÿýþþþþþÿÿÿþþüüýûûûþüýþþÿþþÿþþþýýþþÿÿ                           þýûúúùùùùù÷÷øøö÷÷öõöõöõòóõõõôóòòñòðüðïñðñïîîîíìúøïïïîîíìêêêëîëííëíòïìëëëëìêéêëéêæçéæäæäæêåçóìããââããáàáãçåâåããèôéçéççÝÞßàààáããâãäãäìææçççççèçèêëêëìêêîñ ÷íõõóððïðòññòóòóõóóôõúóõô÷÷õööö÷ö÷÷ùúúúúúûþýþþþÿÿÿþþþþþÿþÿüüüüûüüýÿÿúõÿþÿýþþüüýýýþÿ            /""!          þýûúúúùùø÷ø÷÷÷÷ööõöõõöôóõõóòóóòñòñðíñðððõðïîîííìíîîïîíííëëíëììííìîïîëëïîêêééêêééæèçæçåææêåäçäååââàî$àæëääãããäèçåççæÜÞààââãâââãããåäæäéêèèééèèéëêèëëìîðòøîðîïôñïïðñññôôôõóôõöûõõõöùù÷ö÷÷ö÷øøùúûúúûþÿÿÿÿÿÿÿýûýÿþýýÿû÷üû9† ÿÿÿÿþýýþ       "  !!!! !#!    !   5       +n¹O ÿþûúùùøùù÷ùø÷÷÷õõõööôöõõõôóóóóóòòòõðððððòðîíîííííííîîíîííìïíìììíìììîíëïîììêêéèèéçççæèæçäææåãäæåäåàñM~âéäãæãâââååæææèÜßáááåèåãäâãåäæç ôçéééêéééé9èëìðôîïìíïïïïðññòôõôôõôóôôôõøóõõø÷ù÷öööø÷÷øùûûüüýüþþÿÿÿþÿþýÿþþþú'Fò{ÿþÿÿÿ     ‰îZ !'(  "+' !""#$%##!"#"""#   "!"#  !!!  "'              ?AAÎþþýýûùùùùúù÷øø÷÷÷ööö÷÷ôôýûöôõõóóóóñòôñññðñïîîîöñîîïïííîîîîîîîíììëìíëëíìëììëëêééèçéççæçææåääææäåêèääãæ÷ãâááâãâ íãäåæçèÝÞßààäéäããâãæèæçþîæèèèèéééêèëìîîõîùðíîðïïòòòóôôôóóõôóôöôöõõ÷÷ùøøùùúú÷øùùýýÿÿ    ÿÿþòtÊJúÿÿÿ        “~A0!!(%"(& "$%#"#$%$$'%$%##$$$" ! !""""#$$$"#"               CDÏ ÿþþüûúúúúùùù÷ø÷øöõöööö÷õüöôõôóòóóñððóóñòóòîîïöñïïïîíîîíìíîïííììììîëëìììëìêåèëééèêèçæèæçååæååäåæåäãããßÞäââáãåâþëâþöèççÞÞßááâäãäåîææçæèéççéééèééêêìïêëñìïí&÷íïðððððòóóôôôóôõõóôôôùöõöúú÷úûøø÷øùø þÿ$:5 ÿÿÿÿÿÿÿ ÿ          9S:,%#+5*"#$!"$#$%%&!Hi,%%&&$$$##!"  "##$%&&&%&%#""!#!                "Jd*ÿþýüúúûûúûúøø÷ø÷öõ÷ö÷ø÷öõõõõóóóòòòñòòòñòõòððïïïïïîíîïïîìîíîííëìíìíìììííëë" éêëêëêèæèçæææçççåååäãäææäååâãáââäçåäùôèéëÞßâãâââääæìæååæìçæçèèéêêëêêêêìëîöìíîÿñîïðïïïïòôòóóôøõõôõôöõõúöõüû÷÷øøøøùøúúÿþ  ¬12  ÿÿÿÿÿÿ            !+cF'#%$*,(&&&')%Jt;&(('&&%&&"($!$%&'((')(&%%%%"             ÿýûûüüûúúùøøù÷÷÷ö÷ö÷ööõ÷öõõôõõòóòòóòðòò÷ñòññïîïïîîíîïïîîìííîììììëííììììæ+¹‰áëëêéééççæçæçéèæææåæçæåäãäãâãâããäãäåèèæëìßàáâáâãäãåäæååæìèèèæçèéêêìíëëíîíëíîîìôñïðîïðñóóöøóõøõôôøôôõööûøøøùúúúûúüüüþ  ‡Ï8 ÿZÿÿÿÿ          !%4$)D6*''$TH%)))*@O80***('''(&$%$%'&'())+.))'&'&##!                 þýüþùøùø÷úùøøøø÷õööö÷öõõõõõôóóõóóòóñöòñððîîïïïííîîïïïìííîíìëììííëìììès[åëêééèçèèæçåæêçäæçåèçããâããâãæâäâäæåäåäåèéààááâåääãåæççèçéèèèèééêêëëìëëìëîìîññïöñðððñòòòóøûô÷üøõõ÷õú÷üûúúùùùúúúüýþÿÿ g¸Š#  *             !"!!  #*2&&%)+)*(?T:)+,-.77(+,,,*))))'&&'))()++****+*()'$$#             ÿþýþ÷øùøø÷÷øù÷øü÷ö÷úöõõõõóôöòòõóóóóòðñðïïïîîííïðïïïîîììííïíëìììëëíìëìêáâíêêééçæèéçæææçêçææäçïîãããâââåâãáãååææææçéààáâãäääããææçèèçèèéééêêëììëëíôüïðîðïîðñððñññòòñóöõ÷û÷õõõõþ÷÷øùúúùøøúúü ýÿÿÿ   Hq<                   !%$!"!#')&*'(**,,,*(,.../0.+-,..-.-,+*+**)++*+-+***+,+)+)()&                 ýÿÿýúúúøùúøø÷ö÷÷÷ø÷öõöøõõõôõôóòòóóóòñðòòñððððîïîìôõïïîïíììîîïîíìîíìëìëëêëëëìëêêéççèèçèççåíëæåååíïåääãââäãâããääæçççêìßààâãããäçõåçæèèççéêèèéíìëíìëì<ìðíîîîîñôöôòñòòóóòõõöõõö÷ôø÷ö÷øûúøùùúúüýÿÿÿ                    "%##%#&()*++*-,11000210122123.0//10.----.,,-,--,,,,,,,-+)))&"!          ýýúúùùùúùùøøø÷øùùø÷÷ùõõö÷÷õöõôóóóòóòòôòñòóòòñðïóóðïîïññîïîîîîìðïîíììëëëëìîòëìêêèèèèéæææééæåååäåççääãääãâãçåææçèêììàááâåçâãì åçèêèèçééìëêííëëìíìÿ'ìîíîîïðòõúøòðòôöôòôõôôõö÷ýõ÷øøø÷ûúøúûüüûüýÿ                  !""%%$%%&)+.-+--2/24545775665445122142200000//////.-.---,,,,,*(%#               ýþüüûüüûúûûúùù÷ù÷÷öøúø÷÷öø÷ö÷ôóóôôòòòóñ÷ôóòòòðððððïïîñøíïíîììíìîîíìììëììëîóíëêëêèéééççæåææåäååäíóâäåæääããçäæåæèêëëáâããåçääìøæçèèééçééííëëëììíîíëèïðñðñïñòóøöñóõõõôôôôôõööö û÷øøùùùüýûüüüüþþ                      " ""#$%%%'('),37.//2:2246679;:9877776664645544312211000//.0..7L..**'$#!              ÿþþþþûüûúúúùùýùûûüùû÷ø÷õø÷÷ù÷÷ùøóòòóõòòòóòò÷õòòñññððñðïïîïîíïíîííìíîîíìììëëîððëëìëëéééééçéçææææææåäìòãåäåääãååáäæçèéêëâãääääæååäçèèèéééééêëëëëííìííîíïñòðñïïññóòñ÷ø÷÷ôôóôôö÷öõôöùø÷øøøüüûüüüýþþ     1                 !$$$%&&'())*-48141593467889<<<<<<:;;<:9989:86697454211200100<b0/-+)&&#              (³Bÿÿÿýüüüüûûûúùúúùùøûüøøùùùùù÷÷øø÷ø÷ôôóóôõóóòóóòòñòòðïñññðïðïîñðòîìíïîíïîíîìííëêí÷ùëëëëêééèéèèèçææææææååäãååäääääååõìèêëééëââáâäåæååææççèèçêêéêëëêéìíìííííîïïðïðððññòòõöøøóøüô÷ùõõööûù÷øøøýýúûûýþýþ    ’^               !)#"!!$%$&'%')((+--10162433689:;==>@?@B@<>?==<===;::=;8865323211214D0..,)*'$!             K ÿÿþþýüüûûûúúúùùùûùúøøùúø÷÷ööúøôúûóôôñóõñóòññòðñòñðîðñðïðïîïïïïðïîîïïîíííííííìëìíìëêëêëéèèèèææååæååææççäæçìåääääãýçïîêêëãáâäæêéèèçæèéèèèééêêëìêêëíîíîííîïïñðññðñòòóóóôôóùýõúúôóõöùûùøö÷þþúúûýýýÿ      E0                 !!###$%%'((()**-0/1.24456679:>@BAABBBEF@@@B?>?>?@?>=<<<97655432341/1/--++(%"            ÿÿýûúúûúúûüûùúüûúúùùûøøøø÷ûùöøùöôõõùùöóôóôóññòóòòñññðððïîîîïðñòïïïîïîïïííííëìíêëëéêìëêéèççççææææçèðôäåçðääæäæã ùèíìêììâáâäåêôïåçæèèçèèìêéêêëêêìïðìíííïðïòððôõóòóóôòñôôôõöøù÷ø øö÷þüþúýüüýþþÿ #%%"                            +8  " ! !!#$*'%%%())++,--.4513876789;<<GDCDDEFGEDDCCDACCABDBAB?>>;9867554553340//.,(%"!            ÿÿÿü  øúûüýüýúþ  ûùùøø÷÷ö÷ø÷÷÷öõõöøýööõõôóññññïðññððððïðïíïððñîîïïïîïïîíììììëëëììéêêëéêéèçççååååææôüäåääääéäåæäæéééêíîãâãäåæåèæèçèêéèêíìëíííììïïîïîìðîññðððøúôòóóòñôõ÷ùø÷øüûøøþý(ùþÿýþþ  !"+4651+(                              |¹  #" !!!#&&)&''()*/0--.09?16@876:;>@>FDCDEFIJGGIGFDEHHDCEEDDB?><<<9765464365211.-)%#!#            ÿýÿÿýY1õûüýüòaDtþüûúøù÷÷øø÷÷øööõôöööõôôöôîòòññññññññðññðîíðïðñíîïïíîïîíííììììëëëìêëëêëëëéèçæçççææçæåæççåäæçäåççèéëëëëìäããääæçæçéèèèèêèéêíîëëìîðííñïòïïïñðïðñóòñì@Qíôôõõõöõöô÷ùøûúýúþþüþÿÿ  (;HR]WK?/"                            % ;#!# !'+"&&$$%#&%&())*+**,../01<F4788<;<?@AA@BEGIJKKIKMJFGHKIIFGGGEEC@>AIE789<65574322/,)&%""        ÿþÿ#úüüüûõJlùúúûûùø÷ø÷÷øøø÷÷öôôõõõõôõŽ íñðññðïññïïðñïïïñïîïîïïííïîîìëììíïðêëìêëëéêíêéèèéèæææææåæéçäæäæäåçççèéêêëëìâçêääêöëèèçêçééêêëëëììììííê÷K‰íðïïóóñðñòòôôðñ÷öööõöö÷ö÷÷øùøøøùúûþþüþÿ  !1Y‡¾äÑ”W7(                          ""  "##$)2&%&'(((),0-,-/0/002336888::>B@ABCDEGIJKKKKKKHIKMLKLJJHHGEC@EQL;<AN87744211.,*&%$         øúþýüûüþ +ÿûûúùùø÷ø÷÷øøøø÷öõôõõööõõjîòóóóñðóóðïñóòððòðîïïððïïïïïîîííììììëìëëêêêîëêêèééçèèçèææçååçåæççëèêëëíììììàçäæçèçéðëëêèïíìììëìííïïîîïïðõóñðóòòóóôõöõóõööööøøøøøøùùùúúüüýþÿþýýÿ    "$+@pþ¸½mB0#   Zzû       Ýà1 ³Y“            (!##$$$%(+*(*),,-+,,31,MI/333468;::=<=>@CCDGHIKLKLNLKLKKMMNOOOMKJGHHFEB><>BJ:86554100,+'$#!       þþýþýûüÿûôøþûýúøùù÷øøøøøøø÷ööõõô÷õöööùñóóòññññòñññòðñóòòððïððððïïïîîíììëëëìëëëëìêêéêèèééèèêéææèçææåèçççèêîðñòóóðíâèååçèèëîíëëëëëëììíïïîíîîïóþïðòòóòòõøóóõöôõöõ÷øúøúøùùúûúýüþýýþþ   $1L‡£ tAG1$   Rp n      3ABùäà              1!#%&'((''((,*+*,,+02//<A;6288479:;<<=?BBCFGHHJLKLMJIKNNMNPQPPOPOKJHFE@Yk>AF;98553116+('""! #        ÿþýþüúûûúúûúúûù÷÷úúùøøøø÷øø÷÷öôóöøöõõöôñôòñððïóôññððïðòïîïîïððïðîíîíìíìëëìëìêìêêéêééèêêèççèëëæåæèèçæåååäèðòóóñøõîîäôüææçéëëéêëôïìêëííííììíííïðñóððòòôóóôöôôôôôôööõö÷÷ùùùùùúýûúüüüýþý   #2L—ŽÓ?#wC.#      ý }       z‚#e¸R        ! '&$$%&'')*(((,,+,---10/002/UŒh687:===ABABFFFEJKJKKLKJINQOORQQRPQQQMJHFE;—Ú:Mi:;9553101.*'$#%$              þþýüúûýüúúúûùùøü÷úùøøøøøøøøù÷öõôöúöôõóóòóòðïïïðòðïøöðððîïîîïðïðïïîìììììììëìëëêëéééèèééèèèééèçæçççåççåæççìêéêéøúðñåççææçéêéêêëöïëìëììíííìíîíïñððòóðóóôöòóóôôõõóõ÷ø÷÷öøùøøúúþûúûüüüüÿÿýþÿ   #/E€ºåf½]8+"         û                    #$$$%&()+1)*,,,.-.//0020250Cj`7:9;?>AABACFGEEJKJIJHFIMQRRSTSRSRQORQLKIGGHFA?<<?<96510/,+)&$+)               ÿýýýûúüþýüûûûùûùúùøøùøøøøøùøööõõõ÷õôôóóòñðïïñðïòñïÿùññïïððïñöòñóóøøöïëíëëëëéîêéêèèêéèééééèçèèæçåëççèèéëéêëê÷øïîæååççéíêêìêëíëëìêêìíííííïîîïðïññóòòøñûùõõôõööøøöøùøùùùýûúûþþþÿÿ );_†«²iG/$          :J           % !!!"$%&&),++,),---.../001223547>>989C_ABCCCDJJIHIJJKIGKRTTUUVUUTTVTSRRRPLIHFDCAA<?<96631/.,)('%!             ÿþþýüüûûûüüûûùùûùûúùøúø÷÷÷øøöõõöùõôôôöõôóñðððððñóòì(tþïòôïîòñðôññðø28 ïîììììêëêðêéëëêééèéèéêéçèèèæçëçèééêêêëëëíîîîåæççèêëêêêêëëëíëòëìíïîîîîðððñóññòøøôõõõõõõö÷÷÷ùüøùùøùúüþýýýüþþýÿ &2:FSUJ;3)                #5              -( ""!"%%')16,,,,,./---.158323335668::=?FBCCDEGHIIGJKIHHJPSUUX[WVUSTTVUTRSQLKJIIEA?><;7642/.+),*'$                 þþýýýüûúúûûúûþúúùüúûúøùùø÷÷÷ö÷õô÷ûõöôô÷õôõòñòóñïñóòð=øïóõðïòòððñðïô ûìííììëêìëëêêëëëêééèèèééééééçèèèçéèêêêêëëëííîäåæççééééêêêìëíëûûïëìðóïïðïððóòôðñññññ÷ûöôõõ÷÷÷øùùýùøùûüþ˜Eùûýþþ  $'-22.*'!           "                !"""$%%&).0,-.-,/--//14665455689:;;=?ABCFEFGJJLGEGIKMNQVWZZ[_Z\WVUTUUXWSSQNNKIGEBA?<;9410.,+,+(&"          ÿýþýûüûûûùûúøûúúüúùøúùøøøø÷öõö÷õ÷ôóõ÷ôòñòóòññòòóðéðñòñòòññðïððñðìëííîîíììëêìëëéèéèöïçééèééèèèéêéñèççèçééêêêëíîîíãìñççéëéèêêêëëííîíìììîðïîðïðñóôõññóòôöúúöõ÷÷÷÷ùüýøùúúýW¦ üþþþÿ  !#""                             !  "#""**')++*,..-,--./0246666877;<=>=@CCEEEHIIKLMMIHGLSUUVZ]`b_]\[YWUUUVUSRQOOOKIGEA@=<;4321.,*((&" (0        ÿþýüüüüûúúúüúùüýùüùøøüÿüúúù÷ö÷÷ôõôóóôöñòòòñòòòñòóóññòòñòóñññðïññðïîîîîíîîííëììëêéééñíèééééèèèçééèìèèçæéèéëêëìíîïïäéíççéëéëëìëëëííííííííïøúîððñòòûûõòóôóóò  ùö÷öøøùýùùúüúý>ÿÿýýÿÿ                                 P{3!+" !#"#%*)')**,,-./-,/0*03469887gf8?ABCEJJIKLNLLONNPQMLRVZ[YZ`de`_^[ZYWTTVUTTRPNOKLIDCC@=;7430-+*((&$!  «ÊD        ÿþþýýýýüûûüûûúûüüøùùøùýÿûüúùøù÷ôöôôôõóóòóôóòòóòòòóóòòóòòñòòòñ üññïïïïîííîîìììììêëêêêééèçèëëééèçèèèéèèçèÜçééêìíîîïñääåçæçêíìììëìììíîîïîîîïóõïðññóóõóôôõóòòôÿÿøöûÿúùøúùúùûûüýôøýüÿýþÿÿ                                 ¦ ^ $/' !"#"#&%%&&(*,,,.////2cA5889;;:WX=BFHIJPPORSURTRRSSUSTZ]]^``cfedb_^\\YVUUSSSSVSMKKJFER¾ÉJ54200-*('&%"    !       ÿÿýüýûüûûüüúüüûøùøøøùùùùùûùü ôöõõôõôôóò÷õóóòóòñòóòòôñññðñóð ýñðïïïïîííííìëëìëëêêëééèèèêíìèéèçèèèèèèèéæãèëêëîîîïðåæèéèèéìëììììíííîîîïîîîîîðñòòóõôóòõöóóóõõõööúýúøùùùúúúûúûûüüýþýýýý    a.             ,7         ^—<-# ! !#""#%&'(.2*+-/0012¨^88:;=>?=>DHLOPQSUU[\ZXYVXXXXXY]`^`dfggfehaa_]ZWXYURQQSSOLJJJIS ZY27432.,+)''%             þÿþýýüüýþþúþúùúûúùùùøøúøùúø÷öþõõõôôôòóóóööôòñòóóóõòñòñññññòñîðóòïïïîïîííìììëìêêêëëêêéèêëëêèèèèèèççéèèéëåçëêëïîìíîåèééêéèéëìïîíððíîïðïîïðððñòóòòôòóòööõõôõöö÷øøøúúùùøûûúûýýüýýýýþÿÿþÿ    1              0Þ+          "5-$"#$%'((03*,-10012sT99;=?BDELQPSTWWXYZ_^]\]^_^^]]]^`bfhkjhigjeb`_]ZXXUSRPRUPLPMIGIsˆE88655/.-*))&"        ÿþýþýûüûùûùúùúúúùûùù÷÷øøùùùø÷øóôõõõôüøùõóôõ÷ôòôõôôòõòòòòñòðòññïïöôïïïïïïïíììíìëêêìëêêêéëìëéèèéèéèèèçêêèêèéêìëìîîîîîåçèéêéééììîîîñðïïðóóïñóððñóòóòóôó÷ôõõõõ÷÷øøùùúúùùùûúûûûüüüýûþÿÿY     ,            4ï>     !"" !#G7'%((')*+,+,.,0/236/;;>?ACHKLV[VZ\]^c__afcbbcdcceddegiloonkkijgedalbXUTSQPSRMLNPQFC=9=876641/.,*''%            ÿþþüüýûüûüúûùùøÿùùùùúûùùùúýõöööööý&ñôôõôó÷øóòòôóóóòòòóóòòñðõóððïðððïíììíìëëììëëìëêíìêêèèèéééêéíìêñëêëìììíîîîîïåèéèééêéíììííïïñññôôñòóññòôôôôôõô÷õöööö÷÷÷øùùúüüùúúüýüûûûüüüýÿR                             "C! "#$#%%#&%&'%&''-+*,-..//0/0136;;=@ABVUORUY\]aebdiefgnkhhhijklmlorqqrrrqlkkjgechbZ\ZURPOMKKHJJCB@@=:7420.-.,)('%!         ÿÿýýýüûûûûüûúûûøúúúúúùþÿùùøøøøù÷ø÷ö÷ùL ðóôõôôóòñòóóôôôñóñöôóòððôòððïïîíííììíìêëìììëîëêêêêêéèèéééìéíëéöëêëëëëìíîîíïêééêìêììïîíííðñóòòòòòóòòóôõöôõö÷öõöö÷÷øø÷ùùøúúúüüúúûüüüûüýþÿýüýþ       +:-                            p.!!#&'%&&$%'''&'((*+,-..-00211247?=?BED__SX]^_cfihjijnlopoooopqrstuy{wvttvxolljff`^\_^XTOLKIGEDA@@<=;8730-++*))(17!          ÿþýýýýûúúúûûúûüùýûùùúúúúúù÷ùþûø÷ù÷÷ö÷óõôóôôôôóòñòóòóôùòóòòòòñððïðñððïîííîîííìëêëììëëëêêéêêééêéèéëéçèêìéêêëëëëìîîíîùåèëñêîíïðïðððòòññòòòóôóóóóöõõ÷øù÷öö÷øøøøøùùúûúùúúûüûûûüýýýÿþýþÿÿÿ        !àW.                               ""!!!(-"!"#$''(%&%$%%%''&)(()+./-./0234348>@ADGJLPU\bdfgilnnosvwxy{||yxxxyyz~}}ywv|tomljgc_^[ZYSNJIFBBA?=<><:5530-+**)('19"           ÿýýýýýýýûûúúúúúúøùúùùúÿøûû÷ý÷÷öõõô÷ôôóôõôóòóòñòóòòòòòòóòñòðñðïñóðððïïðïîíïñìëêìêëêëêêéêéèééèçèêéçèéçèêéêíïíìïîîïÿåéééëìííïîïðñóòòòòóôôôôóôôõöõùöú÷÷÷÷ø÷öøýýúúúûúûûûûûýûüýüüþþþþþþÿ     $$ír(+                        %)!!###!$#  "$'($#&'&%%%%&%%&'*+-..//.0355579>@BGLORW\adhllortvz~‚‡Š‹‘“‘މ‘„„‚~xvusqmigeacjncUNJFMW>==:9=;:7300-,,*)('(+$"     þþÿþýüûüüüûúúüüýùúúúûûûúùúûúøûýùøöööô÷ôôóôóóôóóòó÷øòóòóñòóòñòòðððòñðððïððïíìð÷ííëìììëêêééééèéêéèçèèçèééèéèéìððïòðîðçéèéêíííííîððñôöõôôõõõöôõõöõõõúøøø÷ö÷øùú÷)+öùùúúûúûûüýûûüþþþüýþýþÿ      h›hC>"#&&"/b[                     "$$$##"!""   !!#&%&&%'&+$%&'%''()*,./012137577<<ACFMQTY_dilnqtx}†‹Ž” žœ¡¦¨¨©™¤¢Š‹‰ˆ†„„|xvtoihfch1Y¬OOKFMW<:::99776363///,)(('%%$!!        ÿÿÿþþþþýüüüúûûýýùøúûúþÿûùúüûùøùúúùö÷ööúöóôôóóóõõôõóöüòóôôôóòñóòðñôõòïïïîíîíîïîîðíìîíëëêêéêêééêééèéèççééééêéëìïððïíîéêééêíìîíîððòòó÷÷óöùöõöööö÷÷÷ö÷÷øøø÷ø÷ûþ÷=Aôùùûüüûûûûüûýýþþüýþþþþ        9+9IQR;%yî‰     8                   !##"""!"!   #%')((&#$%%&&''&&&*,+-12342479;89EBEGLQV\afjotux~…‰•Ÿ¤¹ª£¨©¬®¬¦Ÿ˜——’‘Ž‹Šˆ…yvpkigdlÉÉKNNNB><:8:;75311?90//-+*++&.<!!        þþÿÿüþûüþüûùþùúûüûúúûúùúùùùüø÷öõøõóóôôõõôôóöúóóóòôóôõóóóôóññòóñïðïðññîîïíòïíîìëìêêééêêééèéèéèééêçéêêêëìíííîíïéêêëîïïïðñöôóôõöúù÷÷øùùúúúøøûùøùùù÷øøùúúûööüûûüüýýüüüüýþþþþýþþþþÿÿÿ         1{SŽåT(G|A     M                !"%#$" "" $(((,-%&&'%&''.*'*-.013555;@?R=?BGLORV\aioru}‚„Žš¤¥¨«±²±¸Ìºµ¶¸µ°ª¥¥¢››™–“‹„|wsnkhfo±½zRMON@>;:7696321075//.,,,,,&,8         þþþýýüûûûûùÿûúúûûúûûûùùùøúùø÷öõ÷úõòóöõôóóóï /ùôóòóóóòòòñóóòððññðððóüùíîííòïììíëììëêéëìêêêêéèêêêèýðêêëëìíîïîíïìëìíííðîñòóóóõööüüúûûûûüüûûúúúúùùúùøùûûûûûûûûýÿüüûýýþüþÿþþþþþþþÿÿÿ       ,C";ÕgÓe^+       !                !""""! !   #'))*'%$$''''''))*,/233699::<?@CF]^TW_biou{€™›¤ºÌµ¼½ÁÄÈÓNãÂÄÄÁ¼·°¬ª§¤¡›˜–“Œ„}urmhfh^VVSMIC?><964543310--.--,--++,)!"       ÿÿþþþüýüüüüûúûûúüüûüüûûûûùùûúóö÷øùõôóõôóóôôóùýöõôóóòôöòòóû÷òòðñòññðîïïîîîïòíìíîííìëêéïñéëììíëëêìé2éêìíìïðñðìíêëôöííîñðóóõõ÷øùúýþýþþýþûýÿûúûøùùùùøøùûüþýüüýýüüÿýýýüþþþýþþþÿÿÿ          "=Íû8Q(#                     $x'   !"!!98# #&'''(%'&&)''(*-/-/02458::;=@BFIMU]]adiow€‰´Å¯¸¾ÇÈÌÒÚÜâêqýØÖÐÍɼ¹´²²­¨£¢žš–ƒytniea^ZTPLHC?><8542021//---31,--,-..&$!!       6  ûÿÿÿýþýýûüûüûûûúûûúûüüûüúúúùùøû!˜öùöõôôôôõóñóõôòôôôõóòòôóòòôóòñððñðððïïððîððïíííìëìëëëéëìéêéêîìéêîòêéëììììììííííëìñùôîîïñòôö÷ùúûýþÿÿýýüüûûûüûûûúüþÿÿþüüüÿþþþþÿþÿÿþþÿ          ˜ñ!C&3kÆÁs7""                      fÑi   ! !**!#%"#&('&&'(&()(()--../23469;=?ABFIPRZ^fikqz…𤭷ÀÊËÒÙÞéî÷øùóï#úáÝ×ÒÌÆÁ¼»¹µ¯¨§ ”Š€vpic`]YRMJEB?<97331.//-,+,*A=,.-.-)('$"     T Q#ÿÿÿýýþüüûûûûúûúüûúúýýûúúüþüùøú Aý÷ù÷ôñô÷öôòñóôôôóóóôóóòóñóôòñòðïððïïðïðïîîïíííîíìëëëííîîéèèèêëîêêëìêêëëëëìíììííîëìíîííîññóõöùýýÿüþûúûýûúúûýþýýÿþüýýýþþþÿþþþþÿþÿ        'X%(<90+$                   J!H !"! #%&&&%'''&'(,*-,,022359<<=@DFIOW]cgnrv}Š•£©®ºÆÏÒÙâéôÿ öëãÜÚÕÍÊÆÁ¾¹±¬¦¡™†zqpf_^[RKIEB?=:841/-/--,+++<8,----+'%#"      # Š;þÿÿþýýýýûüûûúúúûúúúûýýüûúúùùúùøòöøøöóòôõôóòòòôõôöõòòôôòñòóðññññðððïïïïðïïîïíííîííìííìííêéééêêêëîêêéëëêéëìììîïîíîëëëëîîðñóôö÷øþÿ     þüûûûüýûûÿþüýýüýþýýÿÿýÿÿýýýýþþÿ         0&                      &8 !%'&'&%''''((***-/99569<??CHEINS^hmp‚…Ž™¡ª²½ËÙäéïø !,178/"õíéãÜØ×ÔÆÀº³®¨Ÿ”Œ€qŒv^^[QIGE@=>:74/.-/,+++*++,++,,-+)&$$!     9ÿÿþýþþüüýüûúúûûúûüúûýýüúøùúûøøö÷øø÷ôóòóôóóôôõ÷ö÷ùôòôôóóòJìññððñññðñðïïïïîïîîííìíîíìëêêêéëíëêìêêìììììíïïîððïïîêêëìîîðñóôöøúý    ÿÿûûûûüüúüüýýþÿÿÿþÿþýþÿþÿþþÿÿÿÿÿÿÿ                              $9 "&('%&'&'&&%(**+-.3459;=>AFIHMSYenuz‡‹•ž¦­¶ÄÓßê÷$+1;ISYVPA. ùôíæáÛÎÊǽµ«£™…xohb^WPKFC@=;874/.,,.,*)**,-,+,-,,*''$#         ÿÿÿÿþüýüþüúüüûûüýüüüýüûúûûúùùùùøøøöõôõ÷öõööõøøööõóõõõôóüïòòññññòôðððððîîîîííìíîííìëëêêéêìîììëëëììììððïððîïðïêêëíñõòòôõ÷øú !),*# þüýþþüüþþþþÿÿÿÿþÿÿþÿýþÿþ ýý            +              !  !$&&&()(')/&),--12138;<>ACFJNS[alu{„‘˜¦®²»Êáíó '.5@KWeqx{zn^L:*öîæÜÑÊ»±«¢—‹|rkd[TOIDCA=7446/---0-)),,+,+,.-*+)(+&$!          þÿþýýýýýýûúûþþýüýþýûûûúùúøúøúùø÷÷öö÷÷õõ÷ö÷öõôôôõõõõôòòòññññññðñôïñðòïðïïðîîììëëíììëéêìììîîëêêêìííììííííîððîëìíîðòôóõöøúÿ.BZfZE2 ÿþüûýþþÿÿÿÿþþÿÿÿÿÿÿ                      #%')())(+2)+,-.23489;?@CFHMSY`hox—¢¯»ÅÑàïú'1<GUdtƒ™Ÿ›‹ufYE5'îåÚÎǼµ¬£™€ricZTNHCA@=8;12--4,,++)-,++)*,*))(''%"!     0ÿÿÿþþÿþþüüýÿüúûþþüýüþþûûú÷øù÷ùùùú÷ûùõôõööõö÷öõõôôóõùþõòòòòññòñðððððïðïððïïîîïïíìëëêëììëéëëìïëêìëêìííîîíëìïïîïïììîïïòòôõöùý&NJš?# þýüüþÿÿÿþþýýýþþÿÿÿ                           .!  "&'('')((++,,-.1568:<?ADHKPW]dks|‡”¡¬ºÆÖæõ2@KWg{ª¸¾¿¾¸§‘|p^N?*$gðëàÓÆ¾¸¯¤›‘„tkdZSMHC@?=:=0.,,.+)21+10+**+*''''%&%"!     (þþÿþüýýýúýýûúüûûýüüþûýþøøøøùøø÷þûöòïôø÷öõö÷øõôôõùûõòóóòòòòðòóñ÷üîïïïïðíêïîíîííìëìëêëêëêëíëëêëëëëìíííîîîîîíîëìîïïñòóõûùü/jEI˜ÿÞN(ÿýüüþÿ    ÿýþýüüüýýüýþÿ                            5$  !%''(()')),-+..0579<=@DGKNSZahpw€œª·ÆÓçü )9K\kz¥¸ÅÕáêãÝ×Ä­–…rbS@-.)úñàÑÇ¿¸¯¦ž’…ymd]TLGB==<844/-,,,,-,)((),-,*'&%&&%#"          ÿÿþþÿÿþþüûûüúûûüþþýýûþ úøøúùùøøüûö2õø÷õ÷úûùõõöõöõôôóòóóòòóóò÷ûñòðñïï÷ ôìííîííîíëëììììêëíìöííììíîííððïïïïîìíîîîïñòôùù5œÍ RìT) ÿÿýý TŒ_ þýýþþþýþÿÿ                                        $!"$&''(()(++---.0159;<?AFJNRX_flu{…”¨µÃÓäù!2CTg}’§ÃÛíýöãʳˆuaO: ñàÓÇÀ¸®¥ž’‡{maYRLGC?;::44//.,-,+,*(()**)(')(''%$$# @2        ÿ Hýÿþüüûüýþÿþýüüýüûùúûùûùùùùùúö'O!ó÷÷÷ùüúù÷õøö÷õõõóòòóóóóñòòñõùðñðîõòíííìììíëêëëëëììïìëñíííìîíîîîïïîïðïíîïïððòôö÷ÿ 2zK)M ´G%  ÿýUSYu¼÷ÿþþÿþþ ÿ                                *   !!)"!   #%&'(((()+*-,//136:<>ACFKPV]djqw~‹Ÿ³ÀÑã÷ 3H]sˆ¡¿Úö &7FROE0êÒ¸„nYB&òãÕǽ¶­¤œ•ˆzk`WOIDA>:8642/1./.-++)'+-)('&%'+$%$"#"!           þþ© ûûûýýüüýýýýüûûûúûùúýúúùø÷øøùúúúûù÷ööùþüöøö÷úöôõôóóóóòòòòòñðóõïïðïíìîíöòìëììêêíñðëììíëëëíííìííííîîîïîïïíîîïðñòôõ÷þ *Y« ¹h5 ÿþÿþ %ñ 3Lû&ÿþþ                                      "$(#$*   O-! !#%((())()++,/02369=@CEHMSX`iou{…’§¼Íßù.F_x—´Ïð "<Yhv{yr]>% íί‘w^E+ñãÕÆº³«¡™”ˆzl_UNGB?;9742/..064,)''&')(&$#"#$&$"""!!     $  ÿÿþûýýûûþýüüüýýýüûüüúúùúûúúúùøøøùùù÷÷ùø÷ö÷þý÷ù÷÷ûõôõôôôöôòññõóçëñïïïððîîîíöòíëìëéëîðïëëëëëëììíìíìíííïîîïîïðìíîïññõôô÷øüÿ "3CORD4%  ÿþýþÿU€Lûöÿ ÿÿ         <                    +,"! ! z;!  !"&+))),1(,,-/0348;?BEHLPV]cksz‚¡®ÄÜï-A]z–¸Ùþ%:Pm…“œŸœ”…hH%ãž}aH/ýîßÏÁº±©Ÿ˜’†yl_UMFA>;87630/-.0H1('&&'('%"""#$%$!'%"!     þÿÿþþÿþýÿþýþýþþýýüÿÿýúøúúúùûúúûùùúùøøøù÷÷øøø÷ø÷ø÷öõöôôóõôòòòñ d2íïïðïñîïïïíííììññììëêëëìììììëëëììîîîïïððððñìíïðññöôõ÷ùûþ  &'# þýýþþ   ÿÿÿ           I                    ! $(  &! "!!""!#&)+,)-<*..-22469<ACFJNSX`fmwˆ”ª·Íéþ&=Ts‘²Õö$Sm™©´·»¹°£ŒgAôÒ©cI1þêÛξ´­¥•„yk^TMF@=:865401,,+2-)&'((&%$""!!$$' $!""         ÿþÿþüÿþýüüýüûûþûûûùûùùøûûúûúùùùùøùø÷÷÷÷ööù øø÷öööõôôóóóòê?Ñxêïñîîðîðïïíìíìëõûòìëëêììëëíìëêëìììíïïïðððïðíîïððòóóõøúûþ     ÿþþþÿÿÿbXÿÿÿ      /%       O             "!   " "   !!!"""%)*)**,0,-./4679:>ADGKPVZ`js|‚Ž›ª¿Øò 5Kf„¥Ïû"Q{™§´½ÈËÌʶ¤ƒ[,ܱ„bF.þæ×ʼ®§ œ’ƒwk^TLE?;<>532..,+*(((&&&%$#""  !"" ! ##"     Mÿ ýüüûþþüûùùûûúûþûùøøùùùùúùúúøøø÷öö÷öõù'øôõõô÷öôôóòòòò&!ïñòîíïîðïíììììêîõóìëëëììëëììëëìíìëíîîðñððïñîîîïðóóôõ÷ùûý       [þþýþÿþûVOýÿ       *"                  "! %$    5$!!!#$#$&()*))*-....568:<?BFJMQV\dpz‰“¤³Êâü.D\x•½ð#S€¡´¹ÃÌÕØ×ÓÌô”k7ßµƒ\A' ùãÑÆº¬¥œ˜žuh]TLD?;:;531/-,*))('&$$$"!!! !&   )$     ThEÿ ÿüÿþýýýýûýýüùøúùúûúùùùøúúûúùûûùøø÷÷÷ööö÷ôöõõõööôõôòòòòóóïíòðððïñîïîïîííëëììîïííììîîìíëììííííîîîòôñðëììîïïñòóóõöøúüýÿÿlÿýüýþþýþöùÿÿ                              &$ ###!   !"#%&$&)+++*-,../257:<?BFIMRYahtŠ“›¬¾Ôí#9Ok‰ª×BsŸ¼ÆÆÏÚßàÞÚÓʼp;Ù¯U;#ñÞθª¤š“¢‘€sdZRJD?<85320.-+*()(&%$$#"!    (""    f  þýÿýüüþýüýüüýüýûûýúûùüúùùûûýûùúûûùûûø÷öö÷÷ùõö÷÷÷÷÷öóòôôóóôóòòñïðïñðïïðñððîîîìñóîïíéðíííìîîîíïîîðïðñïø+íïïðñòóóõöøúüûüþÿÿ÷ýþþþýþþýýþÿÿÿÿÿÿ Rª                              %#  !#!  !#$$#%&&&(+,-,-//20249=@BDHLQW]fmy…“ž¦¶Éßù/KazœÃô)_Œ²ÎÕÖÝáââàÝ×Ì»œm5ФwO5 ìÚ̽´¨¡˜“ŒrdXOHD@;8532/.-+,(((''&%%#"!!       Fn  þþþýÿÿÿþÿþþýû %ûûûûúûùúùùùüüûûûúúøùúø÷÷÷÷÷÷÷õ÷÷ö÷öôôôôôóôôóòòñðïòñððïôñððîîíìííì[ïëíìîîîîïðïïððïîìü7Eíîïïññóôõøùùúúûüýþþÿþÿÿþýøúýþýýþÿÿÿÿ[Ö             """    !'$##+)&(')+())+-1./802368<@BDHLOUZ`it‡‘—¢®ÀÔê$=es‡®ÛFx¡¾ÏÚÞáãããáÞ×Ë·”c+ó—nH.æØÌº²¦œ”‡„}pbWOIA;:8400..+**'%)&&%#$"!         Z|ÿýûýýýüýþýüúùùùùùùùùøùúúúûûùøøøø÷÷õõôôõøö÷ø÷õõøõòóòòñòòñððñððïïîíîíîîìííììëéCåìììëííìíîðîîîîïîíðòìïïðïñòõõõøøøûüûúüüýþþþÿüþýýý ÿýýþþþþÿþF    &                !!! !$#"#%%&%$&)))(+-,..11335:=>@EJNSW[ak­²¯µÄ×ó *G[w—½êV‡«ÄÔÜáããããáÜÓÅ­†Qᯅ]<#úÞÐÈ´®¢™Žˆ…zm`TOIMM65>U--+))&%%&$###!         ,3ÿÿýýüý"ýýýüüüúúúøùùúûùøûúùùùøøøù÷õööõöõ÷öø÷úû÷ôôôôôóóññðñðñôïïîîíîíííííííîíìíñöîìììíííîðïîîîíïïííîïïññððòôòôõûùùùùúúúûûüüûüûüÿüûûúŠMûýýýýýýüý ÿÿ        "/,             "$!!" !!#$$$&*+(')**+..-./11458;?CEKQTW^ep¶Â¢ªºÌâú0Leˆ§Éö,bŒ°ÇÔÝáâãâàÝ×ͺ›n9ýÇšrM/÷ØÈ»±¬ –ˆ„vk_TNOdb43Bc-,))('%%####"!      + ÿþýýýýýû?Føüüüüüûøúøúúûûùøùùúùøøøøøù÷öõ÷öøõöøö þõôôôôóòóòóõññððïïðîïîíìììììíïîíííîííïîííîîîíîïîïîïñðïîïñññòõóõõ÷ö÷÷÷øøùúúúúúüûý ûüüùV/ûþþÿÿýüýÿýþÿÿ           !)"       !!!&#  !!"#$$$,.('')++-.../33568;ADINSZ_bjuƒ›¥°½Óç9SmŒ¯Ôþ1dްÈÓÚßááÜ×ÕÐÁ©}Mᬂ\;$ÿçÑŹ²§”ކ„~vj^TKS[E540,-+)''&&$$$""""!'PO      ÿÿýýþýþýüýüüüüüúûúúûûúùùøùúúúûûùùøøø÷öøù÷øù÷øúöööøùôóóóóôùòñïñïïïïïñïîîîíìîîîîìîîìíøðîìíìîîîïîîîðóñíîðïðóóòôõôõõö÷øúûúúùùúùúøûüûüþüøùûüþýýþþþþÿÿÿB            !!#"  !!%&$$$$'*+))+++-10//04468:=@EJOTY_gv~‚‘©µÃÕó!<Yt“¸Øý/c«ÃÏ×ÛÜÛÕÊý©ˆX+üÅ“iF,óßËÁ¶­¤š“‹„}uh\RKE=8323.+**&&$$#"#""#!!!:í      ÿÿýÿþüýýù úüüûúûûûùùúùúùùùûúùúøûý÷÷÷÷øøø÷÷øõöõôôôôôôòòòòðññòðïïîîîíîíìííííííìììíììðîîíëìëîïìïðîíîîîîïðïïñòòóôõö÷ø÷øúùûüùøúúúûûùûüÿüüûüþþýýýÿÿþÿ 7        2=      "$%#!#**'()++*,-///25558:?CFIMRY_gqy„• «·ÆÙñ &A\u’¸Úú#S|›´ÂÌÑÑÏÌ»¢ŽoX,Ô¤vQ5 ûêÖĺ¹« ˜”ˆ}zuk[OIA<7234.*)+%%%"!!""  !-Áâ    ÿÿþþþýþýüüúûüúûûûùùúùùúüýûûúøùøûþø÷÷÷÷÷÷÷÷÷öööú÷óõõóòòòòððñðïïñïïíîîîíìííëìíììëìëëíîíìíìììîìùÿòìïîíîîððïðòòóõööööõ÷÷÷øøø÷÷÷ø÷ýûûùûúúúúúúüüýýüýþýþþÿÿÿÿÿþ     0       $*      $# 3.&(&')**+,+1D055:79;@DIKNRY`emw‡˜¦¯¼Ëà÷+C]z–µÓó?h…›«¹¼Á¿®”€QF1ÿÖ®ƒ];"ôãο·³« œ’„}{uwv_MH@:630//*)'&%'" "!          ÿþýýýþþþýýýüýüûûüüùúûýúùúüûúúùùøùûùø÷øø÷÷úú÷õõöõõöõóòòðóóòñððððïððîîîîîíììììíìììììíñíìíììíìííííîîîíîïîðïòòòñòóôôõöõöø÷öøùö÷øþúÿþøùùùúúûûûüýüüüûüþÿþÿÿþÿ       O#              !"!     "#!,)%')/2++,.21936:<=<<@FILPV[`gnu†š¦´¿Íäû-F^x’®Ëè$Gj„Ž”–w^V&&üÖ³kE&ùëÜǼ³®ª œŽ{zvl^RMIA:73/.*)('&&$"!        ÿÿÿþýýýýþþÿþþþüüüüý ýúÿûùúùúúùùùùùøù÷ùø÷øùúûýûýúõöôôóòòóòòòòðñððïïíîïîíííîììíìííííóüîìîííììíïîííííîîïðñðôøóõôôóôõõõ÷÷öõö÷÷ùüýøúüùúúùùúúúûýþýüýÿýýÿÿÿ        !      !#" ! #'!""#(/+'*./,--0201568;<=>BGMPQV\ad‡Â›·´¿Ïäû+E[sŒ£º×ö BduupWK=濨ŽkM2 ùîäÒ¿··¯¨£—‰ywsgZOIF@;72/..**&%$$$"!!    ÿÿÿÿþþþþþýýýüüüýýûúûúúúüþûúùøøøúúüùûùûøúýùùøõõõóóóðòòòñòññððòïîïïîíìíîííîîîììííîííîìëëìîîííîîïððïðñððôóôô÷õôôõõöööö÷÷úúøøùüøùúùüùùúûüüüýýþþþý ÿ     "#("!#"   DR%  '   !!!1)"$#$)0-(13*.0.0/235689<>@DHMPSX]dlœ‘œ²·ÁÎâø &@Wn„—©¾Ùíý6FPKN3# áɰ‡lN5!ñèÚɺµ²±ªÃ—…~xuqcTLFC?852...)('$"$!        ÿÿÿÿÿþÿýýþþþýüýûñùýü ýÿúûûûúûÿûù÷ùúùùûøùúùø÷÷öööõôöõ÷0ïóóòòñòòñòïîîîîîìïðíîíïñïìîìììîíìïïîîîïñòíîîîðððññòóôöõõôõ÷öõ÷ööö÷øø÷úûúùùùùüüÿýûüüûÿýýþÿÿýÿ     ""%)))*((&$# ^w- /!  !!!-"!"#%%'('.1*05...1449;9<?ADIMQUY^fntz‡œ¯ºÃÐÞô  7Pew‡—©ºËÙé! ôؼ¡|cI2!õäÞÒûº²­§¨Â˜xti]QHC?;73/--.(&%$#%        ÿÿÿÿýýþÿýýþýþþýùpþüúþüýüûüúûúúüþüúøúúùøø÷÷øùø÷÷ö÷÷öõö÷öðóôóòñò÷ñññïððñðîïîííîîòðëîííîîííóóïíîïïîîîîîñðïñòòòóôóø÷öõõö÷öö÷ööö÷÷ø÷úùøúùùûúûýþýýýüýþþýþÿÿ     !##%),.2230.,)&"!         "   !   #$%%&')++-0.-.0538;<A@AFJNSW\agmt~ˆš­¹ÆÑáð0F\mxƒ‘ ¬¹Ç×âæìêÝÅ®—€lY@,üêÞØÉĸ¸´¯¦˜¯œ€wodVMGB=9640.,+/''#"!"!       ÿÿÿÿþþÿÿþÿÿþþ÷©+þýýüûüýüüúùúûúüýúùùùùùøù÷øøûú÷ööõõõôõôññõôôôòóðôòòüõñððïîîíìîïîïðîîíîííìííîíííííîïïîîòôñòóôóòôõöõõôôõöõö÷ö÷÷÷÷ùùùøøùûùùúûüýýþýûüýýþÿÿ!  ""%),28;>>=;;3/+)(#     ! ## !  "%'&()*,,++./21456:=BBDGKOSZ`cipv€Šš¬¹ÆÒáîþ(9M_hpy‚œ«¶´¸º´¦—ƒpZI7(þóâÕËÁ½··°«¥‰‚ysj_TLFA=842/-,*)''$!! (&     ÿÿÿÿÿþÿÿþþýûûýüüûûüüþüüüûüÿüûùúùúùøýùøøûùøööôôôôóóóõ÷óõóñôððñò÷óîîîîíììììîîîîíïîîííììììììíîíîîïïïóöñòóóóóôôõôõõõöõõö÷öö÷÷øùùøøùúúùùúúüüüüûûüüþþÿÿÿ*    $)+07<@BIIGGC=850*$!    !!"$"!%'()))+,+-.2;64569;?BDGKOT\bdiqw‹˜ª¹ÇÒÞìø )>NV[^er~‹Žˆ}oZI:,"  øíÜÐļ·´²­¥˜Š~yri`VOIC?<830.+*'(%$#!         ÿÿÿÿÿÿÿþý  ÿýûûüüüüþüýýûÿ ýûûúùùûúùüúøùøøø÷ööõõôôóóóôñôòñóõòñòðïîíííììðòíîïíîíïîîìîíììììîîîîîïïððñóñôòòòóóóõôõöö÷öõõõöõööø÷øøø÷øøøúúùúüüûûüüüýþþþþ   '(%-4:@FKOVVTQLHE@5-($ !    !#%'$#(()+)),--/23<85579FABDGKOT\adjqw€‹˜§¹ÆÑÛçðÿ +9BGHNYfoomed_UF9,"þñåØË¿¸µ³®¬Ž†~tkb[ULFA=974/.,((&$'#"          ÿÿÿÿþþ ýþýüüüýýÿýüüüþýüùúúùùùùøøùø÷øøø÷÷õööõõôòòòñ÷ôñôøóòñðîîïîíììðóíïðíïíîîíùõîíííííîïïîîïïîòñòóòòóôóôôõö÷÷ööööõöö÷÷÷÷øüøþúøùûüüüüûüþþüýþþÿþÿ    "&*1=JJQ\glrle[ZVG;3.'! "!!"! !$&(&$41)++,++/14224579<YGBEHMPT]ceksyŠ˜§·ÃÑØáéõÿ "+38=DLSTOHC;0( üõòîåÙÏÈÁ»·´ª¡ˆ‚ymd_VOGC@<742.+)('$##$        2-ÿÿÿþýÿÿüüþþýüüüüüýýüûüûúúýü ùúúúøø÷ùøùø÷ø÷öööööõõóòóòòüòòòôòñðïîîïðîîííîîïïîîíïïìøôîëëììëîïîîíîïîòòòòòô÷ôôöõõõ÷÷õö÷öö÷÷÷÷÷øøû÷þûùùûüýþüüýýþýþþþÿ    #'/9EN^iyŠ”œ©†zq]NB71*" !""""$!%&(&$72*+++/1,02144458=QFCEINQT^dfls{‰–¤¯¿ÎÖßåìóü $+-34321*$  øóîèàÚÕÚÝËÄÀ¸® ‘‹…rg^XQJGE@;62/,*(%%#$"!         yþÿý ÿÿýþþýýþýþýýüûüýüüüüüûûûõ>øùùùøùùûúúùøù÷öö÷öõôõýÿóòòøòóñððòóñîîïïîïðíïððîîíîîîíîîìíëëìëíííííîïðñòóóóóùôôõõôõööööööø÷÷÷÷ø÷ø÷ö÷øùùúúúüüüûüþÿþýûÿÿ    "$*3@KXm‘¯ÊðéÃ¥~dVJ>3,'!$ ""$  !$%%''')*)*5:-031544779<AEFHKPUY^emry€ˆ”ž³¹ÇÏÛßáçîô÷ú  ûôëäÞØÑÌÅâòþ»´§–‹‡{kaYTNGEC?:410-(&%$$"""       ÿÿÿÿÿþýþýýþüýýþþüûýüüüüúúúúúø÷ùøøùøûùúúøøùúøøôñó÷õõóôóóôòòòñò÷ôîíîðñîíïïïïîîîïíîíîììîìëëìììîòðîïïòòóóóóôóôóôõúú÷õõõ÷÷öö÷÷÷öù÷ö÷÷÷ùùúûúûüüþþýü %ýÿþÿ   "(0:GSe² e¹Ôš1È‹lZMA5-' !%("! !!$"$)+**+*+,/4/13467::;?ADGJLQTZ`elt{~‡’š¶±»ÄÒÚÚÝãåæêïõúþ  õêãÜÔÎÈÇÄ»ÊÒ¸¸µ¬œ””•‰ve\VQLFB@<831.+'&'%$#!!             ÿÿÿÿýýþÿýþÿüüüýüýûùùûûúúùùúøùÿùø÷ùøùúú÷ ÷÷ôõóôöóôóóòññòôóïîíðòíêîíîïïìíîëíëíìììíìëêëìîñïììíòòóóôõôôôôôøþýøõõõ÷÷öö÷÷÷÷ùøøøø÷øùúúúûýÿþýýþ )þþþýÿ  Z$#*3>JXq™äk6™¨i›ñ¢x`RG;0)#  ###%$""%&'*/-++,-15145569;;==ABIKMPTZ_ektz~†Ž”œ¦±ÅÉÑÔ×ÚÜÝßäèêìïóöøùóöðòßÓÌÊÆÁ½¾º´¯«±³«Ÿ“–”†rbXRLIDA>:62/,)&'%$$"!2F         ÿÿÿþýüýýýþýýþýüûüýüûûûûûûúøøûøøúùøùùø÷÷øð[Á[îõõòóóóôøôóòðññòñððïîïííïîîïðíííììêìíëëììêîîëìëììëëóóôôôõõõõõö÷÷ö÷õôõö÷ö÷÷ööø÷ù÷øøøøùüûýþýýþþÿþÿþÿ c) #,4?N^|µÀªâæ·Ö±“jOC8.&!"     "&%&&&(',3/,--.002354789:<=?BFIMORW]cmwu|ƒ‹–œ¦ÇÂÅÌÑÔÙ××ÜÝÞÞàâåãâßÖÕÍÇÁż¹¶³³¯«¯µ°¤š‘™Â˜Š€p`UNIFCA?;72.+)(($#""!  )!             ÿÿþþüüþÿÿÿÿÿýýýýýýüúûüûúùùùûúþøýûùøøùïj˜ê÷öôôóôôööõóñññòòððñññðññïïðïñïíïììíîìëëëêññììëìíìëôóôôôóóôóôóóöø÷õõõö÷öôõõõöö÷öøø÷øøþ ùûýüþÿÿþþÿÿ   "$+3@Q`‚¿È¹å桽ª†eNB6,% &3 ",, (  #'&'(&''(*-.,/312256889<<??@BEGJNQV[`q~qx~…ˆŽ–¦°½ÆËÎÛØÏÒÓÓÑÓÖÔÏÎÉÄû¶µ¾°®­ªª§¢³ØÌ’Œ—ËŸˆ‚r`RJFDBA?<72-,+)(##!"" #3(        ÿÿþÿýþÿÿÿþýþýýþýýýûûüúùûúùùùúúúúûýÿüø÷öõõòóòõö÷õõòóòññóóòòññïîïððòðîïííìííëìíìíììíìììììöôôôôôôôôõôõ÷÷ö÷öõõöùôõöö÷ö÷øøùùøøý ùûýú—ÿÿÿ       #)2@Q`€ªë‹P—…%iÙ—s\RD4,$ x9"%&'%'(*+++-/1443359:9:=?AABCEHKMQUZ_ciqtzƒ„“›¦´»ÄÇÏÏÊÊÈÆÇÆÇÄÀ½·²¯«©§  ¢   £ž¤ËƉ‡„|‹‚‚r^PGCB?>=951.-+()%"!  +S=%           þþÿÿÿþÿþþÿÿþýþýüûüýýýûûûúùùûùù÷øøùø÷öøùøöôöóôõóòòòóðñðððññôóññññïîîîððîíòñîëììêêìììíííìììííôôôõôóóõôõõõôôööõõõõõõöööö÷÷ø÷øúùùúúúûûýù!Åþÿ     !(1=L\vÀÂ¥[°}hVNA1("$E"$&'')1-*,,-011238;;;=@>AAADEILMQUWZ_ejrvy}†‰‘›©´¼ÀÂÅÇľºº¹·±²ª¦¡ ¡Ÿ›™˜˜™•š…€~‚{zvomnfWKEA><;9632.+(&'% &P>        ÿÿþÿýÿþþÿþÿÿýûÿþúûüþýûúüüûúùúøùúøøù÷ööõõôôóôôòòòòôðñññññðïðððòñïïïïîïîí÷öíììíëìíìíîííëëîíïòôóôóòóôõôôóôöøöôõóôôööõõö÷ö÷ø÷÷ùùùùùúûÿ!2ÿÿÿþÿþÿ   !&-7CPcz–·ÚúëÇ­ŒkYKC9-&!!#&'5.**+.../1125::;I„ODC@@DHIKMPVXW]egnruw{€‚‡’¢¶¹¸¹½½¸µ±°¯§›™—˜™˜•“’•˜„ƒ|{{{wtskfa`XOGB=986410/,(&#"!          ÿþÿþÿÿÿÿüûúúùûüüýüýûúûúúúùùøø÷ø÷ööõõôóóòòóôóòòòòóòóòñññïïðïïïðñöíïîîìëííììëìíííííëëìííîòóóõôôôòóòòòòõ÷õôôôôôôôõõù÷÷ùû÷øùùúúùûüüþþýþÿÿÿþþÿ      %+3<FUgp~™”‡wl^NE:0*%! !"#&*)*++../123369:<wÞ|=BCBDGIJPWVTV^gdiotstx|}‡”¤©¯°³´°«§¢˜“’’‘’Ž‘‡…‚{xxwvtttqnjb\YSOKF@9541/,*)'&%#""   /gD         ÿÿÿþýþÿÿÿûùøøøøøùûúÿüúúúùüú÷öúû÷ö÷õôóóóóóôóòñññôðñ÷õñððððïîìíîíîîììíìíìêëìííììëëìëëëôóôõóóôóóóòô÷õôôóóóõöõöõôøøøøùùøùùúûüýýþýýþÿÿýÿ       "*5;@NRWbimjd[TOHA4+&"   ""!%&'&D@,-/23359::=M‘PDCDFFEGJLUYTUY^aemmnrtzxz~‰•šœž¯®—–”Œ‡ˆŠ‹ŠŠ‰„„~vrponmmnopjfa\_RMIEB>830-*11%&%$$!! 0mI          ÿÿÿÿÿÿÿþýÿÿÿüúüûù÷ö÷ùúúýûúøùùúøøùø÷÷÷ööõóóòòòôòñññóõ÷óñï òïððñòðíîïîîîíííííëìîíììëìììíìëëõóòóõóóòöóó÷öõôòóôôõõôöõöõöúú÷ùøøøøûúûüüýüýýÿÿ      %%/68@DJORTQPJFB=7/'" 6   ##!$%%2;2+,.13568:;>@7@EBDFEEIJKNRSTWZ\_ghpmmpqtw{€…ˆˆ …‚‚„†„ƒ‚€~{zwpokigeeghfef`ZXXvNMTG?=81-+$EM!##"!             ÿÿþþúúýýûùøöûüúûúûûù÷ùùøø÷÷ø÷õõôóóôôòññóòñòóóôóòòñîïòñîîîïðîîîðîíîîòðëëìííîîëíêòóóóöóóóöóüòóôóóôôüûõõùõöö÷úúøøùúúúúúúûüþþpýþþK    @1"%(.4:>ABDDC@<71-+& 2  "  ##&(&,+)-/014779;<AAAADFFFFGHJMOQRTVY^bbejmlnqruvwx|€…‹†~~~}~~xvpkhedhe_^_`b_\[VSRQNrÜf<<?7.*'-/$#"!                ÿþþÿþÿÿýúùûüÿýööøüüý ûýùùúùù÷ö÷øøøõôõööôòòòóñòñòðïñòñððòðîîîîîìììëìíìîíîíìììììëëëêííêëéôòòóóóòôóòôôôôóóôôôõ÷öôõ÷ööøøù÷÷øùúùúûüýüýýýþþýÿþ9     $$&+/2379;843/+(%#     "#$%,3,'+-./1467;<>@BBDKHEGGFHJLNPSVWY^_deiljnppqruv{}zzz}yxuvwxxrjdfc`]cbYUTVVURPNLJGHŽˆ‰3982,(%#!!=G              ÿÿÿþþÿÿÿû÷úüÿõö÷úüûùùøøøùù÷öþüööööõõôòóôòôòðñððñññðñðîïïîííîïíìëëìîîíììììììëëëëêéëëëóôññðôòòññòøõñòóóòûòóôõõõùõö÷÷÷÷ùûûù úüþÿüýýýÿÿþÿÿ         #$'),./-+*'%"    !!!(/*&()+-/2788:<>BCDGGFHGGIJLMQWXVY[^cdfmjjmnpqsszzssuvtsplsøvaa_V£†TVTPOPQQKHIGDFGEF<751/-)%#"  Yx             þÿÿüøûþÿû÷÷ùúüüþÿÿùúúøøúûúø÷÷÷÷öõõòôô÷ôóôòòòñôóññïïïíïííëðêìììííëëííììîòòëëíïêëñòñòñóòòñòòòñññòóóøúóôóôõõ"üóõ÷÷÷øùûûúýüûýþÿýþþþÿÿ:þ      $%&&&&&$$"  !  "$%%%(+-.15789<=ABCEFEFFGIJKMQVUWY[^bceiiklnnpqqrsstpmlkhghŠˆbc\YVƒnOPMNLTvyFCCC@=>;87420.,'#!"!              ÿþþÿÿÿýûûüúùùùúûûûüþüûúûûøùýû÷ûû÷÷øøööõóóôøóòóñòóñõóððïïîíõùïíëìïëëñëëìëëëëìììíìêéêëêéóòñññ÷òòññòñòñðñòóõóóóóó÷öþýþõøøøøøúüüûúúþýýýüþýÿ    ()"!##"   %a/!! !#'%$(*,-/2479:;=@BDBPKEFHHILOSUWY]^_bbeghhjkllllmooljgedb`]ZYYWVSVRLIHHGIQOC??<:7766721-+)&# !               ÿÿþýÿþýüüûúúúúúûúüüúùøüúúùúøúùö÷÷øüúõõôôôóóóóñòóòóòïððîîíííìììêëêêìêêëêéèéêêëìêèèèêééññïîïòðððñññòñðñññòòòòóóôôóùøõö÷ööøøøÿúûüûûý ÿþÿþ        /,       &$0úM !!"%$#&(((-.01688:=>A@JGDFDGIJMPSUX[[[\^`abcdffjjijikleda`_\ZYVVTRPMKHDCDDCB?=<;9665432/.+)'$ !              ÿþÿÿþýýüüüûûûûúüúúøøüøúùø÷úùö÷÷øúùõõõö÷òóóóòòòòòñùøðïîíííìëìëêêëéééêëéèèèèêëêçèëèééîîíííîïîïñððññððñññòññòñòòôôõôôôôõö÷÷÷úûùúúûüýþþþÿÿþ        ¹‚&            '!(¿H  !#%''(.7GP3779:;>@>?ABJLGIKMPRUUVXXZZ\]```befddefea_^ZYYYXVTSLLKHECBBAA@?=86534340.,*('$""!!.    (       ÿÿþþüýþýüüüÿþüüúûûùúùùø÷ùø÷øùøöööõö÷ôõôõôóóòòñ÷öòñïïïíîìîîëììééééêêéèüüêëéèèëçèéìííîìíïïïððððòñðñññóñòòðòóôõóôõõõ÷øøøøøúûüûûûûýüýþþÿ        64         ™c"H%! !"%')-6EZ[35889;<>????KMFHHKMOPRSUVWWXY\]``_``_`aa_[e]VVUSQXpWEEECBB@?><:76533920+)(&%&#!!          ÿÿÿÿþþþýýýüüýõüúûúùøùú÷þÿù÷øùùööøþ÷ùöúöõôóóóññòòóòðïïíîîïüììéèèéééèééòñéèççèèçççííîïïíïïððññðñòñññòóòôóôóóõö÷øõõ÷øùøøùøúüýûýüüýýýÿÿþ          #   bZ      /» .€!##$)5<;&5476899<??>>CEDDFIIKLOSQQRTRTVW[\]\]^Z\\[Xbˆ\STRPMN^OCCB@?><:;964431230-(%$+'"!             ÿ $\Z ÿÿþþÿþýýýýýýüüûú Húûúúùöøø÷þ÷÷÷øøööùøúøûöóòóòóòðñññòðïïðîîìôìêéêèééççèéèçèççççèæææíîîîîìîîïðððïððððñòññóóôõóôôöõóôõ÷øøø÷÷øúúûûûûûûüþþþþÿ      !‡}       ,5       !! $*dÕA424767:<;<<>@ABDEEHIKONMNRaXRRTVZYYYVVWXVY^VQQONQNFCBA@?=;97654311..-.)&;,"#              |x;ÿýüûüýýýüûüýù…úûúûúú÷øùø÷÷÷÷öö÷÷øñ÷ù÷öóùóñóóòñððóòîîðîíëêëêêëêèèééêêêêèèèèççææåìîîííìíîîïïïðððïïïñññòóòóóòóóóôôôõö÷÷ø÷øùùúúûûþüþýûúþÿÿ         i_           "!(²ÂN323566899;;<>>ACCCFGHGJJJOd[QQQQSTSSTUWVUWVTSKNNOMIFCA@>=;8763221/-.-+(%?.        –æÝO   üüüýüýýüüýýûú÷úúüûøøøøø÷÷÷öööõõkø÷ôõõüøòõóñðïñòíííîïëìêëîêéèèêêìëììèççççææçåëíîííìïîîðððñðððñõõññòóñòñòóóóõöôõ÷÷ùóìøúúùûúü! ü ýÿ                         #$)S´=20234466799:<=?BBBCEEEEEFHKONNMMOOOPRUWSSTTUWMOMJGHFB?=;;97651//1/,,+)'%*%            /jj þþýýýþýýýûüüúúúúúùýû÷úø÷øø÷÷÷ööõõ)¹ööôôôòýóõóññïîîîîîïïëìêëîëééêééêéêêçèçæææåææêêìíêìïíïïîîîïððòøöïððñðòññòôôõöõõööîkÜ+öúùüûüüüÿÿÿÿ                                       .%!$(.""../12245456778:<????CCBBCDDGHIIHIJKLNOQRPQPUXYVTOLHDA><:988:92/--10,*)'%"'                 ÿýüýþýûûüûüüûûúúùùûúø÷øùø÷ø÷÷÷ööøøù÷öõöõôóñõóòñðñðïïïñóïíìíëìëëêëëêééééççééçæçææçêêêëëíììîíìííîðððñðïïïïðñððñôõôõöõõöízý/õúùüûú÷ùûüÿÿÿþþÿþ                                                  ##%#"'*-..1323344576678:==ABAA@ACBFFGFEGIJKLMNQRU[[\]\XSMFB><;98:<:31/-//-*(&#! "2               þüüýüûüüýüüüúüúýûûúøøùùúùùøùúøùû÷÷ööõ÷ööõôóòñþððððïðòïíìíìíëëêíêëëëëéèèçèèçææåæììëëìììììíîïïíïððïðòñïðððððòóòóõööö÷ø ûùùúûúùûûûüûüþþÿÿÿþÿ                                                "!! %%&*///013112333577:?=>?@?>@@oUCFDDFHJJKLOTX\]^ba`][VNFA><99:85343-.,,)(%"! '             ûUCÿ üýüúûûûüþûúúúýýúùùùùùùøûüúüúùõõôø÷ööôóóïðïïïîíííîðîííëëëìëîíìêèêéèççæääãåìêêêêêëëëììòñîîîîîðððîñïïððòòòóôõö÷ö÷öô÷ùùùúùùüúúúûýþþþÿþ                                             (%*)+,,/////01003446;9:=>>>@>·j>CBBEHJJKPWZ]bdfhgfd_ZUMF@<:9755332/.**)&#!                    ùeZ øw‘(÷ýûûýýüýüüúûüÿüûúúúùûú÷ýþûûÿûùø÷ú÷õôõôñññððððïîíòöðííííîîðïïîêéêéèçæææååæëìéèêêêêêêìíìîîììíïîîïðïðïðòñòòôôööõõöøøøùøøùúúúûùûþýýýýýÿÿ                                          #! !$'()(),--..-.1311233587<<==?:AA@ADHJJLRX^eluz~}zulbZXWMB=;99751.0/*)(%%"                 !"  ÿþýýýýýûüûýÿýýûúüüüüÿûýþþþþþB3ÿüûüú÷÷÷õôóòññððïîïïïïñïïîïñóïîðíêêêêéèçèçæåëùêéééêéêëëëëìììììîîîîðòòðññòòóóóööõö÷ùù÷øúøøúúùûûüýýýþþþþþ                                         !"%&'()*,,,.0005B?/123358<;=>?AAABCGMMKOXam~™¡¥¢ž•„vgi–xDB=>?951.--))'&'"                        ÿþýþþüûûûûûýÿüûûùüüüüûûýÿÿÿüýû÷õõ÷õñïïïîîííîîðìíìíîðîîíëéèéêèççèéåãèéêéëêëêëëìììíìíïïîîïïòòôòñðóóôôóõõö÷øùø÷øüùùúûúüýþýüýÿÿþþþÿþÿ                                                   "!"$%()'((),00.2MO+0/012487;:COC>DFHLMOWarŠ£¹ÇÒÑÌÅ»²£ŽzxÉ—EH@<:961/,*)&%'#                     ÿÿÿÿþýýþûûúúùûÿúüúûûýÿýüüüþÿý4|$òõõùøñïïðïïíìíîðíííïííîîîëìíéêèçééèäãéééçéèçèééééêêëìíìííïï÷ïïððññòóóôôôõõö÷÷ö÷øùùûøùúüýüüüüýþþþÿþþÿÿ                                           !"%&-+(''),,23-.--.01284889<==?GKLNOVat‘«ÈÞðþøïìÜÆ¹®™}bTQLE>::72/-*(&#$$ "                        ÿÿþþþþþýüüûûûýùúøûûüýþýüÿ        ÿ+ÑIî÷öõòòðïñðîííîíìëïïìëììììëûýççæçéèéäåéèèèçééêéçèìíëìííííìïïðïðôññòóóôõõõôõõøù÷÷øøùù÷ùùûúüüüüýýþÿÿþÿþþþþ                                             ' "##&(''&(***,++,,,..293479<>?@CMQOU`p‹®Ðè':6" ñÙǽ±”w`TPKC;853/,)&%#" +                     K”>ÿþÿÿýýýüýýþüûüüüüýýýÿ  ('033)  ûúøõóòóðïððïíîððîîïîíîîíìëëëëéèççèèçææèéèâXèòïåìíðííìíîîïïóòðñðñòóóôôôõôõööø÷øøøøùùùúûüýüüýýþýýþþþÿÿ                                         Œê !!!!!"$%&&'(''())+-....1265BF;;=@FQUSarƒ¨Êê Dq‰‚g?ùÞĺªp\RNH?952/))&"#!  Z                      ,Mí#þþýýüüûüüûûûýýýþÿÿ'<<EObg[J<2<$ ÿÿýúøöõòðñðñîîîóðîííìëëìííëëêëëéèèèæçæçèèéìôêëëêîðïïîííîïïðïñóñïòóòòôôôôõõõõööøøùøøùúüûûûýýýüüýþþþÿÿ                                            Ð !#!"#$$'(('''(*++,.-,/013F;68;?JW[Zbw–»ã0y¶ÝäË–Qð×´ž~bRNJA:610+('"! "#                           +òÚ%ÿÿþþýûýüüýûýûúùüýüÿÿ":S^m†°·›€cItj% þüùôóóññðîîðñíìíìíêééëëëëêëêéèèèæçéææèèèççëêêêéêììììíîîîòíðïòòñòòóôôôôôôõööö÷ù÷øøúûúúûûûýýûýýüþþøþÿþÿÿÿÿ                                        -&0! .#"!"$&&&'%%'()))**+-0/16457:>JX^fo¦ÉíM í.E+â•=á̸¦ŽmVQMB95/-*'$""hn.!                      ÿÿþH”Aÿþþÿÿþýûüüûüýûùýýýþÿÿ"1[}‚´:' ù¼ŠfR0üúþýõôôòñðîïñîëëíììêééëìëêëëêìéçéçææææçççèçèèèéêéêëëëìíííïìêïðïïïñóôôôôóóõöù÷÷÷úö÷øùøùúûúûüúùùûýüüýýþýýÿÿ                                        $.%%" !"$%%%%))'''(+''*,.-/0348;>IZdmy޲Ñî Q·"‹©·kÈSé×Á©’sZOKD93/,''!"# ¥<              "             ýùùùþþ ýüýüûýýýÿÿþÿ $/E¹×5Ä¥ž=겂J3"ýûùõôóóòóññðíîìíììëëëíìëëëëëëéêèêìçäååçççèèççééêëëëëëïîíîííðïïðïðòòðòõôõ÷÷øö÷õöøûùúûúù ÷ùúûþÿüýþþýýÿ                                  -$%!!!""'&%%'('&&(5=&)*+,-/25579>K]nw—¹ÔóR¿NÁ×ÜÂwòÞÅ©’xaSMG=5/+'%"#$!"!                           ýøööøúøþüýýüûþþÿÿüþÿÿþ (7R“Ý%¢' ùƒ/ÚÂc4# þú÷õóóòññððíðíííììêëëìëêéêëèééééçèçäåæççèèéèéêêëììëëìîîîïïòïñðññòñóóøûöõõõøù÷øùö÷øùùúùûû øúûüüüþÿþÿÿþþÿÿÿ   5C                                      +$  !"%"'&%%%#)/+/$'(*5--03347=I\r†˜µÍçE¦FÎÜÛÈ42÷ßÅ¥Œu_OJE<5,(&#"      ,+                      øõ÷ùûú÷ùÿÿþÿÿþýýüýþýüûûþüýÿþþ %8uÇã—nNº_úò1 ýúøöõôòñññðïïîîíììëëëëëëêêêéêëëèçèçäæåååæèèçèéééëììëëíïíîíðîïïïðñóóòòóôôôôöøöøøö÷úùøøøùùúûúúúúùúüþÿýÿÿÿÿ                            & "!"#"#%$(/*"#%&((0*--13989FYl~‰–®Èåý1|ñ–Ì¿Ÿ§@üâÅ¡„mZLHD80+&$$#   XJ     H1Ë»              ýööúÿþúõþý ÿÿýÿÿÿÿþüüýýûüüüüýþýþ$4hÈöãBÇ4QUÎoé‚0 ýù÷õôòòòðñïðîòñíëìêêëëíìêêëìêèééçççäåååãåæçææçèèéëìëëìîíîìíîîîîîðññòòòñòóõøý÷÷÷ø÷øùøøøùù÷ùúúûûúûüüþýþþþþþÿ                   !%"'  !/*#$"(+$$$%'''''+,/2679BSbs…•¨ÂàóU¥afAð™=ûàÀ–vbSHC@6/)&#%! rn%%     ."{y                    þùõ÷üúöøý9 þÿÿýüüûûûüþýþýýÿ#4D~ÚîÿX°éû’3öÏv, ü÷ûûóóóòðñðñïððîììëëëêìíìëëëééëéêææãäääéèäåçæéêèèêììëêìîôîíïîîïðïõõñòññòóô÷ø÷öø÷ôøø÷÷øøø÷øûùøúùùûúüüýþýýýýþS2û                      '$  E<"!!##$$"$%%&&%'),/258=L\i{ŸºØê*e§â÷æ½}3ûÚ²‡hVLE@;2-'$""!!-*                               þùöøû úúýÿ?þþÿþýüûûûûþþÿþÿÿ *9N…ÉÛNjZ%Ò½µ] û÷øùóôóñððððïîïîííìíìêëììëììéêéèèçéèãããéæäåæçééçéêëììëëíñî òððïïõõòòòóôôõõõ÷ö÷ö ú÷øùùùù÷øö)öúúûüúüýýÿÿþýþ þÿ                   72!!""!""##$'&%$&(*-2569DTcsƒ–®ÈÚð -T˜›~SôÈšsZLEA<6.)&%"  #                                   ÿü÷÷úýÿù÷ûþýÿÿÿÿÿÿÿþÿýýüýûûûüýÿÿÿ ,BSqºíò̼Ž{x5  þù÷õôõôóòñðññðñðîîîììììíìììëìëëéêççéèââãäãäæåæççèéêëììììííîòòòñññòóòòóóòñôùøöö÷ úøúúúùùúú÷ öúýûûûûþýþýÿý         ¨?             !#  ""##$&$#%)+.1357=IYfs‰Ÿ¸Êãõ5LQt<ب}aNA<;82+'%$"                                 ÿú÷øöøûø÷ýÿÿþþýýþþþüûûýüþþþÿ -=N`n‰¨‚mXE0 û÷öõôôóòòòñòððððîîíîííììëêëêëêëêéèèçáâáãääååååççèéìììíëììíîíØëñø÷òïññòóññüù÷öö÷û÷÷øøøùúùùù÷øùúüûüüþþýýýÿÿþüüo4         f,         2#'     !#!"#!##+c,'*-03457?NXdv§¼ÍÚéú®AÛ«‚dQB8563/(%$! "+P8                                  +ÿýúöôöùõøþÿþþþþÿýýýþýýúûüüûûüýýþ 1BCKWJ=* ýùõôôóòóôññðñðòððîíîîîîììëêëëêêêêéèçæâåæääååååæççèêëêêìêëêìîýÓ@ðóõðïññòòñìl3óõööööö÷÷øøúùøúûúûùúûúûÿýüýüüþÿþTP e.                   ¯[;I  ""! ! $"1ˆ5('*.13426CPYbuŠ¡¯¿Í×ÜããCô¥€cSD7122/*&$" #!7)                                ÿþûøùþþÿÿÿþýüüþûüþüüýüýþþÿ   þúø÷õõôóô÷òñññòóòñïððîîïíîïìëëêëêééèæçáåèåãääæåäåæçéééééêìëìïJeðîðððñññññï Eòööøö÷öùø÷ùúøùúúúûûûûûúøûüüüüÿþþÿÿ;9                „¹"(  !! !"$#%,1,()+.23108EPV^l™¡ª®±µ±—ˆt`PE91/00,&'-!              &(                 ÿÿþÿýÿýþüýüûüýÿÿÿ    þûø÷÷öõôòóõóóòòóôòñðððïíïööïìëêêéêèéèèèßââãâääçæäæêêèêêëìêìëîðøB ððððñóòññòõóëðö÷÷ùø÷üøøùúúùúúúûüûüû7ýþþÿÿÿÿ                              !! !!###$L=*'))-110019ENQWf|zƒ‡ˆ†zndVLB70.//-(%'+!                                      ÿÿÿÿýüýýþýüúúúûúûýÿÿÿ þüù÷ööôôôóóóôòóñòóñòñðîîîìíöõìììêêééëêééçâäåããåæåæåçðïèêêëïìëìïïðçìïïïïðóóñòóôôõõööù÷öüøùúúûûûüûûûüþü/ýÿþÿÿþÿ                           !""#%J:)'((*+..--07AIKOV[dda^WOJE=5.+,,+(%$#                                  ÿ ÿþÿÿÿüþþýûýüûûûüüûüýýþÿÿÿþýÿÿýýüúøöõöõóóôõôòñòòññòïðïïîîíììëëììíêêëéíêééåßãåããçæåæääæççéêéëîíëììîíîïïïïïðððñóòóôóôõ÷øü÷÷÷úúùúûûúúûûýüþüûüüþþþÿþÿÿÿÿ                     $JM"!  ##"#%$&')%%'(+-,-./3:@DGKQSPLFB=81-**++($#"! (                       /M        ‹‡ ÿÿþþýÿüüüýúúûûûúúûúúüüüýýýýÿþþþûûûûüùøøøõööôóóõöóòððððñðïîîïîíííëëíêéìéêëéêéèæåßàáäâããääãäååæèèèééëêìëëëìîîîïïïïððñòóóòôöõ÷úõ÷ø÷øùùûúúúúûûýþûüüýüýýÿÿþÿÿ                        ;D"#'!!!$!$&&'(%%$'))*+.//047;@DGHD>71-,)()**%#"  ,                         #8   HIÿÿþþþþýÿÿýûûúúûûûùúúúùùûûûûûüüüýýþüúùø÷øøùøöõöõôóññòõöððïñððïïïîíîîìììùýéëêëééèèææßâßâáàâãããääåççèèêêìêìîìëìïóòïïðïðïïòôóóõôôöõööùùøøø  úüûúùûûûúúúüüýþýýÿÿÿÿÿÿÿÿú                   C\&'!"#%'(&#"##%'((*,*,--/02468:60+*)&&&))$"!                                §¨+þ ÿþþþþýüûüüûûüúùþüùùúùúúûüûûûúûúùûùööøùôõôôôóóòñþõððòðòñïïíìíííìë$7çëêéééèçææßßßßáàáááââãååæêèééëêéëêêëðû÷ðîííîîïòòòóôóô÷øööûøøùùùúýýûúúüûûûûûûüýþþþþÿÿþÿ ;                 $$" #!""#&!$&&'%$%$#$**&'**++-0.1/5183,+)'&&%'(# !  +"                           Èæ=ûÿÿÿþþÿÿýþ  üÿüýýûýüúûúúùùúúúúúûúùøúûùùÿýøùùøöõü÷õõóòòóõ÷óùïïñðïñïïíììëëíë%ëêêééèçæçæàßààáááââãäåäåçèééêêëéêììëîíîïïîîïñðïðôóôõõ÷ú÷÷ùøøùùúûüüûûûüýüûûûûüýýþþÿþÿÿý¯0            *     !  !$"&&$%'%"#$%'()()*,->5A-..*('(&##$! $                      %G         EJ þþ_ÿÿÿþÿýûüÿüüÿÿûûûúùùùúúùúùøøøùúøøýýù÷÷÷õôüÿ÷óø÷òóöùúñòôððððîïîîîììììììéçêêééèåççææâÝÞÞäãáááãääääåçèèèééèêêëëììîîííîðññïðóóôôõöù÷÷ùøøùúúúûûûüúûþüûúüýüüýýýÿÿ‚-û        F^     "!!!$%&%'%"!! "$')%&'')@S*$&&(''%#"!!! "                        (J        ýÿþCÿÿþýüüüûûüþþûþûûúûûùùûúùùùúùøøø÷ø÷öõõöþøóõôóö÷ñòòòòðññïïðñïîìììêëëëêèéëêïíææçàÜÝÞßßßááâããääåççææéëèêêéììëííìíïðððïîðòôôôõöõö÷÷øøö÷ùûüýýýüüúûüýþûüüýÿÿÿÿÿ ý4¤      "7      !   ##%*)%"!! !#&'""#$$&'%$#%$##"!                                           ÿÿÿýþÿÿýûûüüýüüúÿùùúúúùøúúúøøöøøöõõõôôôôóôõññôòñòññðïïñîìíííìëëëììêêêã ÅèæçÜÜÜÞÝßààáâããäæææçççèêçéééêëìììííîïïïîîñòóõó÷ùöõö÷ùù ÿûýþÿÿÿþüýüþüýýüýÿþÿÿ3                 !  !!"##)&#"#"! !"#!!"#!"""!!   U%                                     ÿþýÿþþþýþýýùûúûþüüûþüÿÿüúúûûùùùúù÷÷ùýöôôôõôóôóòôõññòñïðððîòùðííëëìëêêéëììëééêîêççæÜÞßßßàààäåâæèäååæçèçéêêêëëìííîîîííïðîòõòõóõôõõö÷øøí|ˆúÿýþüüýþüýýÿÿÿþÿÿÿÿÿ                    !+'$$%! $#!! !  !  !                                      ÿÿÿþþýþýúûûüüûùüûýýûüüüûûøùüüûûùøøøøö÷øùöôôø÷õòóôòòòòôõðððïïò€B)åîîììëëêééêééêéçéóèçåÜÝÖÝàßßßââáäåäæçåçèçéëêêëîõëîîìëêêìîñòòóõóôôõõö÷÷ùýþ'/þýüýüûüüýþþýþÿþþÿÿÿÿÿÿþÿÿÿÿÿ         #      _’%  # #%$#žÁR"&   $#                                   ÿ ÿÿþüúúûüûúùüýýüûûûùúúúùúúùùù÷øø÷ùù÷ö÷öó ÿööõôóññòòóñðïïîð6‹ éïìêìììëéèêèêïêçèñèäåÚãxÝÞßßààááâãäååçæèèíééêìðîìííìêêëéíòñòôõòõöôõõöøùùùûþg=PO þþýûýýüþýþÿþýþÿþÿÿþÿþÿÿÿÿþÿ       "      Lu" "  !!ï5z%4i*%%                                    ÿÿÿþÿÿþýüüüýýüûüýýúüûûøúúúùøøøùùøøùù÷÷ø÷õýù÷÷õóóòóòòóòóõññðöûóîðíììëëêêêëìëëëéèêéèèÛëUØÜÞßàááâáâåæäæææèèèèêêêëìîíìíììììïòðòòòóôôôõöö÷ùüýÿÏ{Zw þýýüüüûüüýüýýýÿýþþýýþýÿÿÿÿÿ                     !$f|@ ! jd]                    2          # '/ ÿÿþþýüþÿýüüüüöùûüúúúûûùùùøùøøùùö÷úùöôõ÷ööõóòóóóòöóñòðíëïîîîììììêéêëêêêëêêéçèçÜßH ÛÝßàáááââãåçæåæççéèéíìêìííìììîñòïîññðõõóóôôõöööúüý aüñ3 ýýüüûüüüýþþþþþÿÿþÿýÿÿÿþÿÿþÿ  $                !$"   !Kž9#                          ^`  t™ÿþüýÿþýýüü/ ùÿùùúüúùùøùøøùú÷÷øøõõööõùøóóòòóòù ðóñîïîîîîîììíìêêëëêêêééêìèôéÚØËÖÞÝÞàçêäââãäææååçæêééììììíííëìðññïîñòñóóôõõõöö÷ùùúüÿ$ ÿþýüüýûüûüýþÿþÿÿþÿÿÿþÿÿÿýþþþÿ lH                   #%"$                       Wa >g     þÿýýþüûDJ öÿþøùúúùøù÷øøøùù÷÷öõõõõõõ÷õóòòñññóúðóïíîîíîîíëëëêêëíëëéèèèèéç ðÚÚÚÛÝÝÞàïöèáââãæçêæçèéééëëëìííìëìðñðñøñòñóòóóôö÷öøùùúýÿÿþûþýýüüÿÿÿý ÿÿÿÿýÿÿÿÿ   S; C>           %        QY               GU        ýýûüüýû #ùúùúùúúùùøùøøøøùú÷÷õôõõõõôóóõõòòòññïñòïîïïîîííìëëëéêëëéèéêèëéèñêÙØÛÛÜÝÞßèìåáâãåäåéåçèëééëëðïíîíëìíïîîòðñòóóòÿö÷öõ÷úûüýþÿýþýÿûûûüþýüüýþÿÿÿþÿÿÿÿ þÿÿþÿþ Á°ü              1!19,$ 2  p                             ÿ ÿÿüýýýüùöùûûúúúùùúúùøøø÷ø÷øøöõöôõõôôôóööóòòòññòñïïñîïîííìêëëíîêëéééêèéèèæèÛÙÛÛÜÝÝÞßßáááãäãäåæçæêêëêêïîìííìììííîîóðñòòòûùõööööùúûýüüüýýýûýûÿûýÿüüüüýþþþþþþýýÿÿÿÿÿþ                   .6" -%   !                  !   ÿþþþüüýüüúúúúùøøúùùùùùùùù÷÷÷÷õ÷ö÷ö÷õóòóôõõôóòòòññðððïðîîðîìëîîëîðíêêêééèççæçæÞÛÙÚÛÜÞÞÞßßßßááãåäæææèéêééìëîõòìììììïðòððòòññòôôô÷÷÷ùùùúûûúúúùüûþøûüûûûûøúüüüýüüüýÿþÿÿÿÿÿÿÿýÿ                   ! "                      0    ÿÿýüýýüûûúùúûúùúüûùúúùøü÷öø÷öö÷øöøúõòóóõõóòóóññðîðïîïîíïíììïîëëììéêêéèèæçåæåÙÚØÙÚÛÞÝÞßÞÞàááäåãåæçççééêëêîôñìííííðñðñòòññòóôôôö÷÷øüýúúúúùøùûüûùúúûûüù(!øüüüüüýþþýÿþþÿÿÿÿ                   *(&                                   ÿÿÿýÿüüûüûûúúýûúøúüúùúùøûÿ÷ö÷öõõööõôú÷óôôôóòñòòñððððïîîîíììììëëêêêééêêêèèæååäåÙØØÚÙÛÛÛÝÝÞßàááââãäååççèêëêêêëííìíîïïðïðñññòñòóõöõõ÷øûûøøøùùøùûûøùüúùùúú ùûûüüüûýþûýýþÿþþþþþþÿÿþ                !                                    ÿÿÿþýûýûüüúþûøøøùúøùø÷÷÷ö÷öõõõõõõóö÷ôýûóóñòòðñðïòððïîîíëììëëìëéêêèèêéèççæåååÛ×ÖÙØâãÜÛÜÞÞÞàãàáâáääçççéééêêêíììíîïîîïïðññóñòòõõôõöøø÷øùûúøøúúúùôùúùùúûøùûúûüüûûýþýþýþÿþÿÿÿþ               /pc                            ÿþÿüûûüüýûúùùùøøøøøø÷÷ö÷÷ööõôõóõóõöóñòññòñòñðñïïïîííìëìëëìëêêíïèééççæçæçäÔÖÖØ×ëíÝÚÜÝÝÞßãàáááããæåæèèèêêêëììíîïïïðððñðòòóóóõöö÷÷÷÷øùúúø÷÷ùùø úøøúüûùúûúúúúûüýýüýýý üýÿþüŠ·5                   "$4…x               ÿÿÿþÿÿþýüûûüýÿüúùúùøøø÷÷ùú÷÷÷ô÷õõôôóôóó÷õ÷÷ñðññòòññïðïîïíîíììëêëëëëæýMRäìèææååæãÓÕÕ֨רÚÛÛÝÞßÞÞßàáãããääåçççèèèéëëëìííîïðïñññòóóóüùõö÷÷öõö÷øøöö÷÷÷ø÷÷ùûûùùûúúúúúûþýþýýýý ÿ <Q             N>_ÄY                   ÿÿÿÿÿÿüüþûýýüüüùüúøøùøö÷÷÷÷øöõööôõôóôõôýñòñðñòðñððððïîðîîîííììëêëìæwŒâíéææåäåãÑÔÕÖ×רÙßâÝÝÞßàßÞààâäãäãåææçççéêêëìòöíîïðñññóòòóüøóôööõôõ÷öööõõõùöøøùùøùøøúùùúúùúüÿûþýüþø“ùýÿÿ               :1ÙÀ                        )wSÿþýþüúýýýüúûûúøúûúøøø÷÷ûø÷ööõõôóô÷÷öóòòóóñññððððïîððîîîîíîîìéìîêêæäéççæææäååÎÒÔÕ×××ÖìóÙÚÚÜÞßßßßáäãåäååæèèçéëëëíøííðïðñðòñòòòóôõööõôö÷õõöõöõûøøùùøøùøøùùùùúúúûÿýÿýýþ´iûþÿ                 €)z                       :' ÿýüýüûûûþüûüüø÷øøøø÷øøøööööôóôóôôö÷õòòòòòòòñðððîïíîîííííìììëéééèêêéèæçæåæäãäÌÒÔÕÚÙ×ÙÙÚÛÛÛÝÞààààâããåæçéèççèêëíííììïîðïòòñóóòóõõôôõ÷÷õöö÷öøø÷÷ôøùøøøøøùùùùùùùûûûùüÿþýýýðöÿÿÿ                                       ø  ! ÿ   ÿýýýýýûûúûüüûûúüúùùøø÷ø÷ýõõõõõõõôóô÷õòòóööññññññðððíîîîíìíììëééèéêééèçççæååäããÈÏÓÔÖÖÖÖØÙÙÚÛÜÞÝÞßàáââçèêðêåæçèêíîëëíïðïïðïïñòñóôóòóôõõôõõöõ÷ö÷÷÷÷øø÷÷ööùûùøùøùûüûþùúûüüüüþþÿÿÿ!                "! !"                  >´           ÿþýýûúûûüûûüûûûúùùúûù÷÷öøøû÷õûô÷ôòôôôôôóòñòòñððððîíîîíìíìíìêêéèêëéèçéçäåæåäããÆÍÑÓÕÖ×ÙØ×ØØÚÛÝÞÞßàßáâââääçççèçèëëêêììïîïôðïðñòòóóòôöõôôôöõõõô÷ö÷øø÷÷÷÷ö÷úúùùùùúúøúúüüüûüýüþÿÿþþÿÿÿÿÿ                   ',"(*'# )0          2'          ka3  F%U*   þþþýüüüúûüúúúùùúøöø÷÷÷øöøþöõûøôùõóô÷ùûúõóñðððððððíïíïíìíìëëëëéèêêééæèçæåæääããÁËÐÓÔÕÖÖÖÙÙÚÚÚÛÝÞÞààáàãããåæèéééêêêêëííìïñðññðñòññòóõõôôôõôôôôõøöö÷÷ø÷÷÷÷øùúøùúöùúùûþûûüüüüüüýÿþÿþÿÿ ÿþþþýþ               '8GJA,PC          kQ          9¸'  IK¨5    ÿÿýüýÿüûýúúùùõõ÷ùøöõöööø÷õùöôôôóõóóòíI °ñòóðïðïïííìïòïëëêéêëêèçéêí÷åååääåâãââ¿ÈÏÒÓÕÕÕÖÚÜÚÚÛÝÝßßàââááäãçèèéìíééëíìëíïïððñðòôôóóóóøùôôôôõõöõ÷õöõ÷øøøø÷øøùùøù(øûúúþúüûüýüûûýýýýþþýÿÿþÿ0]þÿÿþþþýÿ            !/’|]”/                         ûü  %tš#  ÿþþÿýüüûúûõZU õ÷÷÷öö÷÷÷ööõöõòöòóóòíLnõñòññïððîíîîòðíììëêëììéèéééçåææååæäãââºÁÊÐÒÓÓÓÕÖרÙÙÚÛÛÜàáààáâããääæèèêíêëêëììíìîïòññòóóòóôóòòóô÷ôõóóõõööõö÷ø÷÷øøøöó+sõüøúýùùúúûûüüûýÿýüýüüÿÿ:}%þÿÿýþþþÿ           !3ŠOÐ*                  ]     ÿÿþÿýûþûûùû÷;Iôö÷÷öö÷öõõöööõóøóòòòóA/öòòññðïïïîíìíììêêêêëëéèèéëîêæåæäãåâäâ⵿ÈÎÑÓÔÓÔØØÖåÙÜÛÝßààáàáãääåçèèêìêëììììííîîöðñóôóóóóóôõõôõóóóõõüõõ÷÷øø÷÷ùú÷öôúýøÿüûùúúûûûûüþþüý * ýþþýþÿ          4¾«s“-                   ,Ø    ÿÿþþÿüúúúÿ÷÷÷÷öõõööôõôôôóôõóòòóñêîóñððïïïïïîííìíïìëêëëéêìêççèèçæååãââãâá²½ÆÌÐÑØØÑÝöóÙåÙÚÚÞÝÞàßâãããääæçæîõôÿëíëííïíîððïòòóôõõóóôôóòòòòôôô÷÷õôõõõöö÷ø÷ö÷ùûüùøúûù÷øúúùúüüûüüû þýþÿÿÿýýþýþ       ,L}j>'+                                )     !#"  ÿÿþûúúù÷õøùø÷ùøö÷öõõôóóóóóôôòù÷ñññòòðïïîïïïîíííííììêêêèèêêçåææåääåããááá᮹ÂÉÏÐÓÔÒÖàá×ÙÙÚÛÞÜÝßßáääããåææçéëñþêëíïðîíîóòñöùùü÷ôõôóóôóóóóôóõóõôôõöö÷ùùøøùýþúüøùüøøùúùùúýýûüüûþÿýüýýþþþýýþÿÿÿÿ          $""                                   $)#'.23/(" ÿÿÿþýþýûúúùùôõ÷ø÷÷ùøö÷õôôôôôôòóòòñúøñððððððïîîîïííìíìììêêêèçèéíîåååååãåââààêæªµ¿ÆËÏÐÑÒÒÓÕ××ÙÚÛÜÜÜßààâãããäèéçèéêòéêìîíìíïðñïðò#0îòòòôòóóóôóóôüöóôõöööøú÷÷øøøúûûýÿùùúûùøùúúûûüüüûýýþÿÿÿþþþþÿÿÿþÿ                            - .7BPTI=5( ÿþÿþýüýüûùøö õ÷õö÷öõôôóóóóóôòóñññóòððïîîïïîïñîííëêëìëëêêêèèèèèçäååããããâçâáäâÒ¼ºÃÉÎÐÐÑÒÔÕÕרÛÜÚÛÝÞßßßáääãçèçèèéëîêêéìëìíîîîïðõùðññõþóòóòòñóôôôóóôõôõ÷÷ö÷øû÷÷ùøúúùüøùùùüûüýûûúûýþþýûýþÿþÿþþÿ               Hê                   l“7  )'8W¯¾›pL1   üøþýüýüüùøöõ÷ö÷ùøõõõõôôòòòóôòðñïïððïïîîîîïðîîíìììììëëëééêêéæåäæåäãåãâäââãâŶ·ÀÇÍÏÐÒÓÖÙÕÖÙÝÚÛÛÝÞÞßààâããäåææèèèèèéìëëëìììîîïòýýñññïýôòòðñòóôóóóôõõöö÷ø÷õöö÷÷øûùüúøùùøúýüúüýüúûüýúüüýüýýÿ$          &+0(     -ƒ                 úzŽþ$=%.Hƒ ºV¿[3#  v„ýýýüüúúùúö÷ø÷÷÷ø÷ööõõôôóòòòóóñðïîðñðïîîðîíìíîëìíìëëêêéëëëëçéïêääãääââààáá✪µ¾ÄÊÍÐÒÒÕÖÑÙÙÛÙÛÛÜßëâÞàèæâãäåççèêèèêìëëëìíîïïîïíîñññðôûòòòññóóòþõòôöõõõøú÷÷÷÷øùùúøüøøùüúúúÿûûûûûûþûüüýüýýþÿÿÿ          *«rÒ?                             Jn4e½"4X¹¸¡Çj:& û+ê"ÿþüûûûûúøøùù÷ø÷ööôööóôöóôòòñòññðîîððïïîîïîîíìíëìììëêîìéééééåéòíãäââââãàààáá•¢±»ÂÈÌÐÏÏÎðq‘ÓרÚÚÛÞçáÞàåäáãåæçççèèîìêìéëìíîîîîîîïððòñðïñòñòòòñòöôóóóûûõööö÷ööøøø÷÷ýúøùùùúûûüýûùûûúýûüûýüüûýþ                 2#’YJ  $W                                'K&:`ÙñÀÙ1p='  8dþüüûûüúùøûù÷÷õõö÷ú÷õô÷òóòñóóðððïððððîîîîíîîíìíìììëëîìéçèèæååééäãâãâãâáàßááÇɵ¶ÀÆÌÏÐÐÎòwŠÓØ×ÙÙÚÜÜÞÞßààâãäåååææèñëêìêêëëìîíîîîîðñðïðððññòùñïóòóóóô÷öööôõöõõöö÷ö÷ûúöøùøùúúüüûúúúûüúúüûûùýþþÿÿÿÿÿÿ                       .ăÒ9''   @Ô                                               #2Uª…gŸÊ^7% üýûûûýûúúúûù÷üûõöùü÷÷óóóòòñóóñðððñðððïîïðîíîîíîíìíëëêêéçèèçæåääåäããããâàààáàûð·³¾ÅËÏÑÑÓÔÔÌ×ØØØÙÛÛÜÝÞßÝÜáãåèèèææéïéèêéêëííííïðïññññððññòòó÷òñøóòôô÷÷öö÷÷÷öööø÷÷÷øúúúùúùúúûúúûúúüýüúûüüûüÿÿþ    ;         ".       $26+   *                                           -F~ÓîqÍxG,   ÿýûüûüúùùùøøö ôööõõõôóóñòñòññððïðñðïïïïïîíìììïíììëêêéèéèèèæåããäããââçããàáàßµµª³¿ÅÊÏÑÑÒÓÔÕÖרÛÚÛÜÛÝÞßöðáåçéèææíîêýëéëíîîíîððîñòðñòññòòòóóôóöúõööõõöö÷÷öõ÷ø÷ùøøúüûûùùúûúúúùúûúøúüûûüþÿû.‚Yø      #"                           $                                           &6H`’„_G5&   ÿþýüûúúùøùøø÷÷õóõôóôõóñòòòðòðñðïïïòñîîîîìíîììëîîëëêêéèèèççèæãâãããââáæâçààßߊ”¢¯¼ÄÈÎÒÒÑÓÓÔÕÖØÛÚÙÚÛÝÞÙ:pÜãäääéðìëéÿëêìíííìíïîíïñðïññðòðòüýôöôÿòõöôôõôõöõõõööùö÷øýûüüùøøùøúûûûüùùùúüúúüüýÿÿÿÿ þ                                           ,                                           &(,6?<6+$ ÿüýûüùúù÷úøûùö÷÷ööööôòôóñòñïððñóñïðïñðíìíîìëíììëëîëëêêéççæåæçåââããâááàâàãßÞß߈‘ª¶ÀÇÌÐÒÐÑÑÓÔÕ×ÖÙØÙÚÚÜ×4dÜâäãåîùçéèæèêëìíííííðñïïïîïïðñðñûûñôòþúóóôôôõõõööõõöööö÷øûú÷øúùùøøúúúúûùùùûûûúüûüþþýþÿüý!¡Aü                                                                                        "   #&.% ÿþüüûüúúù÷øøûüùøù÷õöõóòóòñóòññðîòñïïîîîìììíòñëëëìêêëêéèèèççæææäââãããáààáßßÞÞÝÞ…™§³½ÆÊÑÖÐÒÒÓÔÔÕÕ×ÙØÙÚÛàÜØÝááãåæëñèèçéèëêëííîîìðòîïðïïîïïïïòóððððóóóóôôõõö÷õõö÷÷öúøøüø÷øøùùøùúùùùùøùøùþüûûûüþýýþÿ%ÈOú                                            %%                                                 ÿüþûûüûøøøøùüùöúùôööôòòñòóññïðïïðïïîîíìííïüêëîëëëëêèçèéçæçæåæåãããããáâáàààÞÞÞ‚Š” ®ºÃÈÓÜÐÐÑÒÔÕÔ×ÖרÙÙÛßâáßàáäæçäßçæçééêêêíïïîìíííïòñðïðïïïðùòðïðñòóóôôôôõ÷õöö÷öúû÷÷û÷÷÷÷øøö÷ùùùøø÷øøùûûýùûýþýþþþÿþ )                    "                                                                          ÿþþüûûûûùùùùøùù÷öúùõööõôóòñöòñòðïïîîïðïîííîíöììîëêëëêéèçèçææååææãããâáááááááßßß~…›©µÀÉÍÍÐÐÑÐÓÓÕÛ×ÖØÙÙÚÜÝÛÞâââäåïåææéééêëïòñïíìîîîðñðïðñïððýóôññññòòôõôôôõö÷õööúúøùýù÷øøòó÷÷÷øùùùùøøúøùüûüÿÿÿþþþÿÿÿüÿ                    B                     Q,                                                         þýúûüûûùøøøùøøùùøöö÷ööö÷õñòïððòïîîîííðñïííííîìëëíëééêéèççæçæääåäãããââáàßÜÕßàÞÞÝz‹˜¥±¾ÈÍÎÏÏÑÑÒÔÖÕ××××ÙÚÛßêéÞàâââNäèæéèëêëëëííííîîïïïïïïñðïñ÷òöóññññòôôóôôôõ÷öõööø÷ùýùöøô)*þõööøùúøøùúù þýþþþþý ÿÿÿÿÿ                                       vT                                       ÿÿ       ÿÿýúûùþúúûøøøøõö÷öôôöõóõùôòôîñòûñîîîîííîîîïðííðìëìêééèèæçæåååäæçääãáâââáä&ëÞÞÝÝt}‡’ž¬¹ÄÊÍÍÎÐÒÒÓÔÔÜØ××ØÙØì+×àâáäû äååçëêèééëêéëíííîîîîïïîïîïïñðïñññôöôññóôóôõõôõõöõöù÷ö÷ñ11þôö÷ö÷÷÷÷øøú ýüþüýýþþÿÿþþþÿ                                     &     $#                                      ýûûþ úûûúøø÷q?óöõõöõõôõóóôñõòöñïïþöííîîîïîíìííìîíêéèéèçèçæåæçåäåæâáàáâõb&×ÝÝÝoyƒ‹ž±·¾ÈÊËÎÏÐÑÐÒÕÓÔÖרÙÙâõíÛÞàÞê>Šáæææõêçèéêêêëííîñïìíííîíïïïòðïððñøøñûþòóóóóôôõöõõõøøø÷÷óóøøöøö÷úø÷ùøùúúûüüþýþÿþþÿÿÿ                                                      !n                                   ÿÿÿþþýûþ ùùúùù÷÷²ñóóõõôóôóññòðñòðññíîíîíííìïõïëëëêëëéèèèèéîöëãããããäâáâáàáù˜ÚÝÞÝmu~‰—¦°¿ÌËÌÍÏÎÐÒÒÓÕÕÔÖØØØÚÜÝÝÞßàâçæåäçæééèéêëêìíííìííìíííïîîïïíïñðððòñíñôõ÷ôôôôõôôö÷ùøø÷ööùù÷÷÷úøùúùúûúûüýýýþÿÿÿÿÿÿÿÿÿ                                                            <                            ÿÿÿÿþýýüüÿûÿ÷øúø÷ø÷ûE+öõôôõóòóñòðððððïîîëìììîíìíîðïëêìêêèçççæææäíêãâââââãæáâàÞààÝßÞÝÝÝjs}…œ©¸ÃÉËËÍÎÐÏÐÔÓÕÕÕרÙÙÛÝÝÝÞàáäääåæååçéççêêéêëëëíîííïïðïììï÷òîñðïïòóñðòóøÿòóôóõùý÷õ÷÷ööö÷÷÷÷÷÷ùýøøøúùûúúüüüüüüý"/ ÿÿÿýÿÿþ 18+3!                                        )                                      þÿÿÿþýüúÿ úúùøûù÷øø÷îòø÷õö÷óñòòñññïðïïïîìíìììëëëìíííêëììèéèçççæææçåââââáâãáààÞÞÞÝßÞÝÜÝgu{~ˆ”¢°½ÆÉÊËÍÎÎÏÒÑÔÓ××ÖØÙÚÚÛÜÜàäâáâãæåäåçëéèèéëëëëìíììíóííìíôøëõòíïõöòññòôõòóóôôúóööõõõö÷÷öööööøø÷ùùúøùúûûüûûü%8þþþýÿÿÿÿÿþ ,.# WB                                                                             ÿÿÿÿÿÿÿÿÿÿýþÿûüûúù÷÷÷øöö÷öõõööóòòóòóððïñððîîîííííìëëììííëììêêéèççæçåìîåâââââàááàÞÝÝÜÞÞÝÝÝdmu|„ª¸ÂÉÏÍÌÐÓÒÒÒÓÔ×ÖÖØÙÚÚÚÜÞàáäëâãäãåã Q áïéëììììîíìíìíîðñîíîîðòðîïòññòóóóõóõöóøöõõõ÷÷öö÷ø÷øøùøøøùûúúûýüüüýü÷ûþýþÿþýþþÿüýÿ   (#                                                                                 þÿþýÿþþÿÿýüýûúüüùùö÷÷öõööõôõõôóóòóóóñðñðïïîíîíííìììëììììëëêèéêèçæåäåæåãæëæààßÞàáÝÞÛÜÜÜæßÛ]gpx€Š—¥²¾ÇÌÊËÏÏÐÏÐÑÔÔÓÕרÙÙÛÝÜÝÞàäááãâääí÷ìßFDõèëëëìììíìíëëîïîííîîîïðïðïññòóóóóóõòôòó÷öõõõööõõõöøùù÷÷÷ùùûûûþýúúüýþýüüýÿþþþþþýþ þÿ                                                                  #'    þ$þüümœ(ÿÿÿÿþþýýýþýûüýùúùùøùùø÷ööõôôôôôóóóòòñññðñïíïïìííììëëìëêêêêëêéèééææçæååääãåëèàßßÞÞÝßÞÜÞÜÜÝÛÚXakr{„ž­¹ÃÉÊËÌÍÎÏÓÒÓÔÔÕÕ×ÙÚÛÜÝÝÞáâàãâäååææççóóëëëëëëëììíïíëíîíëîïîíðððððððñóóòôòôòóóò÷÷õõööööö÷÷øøøø÷÷ùùÿûûûúúúûüüýþ ýÿþþÿýþýB÷ÿÿÿþ                                                                 -  ÿþÿÿÿ,þþÿø¸Cüþþÿÿÿÿþÿýýüüüýýýýüúûøùù÷ùù÷õöõôôôóóóóóòñòðððïðíïîììîíëëëìííêêêìëéïèéçææææææåääããáßßÞÝÞßÞÞÝÜÜÚÛÚS[dmv‰—¥³ÁÆÈÊÊÍÍÏÐÐÒÓÓÓÔ×ÙÙÙÚÛÜÝààßàáâãããæççææèêëëëêììëëëëííìììîîíîïííîðñðñòòóõòöòóóóôôóõöõõõôõö÷÷õõöøøøüúûûúùúûüüý#5ûýüþÿþþÿþþýªP÷ÿÿÿÿÿþÿ "                                                         3$              ÿÿ4w ýÿÿ*þÿÿþþÿÿÿþüûûýþüüúúûúúù÷÷ú÷ôõõôó÷÷òóóñññòñïïíðïííííììëëììììëëëêêéëçççååææåäããâáâààÞÞÝÝÝÝÝÜßèÞÚÙPW_ir|†‘«ºÂÈÊÊÌÍÐÛÔÑÒÓÔÕØÚÙÙÚÛÝÝÞßßßããããåææææçèðñéëëííìííîïîìíííõóïîïïðñðïðòòôõóõôóòñöõôôôöø÷öööööö÷÷öùùúùüûûûúúûýýûûýýÿýþþýþ÷üÿýýþýÿ                                                         þÿÿþÿþþ ÿýÿÿÿÿÿþÿþÿÿÿþüûüûþûûûùûúú÷øöø÷õôõôôúûôóòññóñðððòðïîíííìëëììëëììêëêéèèêèèçéèæåääääääàââÞÞßÜÜÜÜÜäÞÚÚLS[dmw€‰•£±½ÅÉÉËÌÏÖÓÐÐÒÓÔרØÙÚÛÜÜÞÞÞßááâããäóïèçèêëêêëëííîííìëíììòüøðîîîïðððïðñôññóóñññ÷õôóòôõôööööõ÷ø÷öø÷ùùúûúúûúúûûùûýþýýüýþýþÿÿÿÿýüüþýþ                          5                                    ÿþÿÿÿÿÿÿÿýÿÿþüûûþþýþþÿþûúúùùø÷÷÷÷õööôõõö÷óððòòòòïóùúðíííìììëëëëêêëêêíèèèèêèèèéæååäääãããááâÞÞßÝÝÝÜÛÜÛÚÚFNW_iqz„ª·ÁÈÉÊÌÎÎÑÑÒÒÓÕרØÙÜÝÝÜÝÝàààââãäæëêèèééééêëëíìëìîíííîïòòðïïîðòòñóññòòòóóôòòôö÷÷õõöõö÷ùûüøþøøøøúúùþýüûüüûúûüþþÿýþÿþþþüþÿÿþ                           )                                 ÿþÿÿÿþÿþý ÿÿþþÿÿüüþüüýýýýüúüüúüÿüûþùú÷÷÷õööøøõö÷öõóòñôüùññðððòø÷ïíìíìììììêëëêêêêïèçèéççççæäããããâáááßßÞÝÜÝÜÜÝÜÛÛÚÚÚ?JS[cluŠ•£±¿ÉÉÉËÌÍÎÏÑÒÒÔÖØØØÚÜÝÝÜÜßÞâáàâçæääæèèèèéëêëëíêêëîîîîíîííîîîïïîðòñðñòòøòòòòòóöõòòóóõõôôôú÷÷÷÷øùùúúúûúúúùùüüýýþýÿþýýýþþýþÿþþÿÿ                                             ÿÿþÿÿÿþþÿþþþþÿÿþÿÿþþýüüýûûûüûüýüüûúúùúù÷÷øøøøöõ÷ùùõôôöôòóñùþïððïðððîîìììííëëìëëìêêêêêèçèéçææååäãâãâáàáàÞÞÜÝÛÜÚÚÛÝÚÚØ×Ø8GSX]gpyƒŽš®ÛÞÆÈÊËÌÌÍÏÑÓÔÔÖ×רÚÛÜÛÜÝÞâàßáääååæèççéíìèëêìëëêëììííìíííñòîìíðóñðñññóñòòñòòôôóòòôôóý öþ#÷øùû÷ùùõ- ÿúûúúûûûûüýüýþþýþüýÿþÿþÿÿÿÿþþÿÿ             #                         ÿþÿÿþýþþýþþýüüþþþþÿÿÿÿþüþþûýúûúüûúúúûûúûûùøø÷øö÷÷øööõö÷ôóóóòòòñôøòðïðïïðñîîíìëííìëëëëêééêêçççççæææååäãâââàààßÞÜÜÝÜÜÜÚÚÛØÚØ××1ANTYclt}ˆ“¥Õ×ÎËÉÊËÍÎÏÐÒÓÓÔÕרÚÚÚÚÜÝÞÞßàáâääååææçèëêééèêêëðïêìíìëíïððííîòùòðñññûóñòòòôóòòòõöô÷ùöüüøýøø÷øøùÿüüûúúúúúûüüüüýþþþýþÿýýþüûþÿþþþÿþþÿ            )                       ÿUÓhúÿÿÿþþÿüýþýÿýýþýýþýüýþþýüüüüüýýüüúûüúúúúúúúûùùø÷ùù÷÷÷÷÷ôóóòòù÷òòòñððñóïðïîïîííííìììíìëëëêèèééèæææææçæäääâááâàßßßßÞÝÜÜÚÛÚÚØ×Ø×××'5BNW^gnx‚˜£°ÌÌÈÈËÍÏÏÐÑÓÔÓÕÖØÚØÚÛÜÞßÞàáâãåäåååææççéééêêêï¯çììñîíîòôèãïðóññððñ÷ùòñòòïóôòóóôôóôôõ÷ô÷ùöööøøýúùýýûûûúûüüûûüýüýýþÿýþýýüýþþÿÿÿÿÿÿÿÿ 4  )                                >³^ÿÿ&' þþÿÿÿþþýþÿþþþýüýýüüüüýþüýþüüýýüüþüüüýüüûúùùùúúøùûùøöööøõõóôõõòñúùòñòñðïðòïïîîííìííìììëìëêêêêèçèèæææææææäãâãâààáßÝÝÞÞÝÜÚÛÙØÙØ×Ø×ÕÖ× .;JSXais}‡‘ ¯¸ÃÈÈËÌÍÎÎãåÕÓÔÖØØØÙÛÝÝÞÞâáâáããäååææççèèêìëêîlýêíìòñîíîéTzëîîððððñòññòñõ ÿòòôôôô÷úõôôõôöõõöøøúùÿúúûúùûýüúùûûýýýüüüüýýýýýþþþþþýÿÿÿÿ6X)                      'þ-Qûþþÿÿþþÿÿþþþþýýýþýüýþýýýüûüýüýüúüüüüûüüûúúúùøøøûúøú÷õöõôóô÷û÷õóòòóóòñðððñïñíîîîìîìíëëëìëééééçççææçæçååääãááãâááßÝÝÝÝÛÚÚÚØ×ØØÖ×ÖÕÕ×&4AKS\dmwŒš¬²½ÆËÌËËÍÌéêÒÒÔÕÖÖרÛÜÜÜÞáàààááâäåæççèéëìêëééèÜéìííîîíìíèFlìîîïîðïðððññðôýóòòóôö÷÷ôóõóõõõõõõøø÷ûüúùùùøúûùúøøøøûüüýûûüýüýþþþþýüýÿþÿÿÿÿÿ                  ÿ  ýýþýýþÿýûüüýýüûüüûûüþþýýýýýþýüúûûûúøúúüúùùùù÷öøø÷÷÷öøöôõòóòóóòññðñòññðñòïïîíîïííìíëêëëëíîêèçççæéæççäãããâááäåááàÜÜÜÜÚÙÚØÙ×ÖÖÕÔÕÖÕÖ,=INV_gp|†žª¶ÀÎÌÉÊËÍÍÎÑÒÔÕÖÖØØÚÚÛÛÝÞÞÞßááâãåèéèçêìëèéééêéêìììëëïñïîõøïíîîîñîïðððððñóõõòòñòõöõóôõõóõõõõööö÷úúùùù÷÷ùúøö÷÷øùùúõûüüüüýýþÿýûüýþýþýÿÿÿ                þþÿþýüþþþþþüüýÿÿüüüüüþýýýýýýýþüûûúøûûüüúùûúøø÷úÿúöö÷÷õõõóóöõòòññóóòñòòòððîïïïíìíìëëìëêóôèèèææçêæçæåãäãâáàãçãßßßÝÛÚÚÙÛØØ××ÕÕÔÕÖÕÓ$2@HQYajt~ˆ”¢¯ºÄÇÎÏÌÌÏÒÒÑÓÔÕÖ×ÙÚÚÚÛÜÝÝßßàáããæêêèçèçééééêêéêíìëìëõöîííííîïïîñïîðððñññðôõóñûÿòôôóôö÷õõõöõööö÷ùúùùùùùúúøøúúùùøx÷ýüüýýýúûüþþþÿþÿ                                   ÿþþþþýýüüüÿýüýüûûÿýýûüüüþûüûüüûúùùøøùùø÷÷÷ø÷ö÷ùû÷õöôõóóóóòøúöóññðñòñðïïðîîîíïìëìëêêêêêéééèèçæææåæåäãäâááÞâæàÜÞÞÝÚÙÚÚÝ××ÖÖÔÖÖÕÔÓÍ ,9DLU]foyŽ™§´ÀÅÜÜÐÎÑÖÔÐÒÔÔÖØÙÚÚÚÚÝÜßàáááââäæææçççêééçêèèêëëìììñðìíîîíîðïîðóþòïïðññðôôòñüòôñòôõõõôõ÷öööö÷ùùùùùùùùø÷øúûúøø‰÷üüüüûüûþÿýþþÿþüÿÿþ       ÿÿþþþýþÿÿýþüüýüûúûûýÿýûüûûûúûüûüûüúúùùùúøøøöõõö÷÷÷÷øöõõõõôôóññòõõõóóñïðïîîïíîïïëøðíìêêêéèéééèèçèèæçåååäãâãâàáíçêîáÛÛÚÙÚÚÚÞ×ÖÕÕÔÖÙÕÓÐÈ"0=GNW`js{…‘Ÿ«¸ÂÇÉÌÌÍÏÏÐÑÒÔרÙÙÛÙÜÜÛÞÞãâàááãäååæçèéçççèçèéééêëìêíîëìíìíîîîïø"ôïïðððïòóóñóóòõòòóôóôôõöõõ÷÷÷ùùøúúøøøöõøøùûú÷ùúûüýüûûüþýüýüüýüÿþÿÿÿÿ       ÿÿÿþýýýþþýþýÿüûûûûúüýúüûüüúûüúùûúúøúøùø÷÷÷÷ööööö÷öõõõöõôôóóòñõóðñòòððððñðòíííõïñîíêééêëêééèçççèèèçæäããääãâßä/  #ðÚÛÚÛÚÚÚØ×ÕÖÕÖÕÔÓÒÌ &5BJRZdlv‰˜¥²¼ÅÈÉËËÌÏÐÐÑÒÔÖÜÙÙÙÝÛÜÜÝÞßàáâãäääççèéèççèçéêéééëêëôóêìíììííïîõñîðñðïðñôóñññóôóóóôóôõõõöõ÷÷÷øøùúú÷øù÷õööøùúúøóùüûûûüýüýþüúüüüýüÿþüþÿþÿÿÿ   ÿÿþþþþýþþÿýþüýüüÿüþýüýýýýüüýûûýûúúúúùø÷øùùùùöö÷÷÷ööööôôöóôóõøõòòòòòññïððïîîñúûîëììêëêêííëëèçèææèçæåääãäåâàáøÝààÞÜÜÜÛÛÙØØÖÙÕ××ÔÓÐÆ¼ ,9DLV^foxƒ«¶¿ÆÉÉËÍÎÐÐÐÒÝåרØÚÛÛÜÛÝÞÞÞàãåääæèèçèèèçèçèèéèéëëíñïëíîííîíîïðìðïïòñððñõôòóõöôôóóôôõõõöù÷÷÷÷ùøùúùùøúûöòöö÷ùüüüùýüüüýþÿþþýýýýþÿÿÿ* ÿ        þþÿÿÿþýýþýþýûþüúýýýýüýüüüüûüúûûúùúùøø÷øøø÷÷öõ÷öööõõõôõòóóõôôóñòñïïîîñïîíîîðìëíìêìëêêëêêèæææåæñîãâããââàéçàÝÜÜÝÛÚÙÙÙÙØ×Õ×ÕÔÔÔÓÐÊ¿´ &2?IR[glt‰”¢¯ºÄÊÌÍÍÏÑÓÔÛùÕרÜÝÜÝÜÝÞàáãååææèéèèéëêèêêêçéêêëëðïìëíîíîíîïïõòïïñðññññõõóôôõôõôôõôöõö÷õ÷÷øøøùúùøøúúõQõõö÷ûûý9ùûýþþÿÿýýýüüýýÿÿÿÿÿ  )  ÿþþÿÿÿýüûüüüüûûùúþþüûûûûûúûúùúûùúøùøùøùøö÷úøõõöööôõóóóôòòñóóòððñðïë ,úíðìíììíîîíëëêéêêéèèçææåæåäãââäâàßàÞÝÝÛÚÚÛÚÙÙÙ×ÖÖÖÕÔÔÓÒÐʸ¬ )6CLVienw‚™¥±¼ÅÊËËÌÎÏÑÕÓÕÖÖØÛÜÛÜÜÞÞßàáâäåçéêéèéèèèèëìíèèèêëêêêéêëêëëìîíîðîïòðïðððóòðóðìòôõòôóõôöõñõ÷÷ööøùù÷÷úùóTõõø÷ûúúS2ùýýýýýüüüûûûüÿýÿÿÿýÿÿ      ÿÿÿþþþýþýüüûûûüüûûùúýÿýûúúúúúûùúúúùùùø÷øùûùö÷úøõõõöõôôóôóóòñòññòñðððíêòíïïñôýïìëëëëêèçèêéæççæäõ!èåãáâáßàÞÞÝÝÜÜÜÜÚØØØÙÕÖÕÔÔÒÓÑÍÄ»¯¤ !/=GOY_ir{„œ©µÁÈËÌÌÍÎÏÏÒ××ÖØÙÙÚÜÝÝÝÞßâäæèêëêêèçèééççíîçéìñîééêëêêêêêîîïðïïïïðñððòòññ "õõôóòóóôõ÷÷÷÷öö÷øø÷ö÷øüôî÷ùúùüúù( ùüýþþýüûüüûüýýýþÿþþÿÿÿÿÿÿ          ÿþ ÿÿÿýÿþüüýüüüüüúúûûûúúúùúûùúúúúùùø÷÷úüùööö÷öõôõõóóôôóòòòñðñññððïîïö÷íìíîñ÷ÿñìëëíëéèççêïñëççßýåäáââàßáàÝÜÜÜÛÛÚØØ×ÖÔÖÔÔÔÔÒÐÉ¿´§œ&5@JQZcou~ˆ”¢®ºÃÊÌÍÏÎÐÐÒÔ×××ØÙØÚÜÞÞßáâåëñõóðêèèéêæçèçççèéèéèééêêçèêêëîííîïðïîîððñóôóéE³5ðõôóôóóóö÷ø÷÷ö÷øùøöõõùý÷øøüùøúøúõúþüüÿýüûüüûüýþýþýýýþÿÿý m    ÿÿþþÿÿþþüûüüûûúûúüýüýüúúûúúùùøøøúúøøøø÷øùú÷öõôöõôóôôóóóôóòññïðñðññïïððìììììíïñïëëêìééèéèçêíêæçâõ/ìâááààßáâßÜÝÜÙÙÙÚ×ÖÖÔÕÕÒÒÓÑÐÌø«ž” ,9DNU^koxƒ›§´¿ÆÊÌÍÏÐÒÓÒÔÙ×רÚÛÛÖHQÿáèú1S$ùíèèèææçééèèééèççèéêéèéêéëìííîîððïîïððóôòì2‚%ïòóñóòôóôö÷÷ö÷÷ø÷÷÷ööø÷øùõ÷ööø÷öPøüûûûûûúúüýþýýùüýýþÿÿ  þ  Z7e ,7ÿ[  ÿÿÿÿþýüýýÿýüûüûûûùúûýÿýúùúúûûúøøù÷øúùùøøø÷ööúùùøôõõôóôôòòôöóòðñððñððóóïîîîíìëìììëììëêêêêéêéçççæåæåâ×ààààßàßàßÜÛÝÜÚÙØØ×ÖÖÕÔÓÑÑÔÑËĺ¯£—Ž"/<HOWair{†‘«¸ÂÇÉÌÎÎÐÒÒÔÔÖÖ××ÚÛÕMMøáâ:”=Úîêçåçççèîééèèçæõõèçèèèèèéìîìííííîîïïïñøöðòòïòòñññòòôóõõõ÷÷ööõõö÷õõöõöúþ÷÷óA¼Eñúúúùùùùúúûûýüüûýýüþþþÿþ)5( ) ÿþþÿÿÿÿÿþþýþþþýüþüýüþüûûûúúúüýüúûüúúûúøùúøøúøùøø÷÷÷÷ø÷ùùõôõôõôôóóôöòõóòððððñòñðííîíììíîíêëïìêêêêééèçæææåääääááááààÞÞÝÝÜÜÚÚÚØ×ÖÕÕÕÔÒÑÑÑÍż³¦›‘ˆ &4@JRZdlt‰”¢°»ÃÈËËÍÎÐÒÒÔÔÕÖרÚÛííããã6bÜ‘ìéçæèèæèóéççëëç çæèéèèèéëìíîìíòðïðïïóýûñòôôòòôññðôóóôôõ÷öö÷÷÷öööõöõôÿ/úøø' øùûûùúûûùûüûüüûüýüüüýýýüýÿÿAn üþ    ÿÿþþýþþÿÿÿÿþþýýýýýüþûûûüýûúûûúúûûûûýüúúùùùúùøúûø÷ø÷üø÷÷öööøøõõôôôóôóôòñôòñññðóóïîïîíììëíëíîêëíêëêêééèççæææåãããäâáàâáßÞÝÝÝÜÛÚÙÙØÖÖ×ÕÓÒÑÐÒÏÉÀ¶ªž”‹‚ +8DMT]fnxš§³¿ÇÈÊÌÍÍÐÐÓÔ×ÖÖ×ÚÛØÚÞáè@Sîæìåæäæççèçççèíëéèçèêééèêëììííîïîïîïðñòòðòõñòóõôòòóóöõôõööõùùõööôóôóúùøùúøùúúúùøúþý÷ùûûüþûüþüûûüüüüýýýþþÿÿ7   ÿÿþþýþüþýýÿþþýýýüüüýûûûüüúúúúùúûúúüüùùûúùùûøøüú÷÷ø÷ ý÷øööö÷þþôôóôôôòóñòðñðñññöôîîïîíììëñííìëêéëêëééèæææåäåäããáãàßààÝÜÜÜÛÚÚÚÙ××ÖÖ×ÔÖÒÑÑÐËź®¡–Ž„} #0>GOV`jq{†’ž«·ÁÈÊÍÎÌÏÐÑÒÖÕÖÙÚÚÛÜÞàåëçäèéæçîååäåæçææçèéççêéææçééêêéëìííîìîîïðñðòóññððñóóöòóõôôöõõöõõö÷÷õõõõóóôõööõöýûúøøúýúøø÷ù÷÷÷ùúúûûüûüýüüýþþþþÿÿÿþÿþ ÿü  þýÿþüýýýÿÿýÿþüúûüþþüüúûùøúøùúúùùûûù÷ùúûúùøøûùùøù÷ü÷÷ööõóÿòóóôôòòòñòòóòððñóòîîííìíìëòñêìêêéêêêééèåææåãäåââáâßÞÞßòéßÜÛÚØ×××ÖÕÔÔÓÓÒÐÏÌÆ¼°¥˜Ž‡~x'6AIQZdlt~‰•£¯ºÄÉÌÌÍÎÎÐÑÓÔØÚÙÚÚÚÝàâããääãäãâäæäääæççééèçèèèçæçèèêìéëëììíëëìñòððóóðïðñððñòôúóóóòôõöõôõ÷÷õôööô÷õóôöö÷ûúøø÷øøö÷÷÷øø÷÷øùúúú$üúûûüüþýùûÿÿýÿýþÿÿÿÿýý    ÿÿþÿÿþÿýþþýþþþÿüüýýýýüýýüûûûúùúü÷øûúøùúúùøùùùùø÷÷ùøøöö÷ö÷öööõõôö÷ôóòòôñòñðñòððñðïïîîíîíììêëìòîèééèéééèç÷ôåæåääâãâáààßÞÝÙx£ÔÚØÛäâÖÔÔÔÓÓÒÑÑàÎÀ³¨œ‘‡€ys ,;DLU]gm…Ž˜¦²½ÆËÊËÍÏÐÒÓÓÕÖÖØÙÚÞÞßààáááâãáâæäääååçéêææêêççæçèéêìèëêëêéëëëïðîïòòïïñòððñóóóóöôóòù÷ôóõöõõúýõõõôôôôö÷ø÷÷÷÷÷ööõö÷ø÷÷ùùùûþûúùùúýýþþþþýüÿþÿþÿÿþÿ   þþÿÿÿÿÿþýýþýÿþüþýûúüüýÿýûúúúúøùú÷ùüüúúùùùùùøøúüûø÷ø÷÷õöõööõööõôôööôòóòòòòóññîïðïîîîïîîïîîðêêééçééèéééèæùöåæææåáââàààÞßÝÙ_”ÔÚØÚâßÕÕÔÔÓÒÒÑÐíߺª •‹‚{un>$1>GPW`h}‡†«¸ÀÉÉËÌÍÏÑÒÓÓÕÕÖØìõåÛÞßßßááâááâãäåååææçææçèçèèçèéêéîëêéìëëêëììîðòòïðððï÷ ññóÿÿõòòóôõôôõ÷ûôôöõôóóõö÷øùøø÷ø÷ö÷÷÷ùøöúüûùúùüÿûúûùD¿|öþýþýþþþÿýÿýþþýÿÿò ÿÿýýþýÿþÿþýúüÿÿþþýúúûûûüøüùøúûúúúøúÿýøøùøûû÷øøöõöõööööööõõôóóóóóòóñóñïïðïîîîîîííîîøðêëñèêéêééèéèçæåæçæåàâáààßÞÝÝÞÞãÞÚÙØ×ÖÔÖÖÔÓÒÑÑÐÌÓ̱¢˜…}vphP&5AKRZdks}ˆ”¢°ºÄÈÊËËÍÏÐÑÒÓÓßßæëáÛÝÞßààáààáâáåååæååæå÷õçéééèèéëéëêêéëíîíëëëíðòòðððïòøùòòóúùóòóóóõôôõõõùýôôóõõúõõõ÷þú÷øö÷øø÷ö÷÷÷ø÷ùøùùúùûùùüûúóh"Åïýþþýýþþþÿþþÿþÿÿÿÿÿ Ý(ÿÿþþüþýýÿüúýýûüýþþúøùúøúùúúùøùúúø÷õ÷ø÷ùüü÷öõ÷þùööööõõôóóôóóòóòñòððððïðîíîïîííííèú õêêöéêèèèéçæææåååäãâààààßÝÞÝÝÝÛØÙÛÙØØÖÔÕÕÔÒÐÐÎÍȺ¯¦š†xpib,:EMU]fox‚Œ—¥²¼ÄÉÉÊÍÎÏÏÑÐÒÝÝ××ÙÛÜÞÞàßßààáááäååääåæã äççèéëéêééêéèèêíííëêîòóòïïïðòôóñññòòñòôóòôôóôøùõôóóôöõõööõ÷ûúø÷÷ùù÷÷ööööøúùøùúùøúùúúúúüþýýûýÿÿþýÿþþÿÿþÿÿÿ 5ÿÿÿÿÿÿÿÿÿÿþüþüüüþþüüþýýýúüþüùúüúúùúûúùùùùúùùúûùùùù÷÷ùöù÷õUñöùøöõóóóòòóññóóòñðïïïííîîïðíìðôêééééêèééèëêèèæåæååäãâáâåâàÞÝÝÜÜÜÛÚÚÛØØ×ÔÓÓÒÒÑÐÏËÈÀ´©“Š€ysjc]$1<GOW_irz„Ž›§´¾ÆÈÊÌÍÍÐÚßàÖÔÖ×ÙÚÛÜÝÞÝÞßßàßáâäåããäåäöôäçèçèèèèèééèéèéëëìëêíðññîïððïðñððññòñòóóòôôôõôôôóóóóõöôõ÷öúø÷÷ø÷ùù÷öõõö÷÷øø÷øùù÷øùøùúþÿþýýþÿþûûýþÿþþþþÿÿÿþÿÿÿÿÿÿ  ÿþÿþÿÿÿÿÿÿÿþþüüýûûúþÿþþýûûûûúûúüüüûùúùøþúûûùúûúúùýþöøùø÷õ÷÷ø÷öõú÷õöø÷ööóñññòòññòôñòïîííîíîîíííìïòêêìêéêêçèêöìçççèçääåäãàãëäàÞÞßÛÜÝÜÛÙØØ×ÕÕÔÓÒÑÐÐÏÉÁ·«¡•Œ„{unh`X(4?IRZcjr{†’ž«·ÁÆÊËËÌÏÛæå×ÓÖרÙÙÚÛÜÛÜÞÞÞÞÞàâääââäåããåçççéåæççéèèèçêêêêéëîíîòïîïîïïïððññòñòóóóôóóóóôôóòðôóóõõöøúùþúöö÷øøøöôôõ÷ôöö÷÷øøøøøùùúûüûù+þüüüÿþþþþþþþþýÿþÿÿþþÿÿÿÿÿÿÿÿþÿÿþýþýüþþÿýûûüüûûüüýûûúúøøþúúúúûúúùøöøúùùøøø÷ööööõõõõööõôòóóòóòóòôôóñðîïîîñðïîîîìííëëëééêèèëùìæçèçæäääååááâààßààÜÝÜÜÜÚÚÙ×ÕÔÔÓÒÑÏÎÌĸ®¢˜Ž…}vogkaQ +7COV\emvŠ–¡¯ºÂÉÉÊÎÍÎÓÔÓÔÕÖ×ÙÚÚÛÜÜÝÝÞßßßààãäââäååæççææéçççèééêêèêééêéìöõîòðîïððñññòòóôóòóóóòòóõöõõõõôõôôõõ÷ú ÿ÷øøøø÷õôóô÷ô÷ùúøùøúùúúúüýýýüûûÿýýÿÿÿÿÿþÿÿÿÿÿÿÿÿ ÿÿÿÿÿþÿÿþþþþÿÿýýýÿýüüûûûûüüûúûùùúúøúùúúúûúûúùúú÷øûúø÷÷÷øööõû÷õõóóôôóòóóòòóóñòñððïñðïðòðíìììììëêéééêéèçëéæåçæäåäääããááááßÞÝÞÛÛÚÙÚÞÜ×ÕÔÓÒÒÒÐÏÌÄ»²­¨‘‡~vokbdZH "0=LRW`hpy‚™¦±½ÅÊÌÍÍÏÏÑÓÔÕÖרÚÚÛÜÜÜÝÝÞáâàßáããååååççææçéçèèèéêëìêéééêëìôôîððïððïñññòòóóññðòòññòôõõôôôõôõõóõõùt¼A÷÷øùùøõóôöõõõø÷ùùù÷úùúúùû  ûþüûüýþüüþýþþþþÿÿþþýþÿþþþÿ  ÿþþþÿÿÿÿÿÿÿÿÿÿþþÿÿþþþþþþüÿüþýýüûüýüûûûûúúúúüùúùúøùøúùúùùùùøøøùùø÷ùø÷ö÷÷÷ôööûøôü÷ñòòòñòòòòóóñññïðîïîîïîîîîìëìêéééèçéæççæåæäããäääãâááàßÞßÞÛÜÜÙÛÛØ×âÝÕÕÔÒÑÑÑÏÎǽ²¬³²ypijaTKAindi-0.5/src/examples/Makefile0000644000175000017500000000237710610527202014162 0ustar jrjr# relative path to dir with libraries LIBROOT = ../ # compiler and linker flags CC = gcc CLDFLAGS = -g GCCFLAGS = -ffast-math -Wall -DHAVE_CONFIG_H CFLAGS = $(CLDFLAGS) $(GCCFLAGS) -I$(LIBROOT) -I../../ LDFLAGS = $(CLDFLAGS) -L$(LIBROOT) LIBS = -llilxml -lindicom -lm # list each sample device DRVS = tutorial_one tutorial_two tutorial_three tutorial_ccdpreview tutorial_dome tutorial_rain # supporting files comprising the INDI driver framework implementation IDAI = ../indidrivermain.o ../eventloop.o # build everything all: drivers # build each sample driver drivers: $(DRVS) # build each INDI driver process tutorial_one: $(IDAI) tutorial_one.o $(CC) $(LDFLAGS) -o $@ $(IDAI) tutorial_one.o $(LIBS) tutorial_two: $(IDAI) tutorial_two.o $(CC) $(LDFLAGS) -o $@ $(IDAI) tutorial_two.o $(LIBS) tutorial_three: $(IDAI) tutorial_three.o $(CC) $(LDFLAGS) -o $@ $(IDAI) tutorial_three.o $(LIBS) -lz tutorial_ccdpreview: $(IDAI) tutorial_ccdpreview.o $(CC) $(LDFLAGS) -o $@ $(IDAI) tutorial_ccdpreview.o $(LIBS) -lz tutorial_dome: $(IDAI) tutorial_dome.o $(CC) $(LDFLAGS) -o $@ $(IDAI) tutorial_dome.o $(LIBS) -lz tutorial_rain: $(IDAI) tutorial_rain.o $(CC) $(LDFLAGS) -o $@ $(IDAI) tutorial_rain.o $(LIBS) -lz # clean up clean: touch x.o rm -f *.o $(DRVS) x.err indi-0.5/src/examples/README0000644000175000017500000000525310610534475013410 0ustar jrjr************************************************* * INDI Developers Manual * Chapter 8: Tutorial ************************************************** Introduction -------------- The tutorials included in the INDI Library can be used with any INDI compatible client. The following instructions are provided to test the drivers with KStars. If you are running a different client, refer to your client documentation. Tutorials ---------- Four tutorials are presented to introduce developers to the INDI architecture. tutorial_one: We construct a most basic (and useless) device driver to illustate basic INDI structures. tutorial_two: We create a simple simulator. We will use a few handy utility functions provided by INDI like timers, string <---> number conversion, and more. tutorial_three: We create a simple device, and establish a data channel with the client to transmit a FITS file. tutorial_dome and tutorial_rain are part of the inter-driver communication tutorial. Usage -------- 1. Run 'make' in the current directory. (This assumes that you built INDI in the src directory, refer to README there). ------------------------------------------------------------------------------------------ 2. Run KStars (v1.1 or above is required) Under KStars, click on the "device" menu, then click on the "device manager". Click on the "client" tab and then click on the "add" button. A dialog box will be displayed with three fields: name, host, and port. You can enter anything in the name field, for example "my device" or "tutorial". Enter "127.0.0.1" in the host name and "8000" in the port entry (without the quotes). This device will be saved in your client menu. So you only to do #2 once. ------------------------------------------------------------------------------------------ 3. In the src/examples directory, run each tutorial $ indiserver -v -p 8000 ./tutorial_NUM where num is the tutorial number (tutorial_one, tutorial_two, or tutorial_three). For the inter-driver communications tutorial, type instead: $ indiserver -v -p 8000 ./tutorial_dome ./tutorial_rain ------------------------------------------------------------------------------------------ 4. In KStars, go the device menu --> device manager --> client and select the host you added in step #2 and hit connect. ------------------------------------------------------------------------------------------ 5. The connection icon should be changed to connected, otherwise, an error message will be displayed. ------------------------------------------------------------------------------------------ 6. Close the device manager, and open the INDI Control Panel in the device menu. You can control your device from there. indi-0.5/src/examples/tutorial_one.c0000644000175000017500000002002310610526344015364 0ustar jrjr/* INDI Developers Manual Tutorial #1 "Hello INDI" We construct a most basic (and useless) device driver to illustate INDI. Refer to README, which contains instruction on how to build this driver, and use it with an INDI-compatible client. */ /** \file tutorial_one.c \brief Construct a basic INDI driver with only one property. \author Jasem Mutlaq */ /* Standard headers */ #include #include #include #include #include /* INDI Core headers */ /* indidevapi.h contains API declerations */ #include "indidevapi.h" /* INDI Eventloop mechanism */ #include "eventloop.h" /* INDI Common Routines */ #include "indicom.h" /* Definitions */ #define mydev "Simple Device" /* Device name */ #define MAIN_GROUP "Main Control" /* Group name */ /* Function protptypes */ void ISInit(void); void connectDevice(void); /*INDI controls */ /* We will define only one vector switch property. The CONNECTION property is an INDI Standard Property and should be implemented in all INDI drivers. * A vector property may have one or more members. */ /* First, we define and initilize the members of the vector property */ static ISwitch PowerS[] = { {"CONNECT" /* 1st Swtich name */ , "Connect" /* Switch Label, i.e. what the GUI displays */ , ISS_OFF /* State of the switch, initially off */ , 0 /* auxiluary, set to 0 for now.*/ , 0} /* auxiluary, set to 0 for now */ ,{"DISCONNECT" /* 2nd Swtich name */ , "Disconnect" /* Switch Label, i.e. what the GUI displays */ , ISS_ON /* State of the switch, initially on */ , 0 /* auxiluary, set to 0 for now.*/ , 0} /* auxiluary, set to 0 for now */ }; /* Next, we define and initlize the vector switch property that contains the two switches we defined above */ static ISwitchVectorProperty PowerSP = { mydev /* Device name */ , "CONNECTION" /* Property name */ , "Connection" /* Property label */ , MAIN_GROUP /* Property group */ , IP_RW /* Property premission, it's both read and write */ , ISR_1OFMANY /* Switch behavior. Only 1 of many switches are allowed to be on at the same time */ , 0 /* Timeout, 0 seconds */ , IPS_IDLE /* Initial state is idle */ , PowerS /* Switches comprimising this vector that we defined above */ , NARRAY(PowerS) /* Number of Switches. NARRAY is defined in indiapi.h */ , "" /* Timestamp, set to 0 */ , 0}; /* auxiluary, set to 0 for now */ /* void ISInit() Initilize variables, allocate memory...etc For this simple tutorial, we're just going to set isInit to 1 and return */ void ISInit() { static int isInit=0; /* Did we already initialize? If yes, then return */ if (isInit) return; isInit = 1; } /* void ISGetProperties (const char *dev) * INDI will call this function when the client inquires about the device properties. * Here we will use IDxxx functions to define new properties to the client */ void ISGetProperties (const char *dev) { /* #1 Let's make sure everything has been initialized properly */ ISInit(); /* #2 Let's make sure that the client is asking for the properties of our device, otherwise ignore */ if (dev && strcmp (mydev, dev)) return; /* #3 Tell the client to create a new Switch property PowerSP */ IDDefSwitch(&PowerSP, NULL); } /* void ISNewSwitch(...) * INDI will call this function when the client wants to set a new state of existing switches ** Parameters ** * dev: the device name * name: the property name the client wants to update * states: an array of states of members switches (ISS_ON and ISS_OFF) * names: names of the switches. The names are parallel to the states. That is, member names[0] has a state states[0], and so on... * n: number of switches to update, which is also the dimension of *states and names[] */ void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { /* #1 Let's make sure everything has been initialized properly */ ISInit(); /* #2 Let's make sure that the client is asking to update the properties of our device, otherwise ignore */ if (dev && strcmp (dev, mydev)) return; /* #3 Now let's check if the property the client wants to change is the PowerSP (name: CONNECTION) property*/ if (!strcmp (name, PowerSP.name)) { /* If the clients wants to update this property, let's perform the following */ /* A. We update the switches by sending their names and updated states IUUpdateSwitches function. If there is an error, we return */ if (IUUpdateSwitches(&PowerSP, states, names, n) < 0) return; /* B. We try to establish a connection to our device */ connectDevice(); return; } } /* void ISNewText(...) * INDI will call this function when the client wants to update an existing text. ** Parameters ** * dev: the device name * name: the property name the client wants to update * texts: an array of texts. * names: names of the members. The names are parallel to the texts. * n: number of texts to update, which is also the dimension of *texts and names[] */ void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { /* Even though we didn't define any text members, we need to define this function. Otherwise, the driver will not compile */ /* Since there is nothing to do, we simply return */ return; } /* void ISNewNumber(...) * INDI will call this function when the client wants to update an existing number. ** Parameters ** * dev: the device name * name: the property name the client wants to update * values: an array of values. * names: names of the members. The names are parallel to the values. * n: number of numbers to update, which is the dimension of *numbers and names[] */ void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { /* Even though we didn't define any number members, we need to define this function. Otherwise, the driver will not compile */ /* Since there is nothing to do, we simply return */ return; } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n) { } /* void connectDevice(void) * This function is called when the state of PowerSP is changed in the ISNewSwitch() function. * We check the state of CONNECT and DISCONNECT switches, and connect or disconnect our fake device accordingly */ void connectDevice(void) { /* Now we check the state of CONNECT, the 1st member of the PowerSP property we defined earliar */ switch (PowerS[0].s) { /* If CONNECT is on, then try to establish a connection to the device */ case ISS_ON: /* The IDLog function is a very useful function that will log time-stamped messages to stderr. This function is invaluable to debug your drivers. * It operates like printf */ IDLog ("Establishing a connection to %s...\n", mydev); /* Change the state of the PowerSP (CONNECTION) property to OK */ PowerSP.s = IPS_OK; /* Tell the client to update the states of the PowerSP property, and send a message to inform successful connection */ IDSetSwitch(&PowerSP, "Connection to %s is successful.", mydev); break; /* If CONNECT is off (which is the same thing as DISCONNECT being on), then try to disconnect the device */ case ISS_OFF: IDLog ("Terminating connection to %s...\n", mydev); /* The device is disconnected, change the state to IDLE */ PowerSP.s = IPS_IDLE; /* Tell the client to update the states of the PowerSP property, and send a message to inform successful disconnection */ IDSetSwitch(&PowerSP, "%s has been disconneced.", mydev); break; } } /* That's it! check out tutorial_two where we simulate a simple telescope! */ indi-0.5/src/examples/tutorial_ccdpreview.c0000644000175000017500000003001510605175713016744 0ustar jrjr/* INDI Developers Manual Tutorial CCDPreview "CCD Preview" In this tutorial, demostrate the ccdpreview feature, and simulate the readout of a CCD camera. Refer to README, which contains instruction on how to build this driver, and use it with an INDI-compatible client. For use with Kstars: click "Connect"; click "ON"; click "Start" */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* INDI Core headers */ #include "indidevapi.h" #include "indicom.h" #include "eventloop.h" #include "base64.h" #define mydev "Device with Data Transfer" #define IMAGE_CONTROL "Image Control" #define COMM_GROUP "Main Control" #define IMAGE_GROUP "Image Settings" #define POLLMS 100 #define WIDTH ((int) CtrlN[0].value) #define HEIGHT ((int) CtrlN[1].value) #define BYTESPERPIX ((int) CtrlN[3].value) #define BYTEORDER ((int) CtrlN[4].value) #define FWHMPIX (CCDInfoN[0].value) #define FOCUS (FocusN[0].value) void uploadStream(uLong maxBytes); void readoutSim(); void makepic(); /*INDI controls */ /* These properties with these names are required display a video stream*/ static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}}; static ISwitchVectorProperty PowerSP = { mydev, "CONNECTION" , "Connection", COMM_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0}; static ISwitch StreamS[2]={{ "ON", "", ISS_OFF},{"OFF", "", ISS_ON}}; static ISwitchVectorProperty StreamSP={mydev, "CCDPREVIEW_STREAM", "Video Stream", COMM_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE,StreamS, NARRAY(StreamS),"",0}; static INumber CtrlN[] = {{"WIDTH", "Width", "%0.f",16., 512., 16., 256.}, {"HEIGHT", "Height", "%0.f", 16., 512., 16., 256.},{"MAXGOODDATA", "max. good data value", "%0.f", 1., 256.0*256.0*256.0*256.0, 0., 30000.}, {"BYTESPERPIXEL", "Bytes/pix", "%0.f", 1., 4., 1., 2.},{"BYTEORDER", "Byte Order", "%0.f", 1., 2., 1., 2.}}; static INumberVectorProperty CtrlNP = {mydev , "CCDPREVIEW_CTRL", "Image Size", COMM_GROUP, IP_RW, 60, IPS_IDLE,CtrlN, NARRAY(CtrlN),"",0}; /* These properties with these names are required by the indi client to calculate the FWHM in arcsec*/ /* The FWHM here is in units of pixels. The Pixelsize here is in units of microns. */ static INumber CCDInfoN[] = {{"CCD_FWHM_PIXEL", "FWHM[pix]", "%0.2f",0., 100., 1., 3.}, {"CCD_PIXEL_SIZE", "Pixelsize[mu]", "%0.1f",0., 100., 1., 15.5}}; static INumberVectorProperty CCDInfoNP = {mydev , "CCD_INFO", "CCD Info", COMM_GROUP, IP_RO, 60, IPS_IDLE,CCDInfoN, NARRAY(CCDInfoN),"",0}; /* Blob for sending image (required but the names can be chosen freely)*/ static IBLOB imageB = {"CCD1", "Feed", "", 0, 0, 0, 0, 0, 0, 0}; static IBLOBVectorProperty imageBP = {mydev, "Video", "Video", COMM_GROUP, IP_RO, 0, IPS_IDLE, &imageB, 1, "", 0}; /* Start / Stop Switch (not required, and only defined in this specific driver)*/ static ISwitch ReadoutS[2]={{ "Start", "", ISS_OFF},{"Stop", "", ISS_ON}}; static ISwitchVectorProperty ReadoutSP={mydev, "readout", "Readout", COMM_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE,ReadoutS, NARRAY(ReadoutS),"",0}; /* Adjustable Focus (not required, and only defined in this specific driver)*/ static INumber FocusN[] = {{"Focus", "Focus", "%0.f",0., 100., 1., 40.}}; static INumberVectorProperty FocusNP = {mydev , "Telescope", "Telescope", COMM_GROUP, IP_RW, 60, IPS_IDLE,FocusN, NARRAY(FocusN),"",0}; /* 1 if "readout simulation" is running, 0 otherwise*/ volatile int readout_is_running=0; /* The number of bytes read from the "virtual CCD" up to now */ volatile uLong readout_bytes_done=0; /* 1 if readout simulation is aked to stop, 0 otherwise*/ volatile uLong readout_stop=0 ; /* a buffer to hold a 16 bit image to be displayed*/ unsigned char *image; /* in this tutorial we simply calculate the FWHM from the focus-position in a real driver you will have calculate from the FWHM from the image you took with your CCD. For example you can write a fitsfile and use sextractor (sextractor.sourceforge.net) to make a list of all detected objects with their "FWHM_WORLD" parameters and take the median of that list. But make your FWHM is in units of pixels. */ double fwhm() { return 0.3*sqrt((FOCUS-50.0)*(FOCUS-50.0))+1.0; } /* Initlization routine */ static void readout_start() { if (readout_is_running!=0) return; /* start timer to simulate CCD readout The timer will call function previewSim after POLLMS milliseconds */ image=malloc(WIDTH*HEIGHT*BYTESPERPIX); readout_bytes_done=0; readout_stop=0; readout_is_running = 1; CtrlNP.s=IPS_OK; IDSetNumber(&CtrlNP, NULL); makepic(); IEAddTimer (POLLMS, readoutSim, NULL); } void ISGetProperties (const char *dev) { if (dev && strcmp (mydev, dev)) return; IDDefSwitch(&StreamSP, NULL); IDDefSwitch(&ReadoutSP, NULL); IDDefSwitch(&PowerSP, NULL); IDDefNumber(&CtrlNP, NULL); IDDefNumber(&FocusNP, NULL); IDDefNumber(&CCDInfoNP, NULL); FocusNP.s=IPS_OK; IDSetNumber(&FocusNP, NULL); CCDInfoNP.s=IPS_OK; IDSetNumber(&CCDInfoNP, NULL); CtrlNP.s=IPS_OK; IDSetNumber(&CtrlNP, NULL); IDDefBLOB(&imageBP, NULL); } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (mydev, dev)) return; /* suppress warning */ n=n; dev=dev; name=name; names=names; } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; /* Connection */ if (!strcmp (name, PowerSP.name)) { IUUpdateSwitches(&PowerSP, states, names, n); PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, NULL); return; } if (!strcmp (name, StreamSP.name)) { IUUpdateSwitches(&StreamSP, states, names, n); StreamSP.s = IPS_OK; IDSetSwitch(&StreamSP, NULL); return; } /* Readout start/stop*/ if (!strcmp (name, ReadoutSP.name)) { IUUpdateSwitches(&ReadoutSP, states, names, n); if (ReadoutS[0].s==ISS_ON) { readout_start(); } if (ReadoutS[1].s==ISS_ON) { readout_stop=1; } ReadoutSP.s = IPS_OK; IDSetSwitch(&ReadoutSP, NULL); return; } } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (mydev, dev)) return; /* suppress warning */ n=n; dev=dev; name=name; names=names; texts=texts; } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (mydev, dev)) return; /* suppress warning */ n=n; dev=dev; name=name; names=names; if (!strcmp (name, CtrlNP.name)) { if (readout_is_running==0) { IUUpdateNumbers(&CtrlNP, values, names, n); } else { IDMessage (mydev, "The Parameters can not be change during readout\n"); } CtrlNP.s=IPS_OK; IDSetNumber(&CtrlNP, NULL); } if (!strcmp (name, FocusNP.name)) { if (readout_is_running==0) { IUUpdateNumbers(&FocusNP, values, names, n); } else { IDMessage (mydev, "The Parameters can not be change during readout\n"); } FocusNP.s=IPS_OK; IDSetNumber(&FocusNP, NULL); } } void uploadStream(uLong maxBytes) { unsigned char *Data, *compressedData; int r=0,offs=0; unsigned int i =0; unsigned char j; static uLong old_maxBytes, sendBytes; uLongf compressedBytes=0; uLong totalBytes; /* #0 Allocate buffer*/ totalBytes = WIDTH*HEIGHT*BYTESPERPIX; Data = (unsigned char *) malloc (sizeof(unsigned char) * totalBytes); compressedData = (unsigned char *) malloc (sizeof(unsigned char) * totalBytes + totalBytes / 64 + 16 + 3); if (Data == NULL || compressedData == NULL) { IDLog("Error! low memory. Unable to initialize fits buffers.\n"); return; } if (maxBytestotalBytes) { maxBytes=totalBytes; } j=0; for (i=old_maxBytes; i < maxBytes; i+= 1) { if (BYTEORDER==1) { Data[i-old_maxBytes]=image[i]; } if (BYTEORDER==2) { if (i%(2*BYTESPERPIX)==0) { offs=i/2; } if ((i%(2*BYTESPERPIX))WIDTH-1)||(j>HEIGHT-1)) { continue; } rr=exp(-2.0*0.7*((x-i)*(x-i)+(y-j)*(y-j))/(fwhm*fwhm)); val=0; for (b=0;b1) { b=(unsigned long) b*(pow(256.0,BYTESPERPIX-2.0)); } makestar(x,y,b,3*fwhm(),fwhm() ); } /*some stars of defined brightness */ for (i=1;i<3;i++) { x=(int) ((WIDTH-1)*(rand()/(1.0*RAND_MAX))); y=(int) ((HEIGHT-1)*(rand()/(1.0*RAND_MAX))); b=65000; makestar(x,y,b,100,fwhm()); } makestar(WIDTH/2,HEIGHT/2,65000,100,fwhm()); } indi-0.5/src/examples/tutorial_three.c0000644000175000017500000002025310605175713015723 0ustar jrjr/* INDI Developers Manual Tutorial #3 "Simple CCD Simulator" In this tutorial, we employ a BLOB property to send a sample FITS file to the client. Refer to README, which contains instruction on how to build this driver, and use it with an INDI-compatible client. */ /** \file tutorial_three.c \brief Simulate a CCD camera by using INDI BLOBs to send FITS data to the client. \author Jasem Mutlaq */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* INDI Core headers */ #include "indidevapi.h" #include "indicom.h" #include "eventloop.h" #include "base64.h" #define mydev "CCD Simulator" #define COMM_GROUP "Main Control" /* Handy macro */ #define currentTemp TemperatureN[0].value void uploadFile(const char* filename); void ISPoll(void * p); static double targetTemp = 0; /*INDI controls */ /* Connect/Disconnect */ static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}}; static ISwitchVectorProperty PowerSP = { mydev, "CONNECTION" , "Connection", COMM_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0}; /* Exposure time */ static INumber ExposeTimeN[] = {{ "EXPOSE_S", "Duration (s)", "%5.2f", 0., 36000., .5, 1., 0, 0, 0}}; static INumberVectorProperty ExposeTimeNP = { mydev, "EXPOSE_DURATION", "Expose", COMM_GROUP, IP_RW, 60, IPS_IDLE, ExposeTimeN, NARRAY(ExposeTimeN), "", 0}; /* Temperature control */ static INumber TemperatureN[] = { {"TEMPERATURE", "Temperature", "%+06.2f", -30., 40., 1., 0., 0, 0, 0}}; static INumberVectorProperty TemperatureNP = { mydev, "CCD_TEMPERATURE", "Temperature (C)", COMM_GROUP, IP_RW, 60, IPS_IDLE, TemperatureN, NARRAY(TemperatureN), "", 0}; /* BLOB for sending image */ static IBLOB imageB = {"CCD1", "Feed", "", 0, 0, 0, 0, 0, 0, 0}; static IBLOBVectorProperty imageBP = {mydev, "Video", "Video", COMM_GROUP, IP_RO, 0, IPS_IDLE, &imageB, 1, "", 0}; void ISGetProperties (const char *dev) { if (dev && strcmp (mydev, dev)) return; /* COMM_GROUP */ IDDefSwitch(&PowerSP, NULL); IDDefNumber(&ExposeTimeNP, NULL); IDDefNumber(&TemperatureNP, NULL); IDDefBLOB(&imageBP, NULL); IEAddTimer(1000, ISPoll, NULL); } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n) { // We're not expecting any BLOBs from the client, nothing to do } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; /* Connection */ if (!strcmp (name, PowerSP.name)) { IUUpdateSwitches(&PowerSP, states, names, n); PowerSP.s = IPS_OK; if (PowerS[0].s == ISS_ON) IDSetSwitch(&PowerSP, "CCD Simulator is online."); else IDSetSwitch(&PowerSP, "CCD Simulator is offline."); return; } } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (mydev, dev)) return; /* suppress warning */ n=n; dev=dev; name=name; names=names; texts=texts; } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { /* Exposure time */ if (!strcmp (ExposeTimeNP.name, name)) { /* Let's make sure that our simulator is online */ if (PowerS[0].s != ISS_ON) { ExposeTimeNP.s = IPS_IDLE; IDSetNumber(&ExposeTimeNP, "CCD Simulator is offline."); return; } IDLog("Sending BLOB FITS...\n"); ExposeTimeNP.s = IPS_BUSY; ExposeTimeN[0].value = values[0]; return; } /* Temperature */ if (!strcmp (TemperatureNP.name, name)) { /* Let's make sure that our simulator is online */ if (PowerS[0].s != ISS_ON) { TemperatureNP.s = IPS_IDLE; IDSetNumber(&TemperatureNP, "CCD Simulator is offline"); return; } targetTemp = values[0]; /* If the requested temperature is the current CCD chip temperature, then return */ if (targetTemp == TemperatureN[0].value) { TemperatureNP.s = IPS_OK; IDSetNumber(&TemperatureNP, NULL); return; } /* Otherwise, set property state to busy */ TemperatureNP.s = IPS_BUSY; IDSetNumber(&TemperatureNP, "Setting CCD temperature to %g", targetTemp); return; } } /* Open a data file, compress its content, and send it via our BLOB property */ void uploadFile(const char* filename) { FILE * fitsFile; unsigned char *fitsData, *compressedData; int r=0; unsigned int i =0, nr = 0; uLongf compressedBytes=0; uLong totalBytes; struct stat stat_p; /* #1 Let's get the file size */ if ( -1 == stat (filename, &stat_p)) { IDLog(" Error occoured attempting to stat file.\n"); return; } /* #2 Allocate memory for raw and compressed data */ totalBytes = stat_p.st_size; fitsData = (unsigned char *) malloc (sizeof(unsigned char) * totalBytes); compressedData = (unsigned char *) malloc (sizeof(unsigned char) * totalBytes + totalBytes / 64 + 16 + 3); if (fitsData == NULL || compressedData == NULL) { IDLog("Error! low memory. Unable to initialize fits buffers.\n"); return; } /* #3 Open the FITS file */ fitsFile = fopen(filename, "r"); if (fitsFile == NULL) return; /* #4 Read file from disk */ for (i=0; i < totalBytes; i+= nr) { nr = fread(fitsData + i, 1, totalBytes - i, fitsFile); if (nr <= 0) { IDLog("Error reading temporary FITS file.\n"); return; } } compressedBytes = sizeof(char) * totalBytes + totalBytes / 64 + 16 + 3; /* #5 Compress raw data */ r = compress2(compressedData, &compressedBytes, fitsData, totalBytes, 9); if (r != Z_OK) { /* this should NEVER happen */ IDLog("internal error - compression failed: %d\n", r); return; } /* #6 Send it */ imageB.blob = compressedData; imageB.bloblen = compressedBytes; imageB.size = totalBytes; strcpy(imageB.format, ".fits.z"); /* #7 Set BLOB state to Ok */ imageBP.s = IPS_OK; IDSetBLOB (&imageBP, NULL); /* #8 Set Exposure status to Ok */ ExposeTimeNP.s = IPS_OK; IDSetNumber(&ExposeTimeNP, "Sending FITS..."); /* #9 Let's never forget to free our memory */ free (fitsData); free (compressedData); } /* Poll device status and update accordingly */ void ISPoll(void * p) { /* We need to check the status of properties that we want to watch. */ /* #1 CCD Exposure */ switch (ExposeTimeNP.s) { case IPS_IDLE: case IPS_OK: case IPS_ALERT: break; /* If an exposure state is busy, decrement the exposure value until it's zero (done exposing). */ case IPS_BUSY: ExposeTimeN[0].value--; /* Are we done yet? */ if (ExposeTimeN[0].value == 0) { /* Let's set the state of OK and report that to the client */ ExposeTimeNP.s = IPS_OK; /* Upload a sample FITS file */ uploadFile("ngc1316o.fits"); IDSetNumber(&ExposeTimeNP, NULL); break; } IDSetNumber(&ExposeTimeNP, NULL); break; } /* #2 CCD Temperature */ switch (TemperatureNP.s) { case IPS_IDLE: case IPS_OK: case IPS_ALERT: break; case IPS_BUSY: /* If target temperature is higher, then increase current CCD temperature */ if (currentTemp < targetTemp) currentTemp++; /* If target temperature is lower, then decrese current CCD temperature */ else if (currentTemp > targetTemp) currentTemp--; /* If they're equal, stop updating */ else { TemperatureNP.s = IPS_OK; IDSetNumber(&TemperatureNP, "Target temperature reached."); break; } IDSetNumber(&TemperatureNP, NULL); break; } /* Keep polling alive */ IEAddTimer (1000, ISPoll, NULL); } indi-0.5/src/examples/tutorial_rain.c0000644000175000017500000001150010610521204015522 0ustar jrjr#if 0 Inter-driver communications tutorial - Rain Driver Copyright (C) 2007 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "indidevapi.h" #include "eventloop.h" #include "indicom.h" #define mydev "Rain" #define MAIN_GROUP "Main" /* Connect/Disconnect */ static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}}; static ISwitchVectorProperty PowerSP = { mydev, "CONNECTION" , "Connection", MAIN_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0}; static ILight rainL[] = {{"Status", "", IPS_IDLE, 0, 0}}; static ILightVectorProperty rainLP = { mydev, "Rain Alert", "", MAIN_GROUP, IPS_IDLE, rainL , NARRAY(rainL), "", 0}; static ISwitch rainS[] = {{"On", "", ISS_OFF, 0, 0}, {"Off", "", ISS_ON, 0, 0}}; static ISwitchVectorProperty rainSP = { mydev, "Control Rain", "", MAIN_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, rainS , NARRAY(rainS), "", 0}; static ISwitch propS[] = {{"Define", "", ISS_OFF, 0, 0}, {"Delete", "", ISS_OFF, 0, 0}, {"Crash", "", ISS_OFF, 0, 0}}; static ISwitchVectorProperty propSP = { mydev, "Property Test", "", MAIN_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, propS , NARRAY(propS), "", 0}; void ISGetProperties (const char *dev) { /* MAIN_GROUP */ IDDefSwitch(&PowerSP, NULL); IDDefLight(&rainLP, NULL); IDDefSwitch(&rainSP, NULL); IDDefSwitch(&propSP, NULL); } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n) { dev=dev;name=name;sizes=sizes;blobs=blobs;formats=formats;names=names;n=n; } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; /* Connection */ if (!strcmp (name, PowerSP.name)) { if (IUUpdateSwitches(&PowerSP, states, names, n) < 0) return; PowerSP.s = IPS_OK; if (PowerS[0].s == ISS_ON) IDSetSwitch(&PowerSP, "Rain Collector is online."); else { PowerSP.s = IPS_IDLE; IDSetSwitch(&PowerSP, "Rain Collector is offline."); } return; } /* rain */ if (!strcmp (name, rainSP.name)) { if (PowerSP.s != IPS_OK) { IDMessage(mydev, "The Rain Collector is offline!"); return; } if (IUUpdateSwitches(&rainSP, states, names, n) < 0) return; rainSP.s = IPS_OK; IDSetSwitch(&rainSP, "Rain status updated."); if (rainS[0].s == ISS_ON) { rainL[0].s = IPS_ALERT; rainLP.s = IPS_ALERT; IDSetLight(&rainLP, "Alert! Alert! Rain detected!"); } else { rainL[0].s = IPS_IDLE; rainLP.s = IPS_OK; IDSetLight(&rainLP, "Rain threat passed. The skies are clear."); } return; } /* Property control for observer test */ if (!strcmp (name, propSP.name)) { if (PowerSP.s != IPS_OK) { IDMessage(mydev, "The Rain Collector is offline!"); return; } if (IUUpdateSwitches(&propSP, states, names, n) < 0) return; /* #1 Define */ if (propS[0].s == ISS_ON) IDDefLight(&rainLP, "Defining rain Alert Light property."); /* #2 Delete */ else if (propS[1].s == ISS_ON) IDDelete(mydev, rainLP.name, "Deleting Rain Alert light property."); /* The fun part, crashing. This will cause the driver the 'die' The observer should notice that */ else { char *p = "byebye"; *p = '0'; } IUResetSwitches(&propSP); propSP.s = IPS_OK; IDSetSwitch(&propSP, NULL); return; } } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (mydev, dev)) return; /* suppress warning */ n=n; dev=dev; name=name; names=names; texts=texts; } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { } indi-0.5/src/examples/ccdpreview.txt0000644000175000017500000000525110605175713015422 0ustar jrjrThe CCDPreview The 16 or more bit data read from a CCD chip has to be converted to 8bit in order to be displayed. CCDPreview transfers the whole high accuracy data to the indi client and lets the user adjust the parameters of this conversion. The way the image is converted depends on the client. For example there could be sliders for brightness, contrast, gamma or a simple bitshift slider or two spinbuttons for lower and upper cutoff values. All details of the conversion exist inside the client only and the indi driver does not care about them at all. CCDPreview allows to send parts of the preview image of arbitrary length that are joined on the client side. So the whole image data needs to be sent only once and the preview can be kept up to date during a longer readout sequence. A "maximum good data" value can be set so that saturated pixels can be marked. Control structure: There must be an INumberVectorProperty named "CCDPREVIEW_CTRL" it must contain INumber Elements with the Names "WIDTH", "HEIGHT", "BYTESPERPIXEL", "PIXELORDER" and "MAXGOODDATA". "WIDTH": the width of the image Allowed values are positive integers up to 65635. "HEIGHT": the height of the image Allowed values are positive integers up to 65635. "BYTESPERPIXEL": the number of bytes per Pixel: Allowed values are {1,2,3,4}. The byteorder is lowest byte first. "PIXELORDER": determines how the pixels are fed from the stream into the image. Set it to 1 if you have got a normal CCD. Allowed values are {1,2}. (1) The first pixel received is written to the upper left corner of the preview, the second one right next to it and so on, when a line is finished the next line below is started. (2) The first pixel received is written to the upper left corner of the preview, the second one to the lower right corner. The third one right next to the first one, the fourth one left next to the second one and so on. Pixelorder 2 is usefull for CCDs that are read out from two sides simultaneously. "MAXGOODDATA": the maximum good data value. Allowed values are non negative integers up to 4294967295. Every pixel with a value higher than MAXGOODDATA is marked as defective in the preview (e.g. by red color). So the observer can directly see whether there are saturated pixels. Usage: Before transferring any new image you have to call IDSetNumber on "CCDPREVIEW_CTRL" in order to reset the preview. You can send data to the preview using an arbitrary blob. But you have to set its .format property to ".ccdpreview" (or ".ccdpreview.z" for compressed data). The uncompressed length of each blob must be a multiple of BYTESPERPIXEL. For reasons of bandwidth and protocol overhead it does not make sense to transfer blobs much shorter than 1KByte.indi-0.5/src/examples/tutorial_dome.c0000644000175000017500000001204610610521171015526 0ustar jrjr#if 0 Inter-driver communications tutorial - Dome Driver Copyright (C) 2007 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "indidevapi.h" #include "eventloop.h" #include "indicom.h" #include "observer.h" #define mydev "Dome" #define MAIN_GROUP "Main" void check_rain(const char *dev, const char *name, IDState driver_state, IPState *states, char *names[], int n); /* Connect/Disconnect */ static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}}; static ISwitchVectorProperty PowerSP = { mydev, "CONNECTION" , "Connection", MAIN_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0}; static ISwitch DomeS[] = {{"Open", "", ISS_ON, 0, 0}, {"Close", "", ISS_OFF, 0, 0}}; static ISwitchVectorProperty DomeSP = { mydev, "Dome Status", "", MAIN_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, DomeS , NARRAY(DomeS), "", 0}; void ISGetProperties (const char *dev) { /* MAIN_GROUP */ IDDefSwitch(&PowerSP, NULL); IDDefSwitch(&DomeSP, NULL); IOSubscribeProperty("Rain", "Rain Alert", IPT_LIGHT, IDT_ALL, check_rain); } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n) { dev=dev;name=name;sizes=sizes;blobs=blobs;formats=formats;names=names;n=n; } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; /* Connection */ if (!strcmp (name, PowerSP.name)) { if (IUUpdateSwitches(&PowerSP, states, names, n) < 0) return; PowerSP.s = IPS_OK; if (PowerS[0].s == ISS_ON) IDSetSwitch(&PowerSP, "Dome is online."); else { PowerSP.s = IPS_IDLE; IDSetSwitch(&PowerSP, "Dome is offline."); } return; } /* Dome */ if (!strcmp (name, DomeSP.name)) { if (PowerSP.s != IPS_OK) { IDMessage(mydev, "Dome is offline!"); return; } if (IUUpdateSwitches(&DomeSP, states, names, n) < 0) return; DomeSP.s = IPS_BUSY; if (DomeS[0].s == ISS_ON) IDSetSwitch(&DomeSP, "Dome is opening."); else IDSetSwitch(&DomeSP, "Dome is closing."); sleep(5); DomeSP.s = IPS_OK; if (DomeS[0].s == ISS_ON) IDSetSwitch(&DomeSP, "Dome is open."); else IDSetSwitch(&DomeSP, "Dome is closed."); return; } } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (mydev, dev)) return; /* suppress warning */ n=n; dev=dev; name=name; names=names; texts=texts; } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { } void closeDome() { DomeSP.s = IPS_BUSY; IDSetSwitch(&DomeSP, "Rain Alert! Dome is closing..."); sleep(5); DomeS[0].s = ISS_OFF; DomeS[1].s = ISS_ON; DomeSP.s = IPS_OK; IDSetSwitch(&DomeSP, "Dome is closed."); } /* This is the callback function called by INDI when a new state from the rain collector driver is recieved. Please note that the prototype of this function is specific for SWITCH properties. There are unique callback prototypes defined for all property types in the INDI API */ void check_rain(const char *dev, const char *name, IDState driver_state, IPState *states, char *names[], int n) { switch (driver_state) { case IDS_DEFINED: IDMessage(mydev, "Property %s was defined.", name); break; case IDS_UPDATED: IDMessage(mydev, "Property %s was updated. The rain collector alert is %s.", name, (states[0] == IPS_ALERT) ? "Alert!" : "Ok"); /* Only do stuff if we're online */ if (PowerSP.s == IPS_OK && states[0] == IPS_ALERT) { if (DomeS[0].s == ISS_ON) closeDome(); else IDMessage(mydev, "Rain Alert Detected! Dome is already closed."); } break; case IDS_DELETED: IDMessage(mydev, "Property %s was deleted.", name); break; case IDS_DIED: IDMessage(mydev, "Property %s is dead along with its driver %s.", name, dev); break; } } indi-0.5/src/examples/tutorial_two.c0000644000175000017500000002067410605175713015434 0ustar jrjr/* INDI Developers Manual Tutorial #2 "Simple Telescope Simulator" In this tutorial, we create a simple simulator. We will use a few handy utility functions provided by INDI like timers, string <---> number conversion, and more. Refer to README, which contains instruction on how to build this driver, and use it with an INDI-compatible client. */ /** \file tutorial_two.c \brief Implement a simple telescope simulator using more complex INDI concepts. \author Jasem Mutlaq */ /* Standard headers */ #include #include #include #include #include #include /* INDI Core headers */ /* indidevapi.h contains API declerations */ #include "indidevapi.h" /* INDI Eventloop mechanism */ #include "eventloop.h" /* INDI Common Routines */ #include "indicom.h" /* Definitions */ #define mydev "Telescope Simulator" /* Device name */ #define MAIN_GROUP "Main Control" /* Group name */ #define SLEWRATE 1 /* slew rate, degrees/s */ #define POLLMS 250 /* poll period, ms */ #define SIDRATE 0.004178 /* sidereal rate, degrees/s */ /* Function protptypes */ static void connectTelescope (void); static void mountSim (void *); /* operational info */ static double targetRA; static double targetDEC; /* main connection switch Note that the switch will appear to the user as On and Off (versus Connect and Disconnect in tutorial one) Nevertheless, the members _names_ are still CONNECT and DISCONNECT and therefore this is a perfectly legal standard property decleration */ static ISwitch connectS[] = { {"CONNECT", "On", ISS_OFF, 0, 0}, {"DISCONNECT", "Off", ISS_ON, 0, 0}}; static ISwitchVectorProperty connectSP = { mydev, "CONNECTION", "Connection", MAIN_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, connectS, NARRAY(connectS), "", 0 }; /* Equatorial position. EQUATORIAL_COORD is one of INDI's reserved Standard Properties */ static INumber eqN[] = { /* 1st member is Right ascension */ {"RA" /* 1st Number name */ ,"RA H:M:S" /* Number label */ , "%10.6m" /* Format. Refer to the indiapi.h for details on number formats */ ,0. /* Minimum value */ , 24. /* Maximum value */ , 0. /* Steps */ , 0. /* Initial value */ , 0 /* Pointer to parent, we don't use it, so set it to 0 */ , 0 /* Auxiluary member, set it to 0 */ , 0}, /* Autxiluar member, set it to 0 */ /* 2nd member is Declination */ {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0} }; static INumberVectorProperty eqNP = { mydev, "EQUATORIAL_EOD_COORD", "Equatorial JNow", MAIN_GROUP , IP_RW, 0, IPS_IDLE, eqN, NARRAY(eqN), "", 0}; /* Property naming convention. All property names are lower case with a postfix to indicate their type. connectS is a switch, * connectSP is a switch vector. eqN is a number, eqNP is a number property, and so on. While this is not strictly required, it makes the code easier to read. */ #define currentRA eqN[0].value /* scope's current simulated RA, rads. Handy macro to right ascension from eqN[] */ #define currentDec eqN[1].value /* scope's current simulated Dec, rads. Handy macro to declination from eqN[] */ /* Initlization routine */ static void mountInit() { static int inited; /* set once mountInit is called */ if (inited) return; /* start timer to simulate mount motion The timer will call function mountSim after POLLMS milliseconds */ IEAddTimer (POLLMS, mountSim, NULL); inited = 1; } /* send client definitions of all properties */ void ISGetProperties (const char *dev) { if (dev && strcmp (mydev, dev)) return; IDDefSwitch (&connectSP, NULL); IDDefNumber (&eqNP, NULL); } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { return; } /* client is sending us a new value for a Numeric vector property */ void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { /* Make sure to initalize */ mountInit(); /* ignore if not ours */ if (strcmp (dev, mydev)) return; if (!strcmp (name, eqNP.name)) { /* new equatorial target coords */ double newra = 0, newdec = 0; int i, nset; /* Check connectSP, if it is idle, then return */ if (connectSP.s == IPS_IDLE) { eqNP.s = IPS_IDLE; IDSetNumber(&eqNP, "Telescope is offline."); return; } for (nset = i = 0; i < n; i++) { /* Find numbers with the passed names in the eqNP property */ INumber *eqp = IUFindNumber (&eqNP, names[i]); /* If the number found is Right ascension (eqN[0]) then process it */ if (eqp == &eqN[0]) { newra = (values[i]); nset += newra >= 0 && newra <= 24; } /* Otherwise, if the number found is Declination (eqN[1]) then process it */ else if (eqp == &eqN[1]) { newdec = (values[i]); nset += newdec >= -90 && newdec <= 90; } } /* end for */ /* Did we process the two numbers? */ if (nset == 2) { char r[32], d[32]; /* Set the mount state to BUSY */ eqNP.s = IPS_BUSY; /* Set the new target coordinates */ targetRA = newra; targetDEC = newdec; /* Convert the numeric coordinates to a sexagesmal string (H:M:S) */ fs_sexa (r, targetRA, 2, 3600); fs_sexa (d, targetDEC, 3, 3600); IDSetNumber(&eqNP, "Moving to RA Dec %s %s", r, d); } /* We didn't process the two number correctly, report an error */ else { /* Set property state to idle */ eqNP.s = IPS_IDLE; IDSetNumber(&eqNP, "RA or Dec absent or bogus."); } return; } } /* client is sending us a new value for a Switch property */ void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { ISwitch *sp; mountInit(); /* ignore if not ours */ if (strcmp (dev, mydev)) return; if (!strcmp(name, connectSP.name)) { /* We update switches. This is different from the way we used to update switches in tutorial 1. This is * to illustrate that there are several ways to update the switches. Here, we try to find the switch with names[0], * and if found, we update its state to states[0] and call connectTelescope(). We must call IUResetSwitches to erase any previous history */ sp = IUFindSwitch (&connectSP, names[0]); if (sp) { IUResetSwitches(&connectSP); sp->s = states[0]; connectTelescope(); } } } /* update the "mount" over time */ void mountSim (void *p) { static struct timeval ltv; struct timeval tv; double dt, da, dx; int nlocked; /* If telescope is not on, do not simulate */ if (connectSP.s == IPS_IDLE) { IEAddTimer (POLLMS, mountSim, NULL); return; } /* update elapsed time since last poll, don't presume exactly POLLMS */ gettimeofday (&tv, NULL); if (ltv.tv_sec == 0 && ltv.tv_usec == 0) ltv = tv; dt = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec)/1e6; ltv = tv; da = SLEWRATE*dt; /* Process per current state. We check the state of EQUATORIAL_COORDS and act acoordingly */ switch (eqNP.s) { /* #1 State is idle, update telesocpe at sidereal rate */ case IPS_IDLE: /* RA moves at sidereal, Dec stands still */ currentRA += (SIDRATE*dt/15.); IDSetNumber(&eqNP, NULL); break; case IPS_BUSY: /* slewing - nail it when both within one pulse @ SLEWRATE */ nlocked = 0; dx = targetRA - currentRA; if (fabs(dx) <= da) { currentRA = targetRA; nlocked++; } else if (dx > 0) currentRA += da/15.; else currentRA -= da/15.; dx = targetDEC - currentDec; if (fabs(dx) <= da) { currentDec = targetDEC; nlocked++; } else if (dx > 0) currentDec += da; else currentDec -= da; if (nlocked == 2) { eqNP.s = IPS_OK; IDSetNumber(&eqNP, "Now tracking"); } else IDSetNumber(&eqNP, NULL); break; case IPS_OK: /* tracking */ IDSetNumber(&eqNP, NULL); break; case IPS_ALERT: break; } /* again */ IEAddTimer (POLLMS, mountSim, NULL); } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n) { } static void connectTelescope () { if (connectS[0].s == ISS_ON) { connectSP.s = IPS_OK; IDSetSwitch (&connectSP, "Telescope is connected."); } else { connectSP.s = IPS_IDLE; IDSetSwitch (&connectSP, "Telescope is disconnected."); } } indi-0.5/src/Makefile.am0000644000175000017500000000752310605175713012750 0ustar jrjr AM_CPPFLAGS = @CPPFLAGS@ -DTOP_DATADIR=\"$(pkgdatadir)\" if LINUX if !HAVE_LIBSBIGUDRV lib_LTLIBRARIES = libsbigudrv.la libsbigudrv_la_LIBADD = -lm libsbigudrv_la_SOURCES = sbig_dummy.cpp endif bin_add = sbigccd apogee_ppi v4ldriver v4lphilips meade_lpi fliccd fliwheel flipdf endif bin_PROGRAMS = indiserver lx200basic lx200generic celestrongps temma skycommander intelliscope robofocus orionatlas trutechwheel stv $(bin_add) liblilxml_a_SOURCES = lilxml.c libindicom_a_SOURCES = indicom.c base64.c observer.c noinst_LIBRARIES = liblilxml.a libindicom.a indiserver_SOURCES = indiserver.c fq.c indiserver_LDADD = liblilxml.a $(LIBSOCKET) lx200generic_SOURCES = indidrivermain.c base64.c eventloop.c lx200driver.c lx200autostar.cpp lx200_16.cpp lx200gps.cpp lx200generic.cpp lx200classic.cpp lx200generic_LDADD = liblilxml.a libindicom.a -lm lx200basic_SOURCES = indidrivermain.c base64.c eventloop.c lx200driver.c lx200basic.cpp lx200basic_LDADD = liblilxml.a libindicom.a celestrongps_SOURCES = indidrivermain.c base64.c eventloop.c celestronprotocol.c celestrongps.cpp celestrongps_LDADD = liblilxml.a libindicom.a -lm robofocus_SOURCES = indidrivermain.c base64.c eventloop.c lx200driver.c robofocusdriver.c robofocus.c robofocus_LDADD = liblilxml.a libindicom.a -lm fliccd_SOURCES = eventloop.c base64.c fli_ccd.c indidrivermain.c fliccd_LDADD = fli/libfli.la libindicom.a liblilxml.a @LIBCFITSIO@ -lm -lz $(LIBSOCKET) fliwheel_SOURCES = eventloop.c base64.c fli_wheel.c indidrivermain.c fliwheel_LDADD = fli/libfli.la libindicom.a liblilxml.a -lm flipdf_SOURCES = eventloop.c base64.c fli_pdf.c indidrivermain.c flipdf_LDADD = fli/libfli.la libindicom.a liblilxml.a -lm trutechwheel_SOURCES = eventloop.c base64.c trutech_wheel.c indidrivermain.c trutechwheel_LDADD = libindicom.a liblilxml.a -lm stv_SOURCES = eventloop.c base64.c indidrivermain.c stv.cpp stvdriver.c stv_LDADD = libindicom.a liblilxml.a @LIBCFITSIO@ -lm -lz v4ldriver_SOURCES = eventloop.c base64.c indidrivermain.c v4ldriver.cpp indi_v4l.cpp v4ldriver_LDADD = libindicom.a liblilxml.a webcam/libwebcam.la @LIBCFITSIO@ -lm -lz v4lphilips_SOURCES = eventloop.c base64.c indidrivermain.c v4ldriver.cpp v4lphilips.cpp indi_philips.cpp v4lphilips_LDADD = libindicom.a liblilxml.a webcam/libwebcam.la @LIBCFITSIO@ -lm -lz meade_lpi_SOURCES = eventloop.c base64.c indidrivermain.c v4ldriver.cpp indi_lpi.cpp meade_lpi_LDADD = libindicom.a liblilxml.a webcam/libwebcam.la @LIBCFITSIO@ -lz temma_SOURCES = indidrivermain.c base64.c eventloop.c temmadriver.c temma_LDADD = liblilxml.a libindicom.a -lm skycommander_SOURCES = indidrivermain.c base64.c eventloop.c lx200driver.c skycommander.c skycommander_LDADD = liblilxml.a libindicom.a -lm intelliscope_SOURCES = indidrivermain.c base64.c eventloop.c lx200driver.c intelliscope.c intelliscope_LDADD = liblilxml.a libindicom.a -lm orionatlas_SOURCES = indidrivermain.c base64.c eventloop.c orionatlas.cpp orionatlas_LDADD = liblilxml.a libindicom.a -lm apogee_ppi_SOURCES = apogee_ppi.cpp base64.c eventloop.c indidrivermain.c apogee_ppi_LDADD = libindicom.a liblilxml.a apogee/libapogee_PPI.la -lz sbigccd_SOURCES = sbigcam.cpp base64.c eventloop.c indidrivermain.c sbigccd_LDADD = libindicom.a liblilxml.a @LIBCFITSIO@ @LIBSBIGUDRV@ -lz pkgdata_DATA = apogee_caminfo.xml install-exec-hook: $(mkinstalldirs) $(DESTDIR)$(bindir) rm -f $(DESTDIR)$(bindir)/lx200classic $(LN_S) lx200generic $(DESTDIR)$(bindir)/lx200classic rm -f $(DESTDIR)$(bindir)/lx200autostar $(LN_S) lx200generic $(DESTDIR)$(bindir)/lx200autostar rm -f $(DESTDIR)$(bindir)/lx200_16 $(LN_S) lx200generic $(DESTDIR)$(bindir)/lx200_16 rm -f $(DESTDIR)$(bindir)/lx200gps $(LN_S) lx200generic $(DESTDIR)$(bindir)/lx200gps uninstall-local: rm $(DESTDIR)$(bindir)/lx200autostar $(DESTDIR)$(bindir)/lx200_16 $(DESTDIR)$(bindir)/lx200gps if LINUX SUBDIRS = @EXTRA_SUBDIR@ fli webcam apogee endif indi-0.5/src/eventloop.h0000644000175000017500000000627010610474336013075 0ustar jrjr#if 0 INDI Copyright (C) 2003 Elwood C. Downey This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #ifndef EVENT_LOOP_H #define EVENT_LOOP_H /** \file eventloop.h \brief Public interface to INDI's eventloop mechanism. \author Elwood C. Downey */ /* signature of a callback, workproc and timer function */ /** \typedef CBF \brief Signature of a callback function. */ typedef void (CBF) (int fd, void *); /** \typedef WPF \brief Signature of a work procedure function. */ typedef void (WPF) (void *); /** \typedef TCF \brief Signature of a timer function. */ typedef void (TCF) (void *); #ifdef __cplusplus extern "C" { #endif /** \fn void eventLoop(void) \brief Main calls this when ready to hand over control. */ extern void eventLoop(void); /** Register a new callback, \e fp, to be called with \e ud as argument when \e fd is ready. * * \param fd file descriptor. * \param fp a pointer to the callback function. * \param ud a pointer to be passed to the callback function when called. * \return a unique callback id for use with rmCallback(). */ extern int addCallback (int fd, CBF *fp, void *ud); /** Remove a callback function. * * \param cid the callback ID returned from addCallback(). */ extern void rmCallback (int cid); /** Add a new work procedure, fp, to be called with ud when nothing else to do. * * \param fp a pointer to the work procedure callback function. * \param ud a pointer to be passed to the callback function when called. * \return a unique id for use with rmWorkProc(). */ extern int addWorkProc (WPF *fp, void *ud); /** Remove the work procedure with the given \e id, as returned from addWorkProc(). * * \param wid the work procedure callback ID returned from addWorkProc(). */ extern void rmWorkProc (int wid); /** Register a new timer function, \e fp, to be called with \e ud as argument after \e ms. Add to list in order of decreasing time from epoch, ie, last entry runs soonest. The timer will only invoke the callback function \b once. You need to call addTimer again if you want to repeat the process. * * \param ms timer period in milliseconds. * \param fp a pointer to the callback function. * \param ud a pointer to be passed to the callback function when called. * \return a unique id for use with rmTimer(). */ extern int addTimer (int ms, TCF *fp, void *ud); /** Remove the timer with the given \e id, as returned from addTimer(). * * \param tid the timer callback ID returned from addTimer(). */ extern void rmTimer (int tid); #ifdef __cplusplus } #endif #endif indi-0.5/src/celestrongps.cpp0000644000175000017500000005227210610474326014127 0ustar jrjr#if 0 Celestron GPS Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include #include #include #include #include "celestronprotocol.h" #include "celestrongps.h" #define mydev "Celestron GPS" /* Enable to log debug statements #define CELESTRON_DEBUG 1 */ CelestronGPS *telescope = NULL; /* There is _one_ binary for all LX200 drivers, but each binary is renamed ** to its device name (i.e. lx200gps, lx200_16..etc). The main function will ** fetch from std args the binary name and ISInit will create the apporpiate ** device afterwards. If the binary name does not match any known devices, ** we simply create a generic device */ extern char* me; #define COMM_GROUP "Communication" #define BASIC_GROUP "Main Control" #define MOVE_GROUP "Movement Control" static void ISPoll(void *); /*INDI controls */ static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}}; static ISwitch SlewModeS[] = {{"Slew", "", ISS_ON, 0, 0}, {"Find", "", ISS_OFF, 0, 0}, {"Centering", "", ISS_OFF, 0, 0}, {"Guide", "", ISS_OFF, 0, 0}}; static ISwitch OnCoordSetS[] = {{"SLEW", "Slew", ISS_ON, 0 , 0}, {"TRACK", "Track", ISS_OFF, 0, 0}, {"SYNC", "Sync", ISS_OFF, 0, 0}}; static ISwitch abortSlewS[] = {{"ABORT", "Abort", ISS_OFF, 0, 0}}; /* equatorial position */ static INumber eq[] = { {"RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0., 0, 0, 0}, {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}, }; static INumberVectorProperty eqNum = { mydev, "EQUATORIAL_EOD_COORD", "Equatorial JNow", BASIC_GROUP, IP_RW, 0, IPS_IDLE, eq, NARRAY(eq), "", 0}; /* Tracking precision */ INumber trackingPrecisionN[] = { {"TrackRA", "RA (arcmin)", "%10.6m", 0., 60., 1., 3.0, 0, 0, 0}, {"TrackDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0, 0, 0, 0}, }; static INumberVectorProperty trackingPrecisionNP = {mydev, "Tracking Precision", "", MOVE_GROUP, IP_RW, 0, IPS_IDLE, trackingPrecisionN, NARRAY(trackingPrecisionN), "", 0}; /* Slew precision */ INumber slewPrecisionN[] = { {"SlewRA", "RA (arcmin)", "%10.6m", 0., 60., 1., 3.0, 0, 0, 0}, {"SlewDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0, 0, 0, 0}, }; static INumberVectorProperty slewPrecisionNP = {mydev, "Slew Precision", "", MOVE_GROUP, IP_RW, 0, IPS_IDLE, slewPrecisionN, NARRAY(slewPrecisionN), "", 0}; /* Fundamental group */ static ISwitchVectorProperty PowerSw = { mydev, "CONNECTION" , "Connection", COMM_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0}; static IText PortT[] = {{"PORT", "Port", 0, 0, 0, 0}}; static ITextVectorProperty Port = { mydev, "DEVICE_PORT", "Ports", COMM_GROUP, IP_RW, 0, IPS_IDLE, PortT, NARRAY(PortT), "", 0}; /* Movement group */ static ISwitchVectorProperty OnCoordSetSw = { mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, OnCoordSetS, NARRAY(OnCoordSetS), "", 0}; static ISwitchVectorProperty abortSlewSw = { mydev, "ABORT_MOTION", "Abort Slew/Track", BASIC_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE, abortSlewS, NARRAY(abortSlewS), "", 0}; static ISwitchVectorProperty SlewModeSw = { mydev, "Slew rate", "", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, SlewModeS, NARRAY(SlewModeS), "", 0}; /* Movement (Arrow keys on handset). North/South */ static ISwitch MovementNSS[] = {{"N", "North", ISS_OFF, 0, 0}, {"S", "South", ISS_OFF, 0, 0}}; static ISwitchVectorProperty MovementNSSP = { mydev, "MOVEMENT_NS", "North/South", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, MovementNSS, NARRAY(MovementNSS), "", 0}; /* Movement (Arrow keys on handset). West/East */ static ISwitch MovementWES[] = {{"W", "West", ISS_OFF, 0, 0}, {"E", "East", ISS_OFF, 0, 0}}; static ISwitchVectorProperty MovementWESP = { mydev, "MOVEMENT_WE", "West/East", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, MovementWES, NARRAY(MovementWES), "", 0}; /* send client definitions of all properties */ void ISInit() { static int isInit=0; if (isInit) return; isInit = 1; PortT[0].text = strcpy(new char[32], "/dev/ttyS0"); telescope = new CelestronGPS(); IEAddTimer (POLLMS, ISPoll, NULL); } void ISGetProperties (const char *dev) { ISInit(); telescope->ISGetProperties(dev);} void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { ISInit(); telescope->ISNewSwitch(dev, name, states, names, n);} void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { ISInit(); telescope->ISNewText(dev, name, texts, names, n);} void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { ISInit(); telescope->ISNewNumber(dev, name, values, names, n);} void ISPoll (void *p) { telescope->ISPoll(); IEAddTimer (POLLMS, ISPoll, NULL); p=p;} void ISNewBLOB (const char */*dev*/, const char */*name*/, int */*sizes[]*/, char **/*blobs[]*/, char **/*formats[]*/, char **/*names[]*/, int /*n*/) {} /************************************************** *** LX200 Generic Implementation ***************************************************/ CelestronGPS::CelestronGPS() { targetRA = lastRA = 0; targetDEC = lastDEC = 0; currentSet = 0; lastSet = -1; JD = 0; // Children call parent routines, this is the default IDLog("initilizaing from Celeston GPS device...\n"); } void CelestronGPS::ISGetProperties(const char *dev) { if (dev && strcmp (mydev, dev)) return; // COMM_GROUP IDDefSwitch (&PowerSw, NULL); IDDefText (&Port, NULL); // BASIC_GROUP IDDefNumber (&eqNum, NULL); IDDefSwitch (&OnCoordSetSw, NULL); IDDefSwitch (&abortSlewSw, NULL); IDDefSwitch (&SlewModeSw, NULL); // Movement group IDDefSwitch (&MovementNSSP, NULL); IDDefSwitch (&MovementWESP, NULL); IDDefNumber (&trackingPrecisionNP, NULL); IDDefNumber (&slewPrecisionNP, NULL); /* Send the basic data to the new client if the previous client(s) are already connected. */ if (PowerSw.s == IPS_OK) getBasicData(); } void CelestronGPS::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { IText *tp; // suppress warning n=n; // ignore if not ours // if (strcmp (dev, mydev)) return; if (!strcmp(name, Port.name) ) { Port.s = IPS_OK; tp = IUFindText( &Port, names[0] ); if (!tp) return; tp->text = new char[strlen(texts[0])+1]; strcpy(tp->text, texts[0]); IDSetText (&Port, NULL); return; } } int CelestronGPS::handleCoordSet() { int i=0; char RAStr[32], DecStr[32]; switch (currentSet) { // Slew case 0: lastSet = 0; if (eqNum.s == IPS_BUSY) { StopNSEW(); // sleep for 500 mseconds usleep(500000); } if ((i = SlewToCoords(targetRA, targetDEC))) { slewError(i); return (-1); } eqNum.s = IPS_BUSY; fs_sexa(RAStr, targetRA, 2, 3600); fs_sexa(DecStr, targetDEC, 2, 3600); IDSetNumber(&eqNum, "Slewing to JNOW RA %s - DEC %s", RAStr, DecStr); IDLog("Slewing to JNOW RA %s - DEC %s", RAStr, DecStr); break; // Track case 1: if (eqNum.s == IPS_BUSY) { StopNSEW(); // sleep for 500 mseconds usleep(500000); } if ( (fabs ( targetRA - currentRA ) >= (trackingPrecisionN[0].value/(15.0*60.0))) || (fabs (targetDEC - currentDEC) >= (trackingPrecisionN[1].value)/60.0)) { #ifdef CELESTRON_DEBUG IDLog("Exceeded Tracking threshold, will attempt to slew to the new target.\n"); IDLog("targetRA is %g, currentRA is %g\n", targetRA, currentRA); IDLog("targetDEC is %g, currentDEC is %g\n*************************\n", targetDEC, currentDEC); #endif if (( i = SlewToCoords(targetRA, targetDEC))) { slewError(i); return (-1); } fs_sexa(RAStr, targetRA, 2, 3600); fs_sexa(DecStr, targetDEC, 2, 3600); eqNum.s = IPS_BUSY; IDSetNumber(&eqNum, "Slewing to JNow RA %s - DEC %s", RAStr, DecStr); IDLog("Slewing to JNOW RA %s - DEC %s", RAStr, DecStr); } else { #ifdef CELESTRON_DEBUG IDLog("Tracking called, but tracking threshold not reached yet.\n"); #endif eqNum.s = IPS_OK; eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; if (lastSet != 1) IDSetNumber(&eqNum, "Tracking..."); else IDSetNumber(&eqNum, NULL); } lastSet = 1; break; // Sync case 2: lastSet = 2; OnCoordSetSw.s = IPS_OK; SyncToCoords(targetRA, targetDEC); eqNum.s = IPS_OK; IDSetNumber(&eqNum, "Synchronization successful."); break; } return (0); } void CelestronGPS::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { double newRA=0, newDEC=0; // ignore if not ours // if (strcmp (dev, mydev)) return; struct tm *tp; time_t t; time (&t); tp = gmtime (&t); if (!strcmp (name, trackingPrecisionNP.name)) { if (!IUUpdateNumbers(&trackingPrecisionNP, values, names, n)) { trackingPrecisionNP.s = IPS_OK; IDSetNumber(&trackingPrecisionNP, NULL); return; } trackingPrecisionNP.s = IPS_ALERT; IDSetNumber(&trackingPrecisionNP, "unknown error while setting tracking precision"); return; } if (!strcmp(name, slewPrecisionNP.name)) { IUUpdateNumbers(&slewPrecisionNP, values, names, n); { slewPrecisionNP.s = IPS_OK; IDSetNumber(&slewPrecisionNP, NULL); return; } slewPrecisionNP.s = IPS_ALERT; IDSetNumber(&slewPrecisionNP, "unknown error while setting slew precision"); return; } if (!strcmp (name, eqNum.name)) { int i=0, nset=0; if (checkPower(&eqNum)) return; for (nset = i = 0; i < n; i++) { INumber *eqp = IUFindNumber (&eqNum, names[i]); if (eqp == &eq[0]) { newRA = values[i]; nset += newRA >= 0 && newRA <= 24.0; } else if (eqp == &eq[1]) { newDEC = values[i]; nset += newDEC >= -90.0 && newDEC <= 90.0; } } if (nset == 2) { //eqNum.s = IPS_BUSY; tp->tm_mon += 1; tp->tm_year += 1900; // update JD JD = UTtoJD(tp); #ifdef CELESTRON_DEBUG IDLog("We recevined JNOW RA %f - DEC %f\n", newRA, newDEC);; #endif targetRA = newRA; targetDEC = newDEC; if (MovementNSSP.s == IPS_BUSY || MovementWESP.s == IPS_BUSY) { IUResetSwitches(&MovementNSSP); IUResetSwitches(&MovementWESP); MovementNSSP.s = MovementWESP.s = IPS_IDLE; IDSetSwitch(&MovementNSSP, NULL); IDSetSwitch(&MovementWESP, NULL); } if (handleCoordSet()) { eqNum.s = IPS_IDLE; IDSetNumber(&eqNum, NULL); } } else { eqNum.s = IPS_IDLE; IDSetNumber(&eqNum, "RA or Dec missing or invalid."); } return; } } void CelestronGPS::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { int index; // Suppress warning names = names; //IDLog("in new Switch with Device= %s and Property= %s and #%d items\n", dev, name,n); //IDLog("SolarSw name is %s\n", SolarSw.name); // ignore if not ours // if (strcmp (dev, mydev)) return; // FIRST Switch ALWAYS for power if (!strcmp (name, PowerSw.name)) { if (IUUpdateSwitches(&PowerSw, states, names, n) < 0) return; connectTelescope(); return; } if (!strcmp(name, OnCoordSetSw.name)) { if (checkPower(&OnCoordSetSw)) return; if (IUUpdateSwitches(&OnCoordSetSw, states, names, n) < 0) return; currentSet = getOnSwitch(&OnCoordSetSw); } // Abort Slew if (!strcmp (name, abortSlewSw.name)) { if (checkPower(&abortSlewSw)) { abortSlewSw.s = IPS_IDLE; IDSetSwitch(&abortSlewSw, NULL); return; } IUResetSwitches(&abortSlewSw); StopNSEW(); if (eqNum.s == IPS_BUSY) { abortSlewSw.s = IPS_OK; eqNum.s = IPS_IDLE; IDSetSwitch(&abortSlewSw, "Slew aborted."); IDSetNumber(&eqNum, NULL); } else if (MovementNSSP.s == IPS_BUSY || MovementWESP.s == IPS_BUSY) { MovementNSSP.s = MovementWESP.s = IPS_IDLE; abortSlewSw.s = IPS_OK; eqNum.s = IPS_IDLE; IUResetSwitches(&MovementNSSP); IUResetSwitches(&MovementWESP); IUResetSwitches(&abortSlewSw); IDSetSwitch(&abortSlewSw, "Slew aborted."); IDSetSwitch(&MovementNSSP, NULL); IDSetSwitch(&MovementWESP, NULL); IDSetNumber(&eqNum, NULL); } else { abortSlewSw.s = IPS_IDLE; IDSetSwitch(&abortSlewSw, NULL); } return; } // Slew mode if (!strcmp (name, SlewModeSw.name)) { if (checkPower(&SlewModeSw)) return; IUResetSwitches(&SlewModeSw); IUUpdateSwitches(&SlewModeSw, states, names, n); index = getOnSwitch(&SlewModeSw); SetRate(index); SlewModeSw.s = IPS_OK; IDSetSwitch(&SlewModeSw, NULL); return; } // Movement (North/South) if (!strcmp (name, MovementNSSP.name)) { if (checkPower(&MovementNSSP)) return; int last_move=-1; int current_move = -1; // -1 means all off previously last_move = getOnSwitch(&MovementNSSP); if (IUUpdateSwitches(&MovementNSSP, states, names, n) < 0) return; current_move = getOnSwitch(&SlewModeSw); // Previosuly active switch clicked again, so let's stop. if (current_move == last_move) { StopSlew((current_move == 0) ? NORTH : SOUTH); IUResetSwitches(&MovementNSSP); MovementNSSP.s = IPS_IDLE; IDSetSwitch(&MovementNSSP, NULL); return; } #ifdef CELESTRON_DEBUG IDLog("Current Move: %d - Previous Move: %d\n", current_move, last_move); #endif // 0 (North) or 1 (South) last_move = current_move; // Correction for Celestron Driver: North 0 - South 3 current_move = (current_move == 0) ? NORTH : SOUTH; StartSlew(current_move); MovementNSSP.s = IPS_BUSY; IDSetSwitch(&MovementNSSP, "Moving toward %s", (current_move == NORTH) ? "North" : "South"); return; } // Movement (West/East) if (!strcmp (name, MovementWESP.name)) { if (checkPower(&MovementWESP)) return; int last_move=-1; int current_move = -1; // -1 means all off previously last_move = getOnSwitch(&MovementWESP); if (IUUpdateSwitches(&MovementWESP, states, names, n) < 0) return; current_move = getOnSwitch(&SlewModeSw); // Previosuly active switch clicked again, so let's stop. if (current_move == last_move) { StopSlew((current_move ==0) ? WEST : EAST); IUResetSwitches(&MovementWESP); MovementWESP.s = IPS_IDLE; IDSetSwitch(&MovementWESP, NULL); return; } #ifdef CELESTRON_DEBUG IDLog("Current Move: %d - Previous Move: %d\n", current_move, last_move); #endif // 0 (West) or 1 (East) last_move = current_move; // Correction for Celestron Driver: West 1 - East 2 current_move = (current_move == 0) ? WEST : EAST; StartSlew(current_move); MovementWESP.s = IPS_BUSY; IDSetSwitch(&MovementWESP, "Moving toward %s", (current_move == WEST) ? "West" : "East"); return; } } int CelestronGPS::getOnSwitch(ISwitchVectorProperty *sp) { for (int i=0; i < sp->nsp ; i++) if (sp->sp[i].s == ISS_ON) return i; return -1; } int CelestronGPS::checkPower(ISwitchVectorProperty *sp) { if (PowerSw.s != IPS_OK) { if (!strcmp(sp->label, "")) IDMessage (mydev, "Cannot change property %s while the telescope is offline.", sp->name); else IDMessage (mydev, "Cannot change property %s while the telescope is offline.", sp->label); sp->s = IPS_IDLE; IDSetSwitch(sp, NULL); return -1; } return 0; } int CelestronGPS::checkPower(INumberVectorProperty *np) { if (PowerSw.s != IPS_OK) { if (!strcmp(np->label, "")) IDMessage (mydev, "Cannot change property %s while the telescope is offline.", np->name); else IDMessage (mydev, "Cannot change property %s while the telescope is offline.", np->label); np->s = IPS_IDLE; IDSetNumber(np, NULL); return -1; } return 0; } int CelestronGPS::checkPower(ITextVectorProperty *tp) { if (PowerSw.s != IPS_OK) { if (!strcmp(tp->label, "")) IDMessage (mydev, "Cannot change property %s while the telescope is offline.", tp->name); else IDMessage (mydev, "Cannot change property %s while the telescope is offline.", tp->label); tp->s = IPS_IDLE; IDSetText(tp, NULL); return -1; } return 0; } void CelestronGPS::ISPoll() { double dx, dy; double currentRA, currentDEC; int status; switch (eqNum.s) { case IPS_IDLE: if (PowerSw.s != IPS_OK) break; currentRA = GetRA(); currentDEC = GetDec(); if ( fabs (currentRA - lastRA) > 0.01 || fabs (currentDEC - lastDEC) > 0.01) { eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; lastRA = currentRA; lastDEC = currentDEC; IDSetNumber (&eqNum, NULL); } break; case IPS_BUSY: currentRA = GetRA(); currentDEC = GetDec(); dx = targetRA - currentRA; dy = targetDEC - currentDEC; #ifdef CELESTRON_DEBUG IDLog("targetRA is %f, currentRA is %f\n", (float) targetRA, (float) currentRA); IDLog("targetDEC is %f, currentDEC is %f\n****************************\n", (float) targetDEC, (float) currentDEC); #endif eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; status = CheckCoords(targetRA, targetDEC, slewPrecisionN[0].value/(15.0*60.0) , slewPrecisionN[1].value/60.0); // Wait until acknowledged or within 3.6', change as desired. switch (status) { case 0: /* goto in progress */ IDSetNumber (&eqNum, NULL); break; case 1: /* goto complete within tolerance */ case 2: /* goto complete but outside tolerance */ currentRA = targetRA; currentDEC = targetDEC; /*apparentCoord( JD, (double) J2000, ¤tRA, ¤tDEC);*/ eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; eqNum.s = IPS_OK; if (currentSet == 0) { IUResetSwitches(&OnCoordSetSw); OnCoordSetSw.sp[0].s = ISS_ON; IDSetNumber (&eqNum, "Slew is complete"); } else { IUResetSwitches(&OnCoordSetSw); OnCoordSetSw.sp[1].s = ISS_ON; IDSetNumber (&eqNum, "Slew is complete. Tracking..."); } IDSetSwitch (&OnCoordSetSw, NULL); break; } break; case IPS_OK: if (PowerSw.s != IPS_OK) break; currentRA = GetRA(); currentDEC = GetDec(); if ( fabs (currentRA - lastRA) > 0.01 || fabs (currentDEC - lastDEC) > 0.01) { eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; lastRA = currentRA; lastDEC = currentDEC; IDSetNumber (&eqNum, NULL); } break; case IPS_ALERT: break; } switch (MovementNSSP.s) { case IPS_IDLE: break; case IPS_BUSY: currentRA = GetRA(); currentDEC = GetDec(); eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; IDSetNumber (&eqNum, NULL); break; case IPS_OK: break; case IPS_ALERT: break; } switch (MovementWESP.s) { case IPS_IDLE: break; case IPS_BUSY: currentRA = GetRA(); currentDEC = GetDec(); eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; IDSetNumber (&eqNum, NULL); break; case IPS_OK: break; case IPS_ALERT: break; } } void CelestronGPS::getBasicData() { targetRA = GetRA(); targetDEC = GetDec(); eqNum.np[0].value = targetRA; eqNum.np[1].value = targetDEC; IDSetNumber(&eqNum, NULL); } void CelestronGPS::connectTelescope() { switch (PowerSw.sp[0].s) { case ISS_ON: if (ConnectTel(Port.tp[0].text) < 0) { PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch (&PowerSw, "Error connecting to port %s. Make sure you have BOTH write and read permission to the port.", Port.tp[0].text); return; } PowerSw.s = IPS_OK; IDSetSwitch (&PowerSw, "Telescope is online. Retrieving basic data..."); getBasicData(); break; case ISS_OFF: IDSetSwitch (&PowerSw, "Telescope is offline."); IDLog("Telescope is offline."); DisconnectTel(); break; } } void CelestronGPS::slewError(int slewCode) { eqNum.s = IPS_IDLE; switch (slewCode) { case 1: IDSetNumber (&eqNum, "Invalid newDec in SlewToCoords"); break; case 2: IDSetNumber (&eqNum, "RA count overflow in SlewToCoords"); break; case 3: IDSetNumber (&eqNum, "Dec count overflow in SlewToCoords"); break; case 4: IDSetNumber (&eqNum, "No acknowledgment from telescope after SlewToCoords"); break; default: IDSetNumber (&eqNum, "Unknown error"); break; } } indi-0.5/src/lx200driver.c0000644000175000017500000010435310610514037013130 0ustar jrjr#if 0 LX200 Driver Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include #include #include #include #include #include #include "indicom.h" #include "indidevapi.h" #include "lx200driver.h" #ifndef _WIN32 #include #endif #define LX200_TIMEOUT 5 /* FD timeout in seconds */ int controller_format; /************************************************************************** Diagnostics **************************************************************************/ char ACK(int fd); /*int testTelescope(void); int testAP(void);*/ int check_lx200_connection(int fd); /************************************************************************** Get Commands: store data in the supplied buffer. Return 0 on success or -1 on failure **************************************************************************/ /* Get Double from Sexagisemal */ int getCommandSexa(int fd, double *value, const char *cmd); /* Get String */ int getCommandString(int fd, char *data, const char* cmd); /* Get Int */ int getCommandInt(int fd, int *value, const char* cmd); /* Get tracking frequency */ int getTrackFreq(int fd, double * value); /* Get site Latitude */ int getSiteLatitude(int fd, int *dd, int *mm); /* Get site Longitude */ int getSiteLongitude(int fd, int *ddd, int *mm); /* Get Calender data */ int getCalenderDate(int fd, char *date); /* Get site Name */ int getSiteName(int fd, char *siteName, int siteNum); /* Get Number of Bars */ int getNumberOfBars(int fd, int *value); /* Get Home Search Status */ int getHomeSearchStatus(int fd, int *status); /* Get OTA Temperature */ int getOTATemp(int fd, double * value); /* Get time format: 12 or 24 */ int getTimeFormat(int fd, int *format); /************************************************************************** Set Commands **************************************************************************/ /* Set Int */ int setCommandInt(int fd, int data, const char *cmd); /* Set Sexigesimal */ int setCommandXYZ(int fd, int x, int y, int z, const char *cmd); /* Common routine for Set commands */ int setStandardProcedure(int fd, char * writeData); /* Set Slew Mode */ int setSlewMode(int fd, int slewMode); /* Set Alignment mode */ int setAlignmentMode(int fd, unsigned int alignMode); /* Set Object RA */ int setObjectRA(int fd, double ra); /* set Object DEC */ int setObjectDEC(int fd, double dec); /* Set Calender date */ int setCalenderDate(int fd, int dd, int mm, int yy); /* Set UTC offset */ int setUTCOffset(int fd, double hours); /* Set Track Freq */ int setTrackFreq(int fd, double trackF); /* Set current site longitude */ int setSiteLongitude(int fd, double Long); /* Set current site latitude */ int setSiteLatitude(int fd, double Lat); /* Set Object Azimuth */ int setObjAz(int fd, double az); /* Set Object Altitude */ int setObjAlt(int fd, double alt); /* Set site name */ int setSiteName(int fd, char * siteName, int siteNum); /* Set maximum slew rate */ int setMaxSlewRate(int fd, int slewRate); /* Set focuser motion */ int setFocuserMotion(int fd, int motionType); /* Set focuser speed mode */ int setFocuserSpeedMode (int fd, int speedMode); /* Set minimum elevation limit */ int setMinElevationLimit(int fd, int min); /* Set maximum elevation limit */ int setMaxElevationLimit(int fd, int max); /************************************************************************** Motion Commands **************************************************************************/ /* Slew to the selected coordinates */ int Slew(int fd); /* Synchronize to the selected coordinates and return the matching object if any */ int Sync(int fd, char *matchedObject); /* Abort slew in all axes */ int abortSlew(int fd); /* Move into one direction, two valid directions can be stacked */ int MoveTo(int fd, int direction); /* Half movement in a particular direction */ int HaltMovement(int fd, int direction); /* Select the tracking mode */ int selectTrackingMode(int fd, int trackMode); /* Select Astro-Physics tracking mode */ int selectAPTrackingMode(int fd, int trackMode); /************************************************************************** Other Commands **************************************************************************/ /* Ensures LX200 RA/DEC format is long */ int checkLX200Format(int fd); /* Select a site from the LX200 controller */ int selectSite(int fd, int siteNum); /* Select a catalog object */ int selectCatalogObject(int fd, int catalog, int NNNN); /* Select a sub catalog */ int selectSubCatalog(int fd, int catalog, int subCatalog); int check_lx200_connection(int in_fd) { int i=0; char ack[1] = { (char) 0x06 }; char MountAlign[64]; int nbytes_read=0; #ifdef INDI_DEBUG IDLog("Testing telescope's connection using ACK...\n"); #endif if (in_fd <= 0) return -1; for (i=0; i < 2; i++) { if (write(in_fd, ack, 1) < 0) return -1; tty_read(in_fd, MountAlign, 1, LX200_TIMEOUT, &nbytes_read); if (nbytes_read == 1) return 0; usleep(50000); } return -1; } /********************************************************************** * GET **********************************************************************/ char ACK(int fd) { char ack[1] = { (char) 0x06 }; char MountAlign[2]; int nbytes_write=0, nbytes_read=0, error_type; nbytes_write = write(fd, ack, 1); if (nbytes_write < 0) return -1; /*read_ret = portRead(MountAlign, 1, LX200_TIMEOUT);*/ error_type = tty_read(fd, MountAlign, 1, LX200_TIMEOUT, &nbytes_read); if (nbytes_read == 1) return MountAlign[0]; else return error_type; } int getCommandSexa(int fd, double *value, const char * cmd) { char temp_string[16]; int error_type; int nbytes_write=0, nbytes_read=0; tcflush(fd, TCIFLUSH); if ( (error_type = tty_write_string(fd, cmd, &nbytes_write)) != TTY_OK) return error_type; /*if ( (read_ret = portRead(temp_string, -1, LX200_TIMEOUT)) < 1) return read_ret;*/ tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read); temp_string[nbytes_read - 1] = '\0'; /*IDLog("getComandSexa: %s\n", temp_string);*/ if (f_scansexa(temp_string, value)) { #ifdef INDI_DEBUG IDLog("unable to process [%s]\n", temp_string); #endif return -1; } tcflush(fd, TCIFLUSH); return 0; } int getCommandInt(int fd, int *value, const char* cmd) { char temp_string[16]; float temp_number; int error_type; int nbytes_write=0, nbytes_read=0; tcflush(fd, TCIFLUSH); if ( (error_type = tty_write_string(fd, cmd, &nbytes_write)) != TTY_OK) return error_type; tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read); temp_string[nbytes_read - 1] = '\0'; /* Float */ if (strchr(temp_string, '.')) { if (sscanf(temp_string, "%f", &temp_number) != 1) return -1; *value = (int) temp_number; } /* Int */ else if (sscanf(temp_string, "%d", value) != 1) return -1; return 0; } int getCommandString(int fd, char *data, const char* cmd) { char * term; int error_type; int nbytes_write=0, nbytes_read=0; /*if (portWrite(cmd) < 0) return -1;*/ if ( (error_type = tty_write_string(fd, cmd, &nbytes_write)) != TTY_OK) return error_type; /*read_ret = portRead(data, -1, LX200_TIMEOUT);*/ error_type = tty_read_section(fd, data, '#', LX200_TIMEOUT, &nbytes_read); tcflush(fd, TCIFLUSH); if (error_type != TTY_OK) return error_type; term = strchr (data, '#'); if (term) *term = '\0'; #ifdef INDI_DEBUG IDLog("Requested data: %s\n", data); #endif return 0; } int getCalenderDate(int fd, char *date) { int dd, mm, yy; int error_type; int nbytes_read=0; char mell_prefix[3]; if ( (error_type = getCommandString(fd, date, "#:GC#")) ) return error_type; /* Meade format is MM/DD/YY */ nbytes_read = sscanf(date, "%d%*c%d%*c%d", &mm, &dd, &yy); if (nbytes_read < 3) return -1; /* We consider years 50 or more to be in the last century, anything less in the 21st century.*/ if (yy > 50) strncpy(mell_prefix, "19", 3); else strncpy(mell_prefix, "20", 3); /* We need to have in in YYYY/MM/DD format */ snprintf(date, 16, "%s%02d/%02d/%02d", mell_prefix, yy, mm, dd); return (0); } int getTimeFormat(int fd, int *format) { char temp_string[16]; int error_type; int nbytes_write=0, nbytes_read=0; int tMode; /*if (portWrite("#:Gc#") < 0) return -1;*/ if ( (error_type = tty_write_string(fd, "#:Gc#", &nbytes_write)) != TTY_OK) return error_type; /*read_ret = portRead(temp_string, -1, LX200_TIMEOUT);*/ if ( (error_type = tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read)) != TTY_OK) return error_type; tcflush(fd, TCIFLUSH); if (nbytes_read < 1) return error_type; temp_string[nbytes_read-1] = '\0'; nbytes_read = sscanf(temp_string, "(%d)", &tMode); if (nbytes_read < 1) return -1; else *format = tMode; return 0; } int getSiteName(int fd, char *siteName, int siteNum) { char * term; int error_type; int nbytes_write=0, nbytes_read=0; switch (siteNum) { case 1: /*if (portWrite("#:GM#") < 0) return -1;*/ if ( (error_type = tty_write_string(fd, "#:GM#", &nbytes_write)) != TTY_OK) return error_type; break; case 2: /*if (portWrite("#:GN#") < 0) return -1;*/ if ( (error_type = tty_write_string(fd, "#:GN#", &nbytes_write)) != TTY_OK) return error_type; break; case 3: /*if (portWrite("#:GO#") < 0) return -1;*/ if ( (error_type = tty_write_string(fd, "#:GO#", &nbytes_write)) != TTY_OK) return error_type; break; case 4: /*if (portWrite("#:GP#") < 0) return -1;*/ if ( (error_type = tty_write_string(fd, "#:GP#", &nbytes_write)) != TTY_OK) return error_type; break; default: return -1; } /*read_ret = portRead(siteName, -1, LX200_TIMEOUT);*/ error_type = tty_read_section(fd, siteName, '#', LX200_TIMEOUT, &nbytes_read); tcflush(fd, TCIFLUSH); if (nbytes_read < 1) return error_type; siteName[nbytes_read - 1] = '\0'; term = strchr (siteName, ' '); if (term) *term = '\0'; term = strchr (siteName, '<'); if (term) strcpy(siteName, "unused site"); #ifdef INDI_DEBUG IDLog("Requested site name: %s\n", siteName); #endif return 0; } int getSiteLatitude(int fd, int *dd, int *mm) { char temp_string[16]; int error_type; int nbytes_write=0, nbytes_read=0; /*if (portWrite("#:Gt#") < 0) return -1;*/ if ( (error_type = tty_write_string(fd, "#:Gt#", &nbytes_write)) != TTY_OK) return error_type; /*read_ret = portRead(temp_string, -1, LX200_TIMEOUT);*/ error_type = tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read); tcflush(fd, TCIFLUSH); if (nbytes_read < 1) return error_type; temp_string[nbytes_read -1] = '\0'; if (sscanf (temp_string, "%d%*c%d", dd, mm) < 2) return -1; #ifdef INDI_DEBUG fprintf(stderr, "Requested site latitude in String %s\n", temp_string); fprintf(stderr, "Requested site latitude %d:%d\n", *dd, *mm); #endif return 0; } int getSiteLongitude(int fd, int *ddd, int *mm) { char temp_string[16]; int error_type; int nbytes_write=0, nbytes_read=0; if ( (error_type = tty_write_string(fd, "#:Gg#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:Gg#") < 0) return -1;*/ error_type = tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read); /*read_ret = portRead(temp_string, -1, LX200_TIMEOUT);*/ tcflush(fd, TCIFLUSH); if (nbytes_read < 1) return error_type; temp_string[nbytes_read -1] = '\0'; if (sscanf (temp_string, "%d%*c%d", ddd, mm) < 2) return -1; #ifdef INDI_DEBUG fprintf(stderr, "Requested site longitude in String %s\n", temp_string); fprintf(stderr, "Requested site longitude %d:%d\n", *ddd, *mm); #endif return 0; } int getTrackFreq(int fd, double *value) { float Freq; char temp_string[16]; int error_type; int nbytes_write=0, nbytes_read=0; if ( (error_type = tty_write_string(fd, "#:GT#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:GT#") < 0) return -1;*/ /*read_ret = portRead(temp_string, -1, LX200_TIMEOUT);*/ error_type = tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read); tcflush(fd, TCIFLUSH); if (nbytes_read < 1) return error_type; temp_string[nbytes_read] = '\0'; /*fprintf(stderr, "Telescope tracking freq str: %s\n", temp_string);*/ if (sscanf(temp_string, "%f#", &Freq) < 1) return -1; *value = (double) Freq; #ifdef INDI_DEBUG fprintf(stderr, "Tracking frequency value is %f\n", Freq); #endif return 0; } int getNumberOfBars(int fd, int *value) { char temp_string[128]; int error_type; int nbytes_write=0, nbytes_read=0; if ( (error_type = tty_write_string(fd, "#:D#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:D#") < 0) return -1;*/ error_type = tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read); tcflush(fd, TCIFLUSH); if (nbytes_read < 0) return error_type; *value = nbytes_read -1; return 0; } int getHomeSearchStatus(int fd, int *status) { char temp_string[16]; int error_type; int nbytes_write=0, nbytes_read=0; if ( (error_type = tty_write_string(fd, "#:h?#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:h?#") < 0) return -1;*/ /*read_ret = portRead(temp_string, 1, LX200_TIMEOUT);*/ error_type = tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read); tcflush(fd, TCIFLUSH); if (nbytes_read < 1) return error_type; temp_string[1] = '\0'; if (temp_string[0] == '0') *status = 0; else if (temp_string[0] == '1') *status = 1; else if (temp_string[0] == '2') *status = 1; return 0; } int getOTATemp(int fd, double *value) { char temp_string[16]; int error_type; int nbytes_write=0, nbytes_read=0; float temp; if ( (error_type = tty_write_string(fd, "#:fT#", &nbytes_write)) != TTY_OK) return error_type; error_type = tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read); if (nbytes_read < 1) return error_type; temp_string[nbytes_read - 1] = '\0'; if (sscanf(temp_string, "%f", &temp) < 1) return -1; *value = (double) temp; return 0; } int updateSkyCommanderCoord(int fd, double *ra, double *dec) { char coords[16]; char CR[1] = { (char) 0x0D }; float RA=0.0, DEC=0.0; int error_type; int nbytes_read=0; write(fd, CR, 1); error_type = tty_read(fd, coords, 16, LX200_TIMEOUT, &nbytes_read); /*read_ret = portRead(coords, 16, LX200_TIMEOUT);*/ tcflush(fd, TCIFLUSH); nbytes_read = sscanf(coords, " %g %g", &RA, &DEC); if (nbytes_read < 2) { #ifdef INDI_DEBUG IDLog("Error in Sky commander number format [%s], exiting.\n", coords); #endif return error_type; } *ra = RA; *dec = DEC; return 0; } int updateIntelliscopeCoord (int fd, double *ra, double *dec) { char coords[16]; char CR[1] = { (char) 0x51 }; /* "Q" */ float RA = 0.0, DEC = 0.0; int error_type; int nbytes_read=0; /*IDLog ("Sending a Q\n");*/ write (fd, CR, 1); /* We start at 14 bytes in case its a Sky Wizard, but read one more later it if it's a intelliscope */ /*read_ret = portRead (coords, 14, LX200_TIMEOUT);*/ error_type = tty_read(fd, coords, 14, LX200_TIMEOUT, &nbytes_read); tcflush(fd, TCIFLUSH); /*IDLog ("portRead() = [%s]\n", coords);*/ /* Remove the Q in the response from the Intelliscope but not the Sky Wizard */ if (coords[0] == 'Q') { coords[0] = ' '; /* Read one more byte if Intelliscope to get the "CR" */ error_type = tty_read(fd, coords, 1, LX200_TIMEOUT, &nbytes_read); /*read_ret = portRead (coords, 1, LX200_TIMEOUT);*/ } nbytes_read = sscanf (coords, " %g %g", &RA, &DEC); /*IDLog ("sscanf() RA = [%f]\n", RA * 0.0390625);*/ /*IDLog ("sscanf() DEC = [%f]\n", DEC * 0.0390625);*/ /*IDLog ("Intelliscope output [%s]", coords);*/ if (nbytes_read < 2) { #ifdef INDI_DEBUG IDLog ("Error in Intelliscope number format [%s], exiting.\n", coords); #endif return -1; } *ra = RA * 0.0390625; *dec = DEC * 0.0390625; return 0; } /********************************************************************** * SET **********************************************************************/ int setStandardProcedure(int fd, char * data) { char bool_return[2]; int error_type; int nbytes_write=0, nbytes_read=0; if ( (error_type = tty_write_string(fd, data, &nbytes_write)) != TTY_OK) return error_type; error_type = tty_read(fd, bool_return, 1, LX200_TIMEOUT, &nbytes_read); /*read_ret = portRead(boolRet, 1, LX200_TIMEOUT);*/ tcflush(fd, TCIFLUSH); if (nbytes_read < 1) return error_type; if (bool_return[0] == '0') { #ifdef INDI_DEBUG IDLog("%s Failed.\n", data); #endif return -1; } #ifdef INDI_DEBUG IDLog("%s Successful\n", data); #endif return 0; } int setCommandInt(int fd, int data, const char *cmd) { char temp_string[16]; int error_type; int nbytes_write=0; snprintf(temp_string, sizeof( temp_string ), "%s%d#", cmd, data); if ( (error_type = tty_write_string(fd, temp_string, &nbytes_write)) != TTY_OK) return error_type; /* if (portWrite(temp_string) < 0) return -1;*/ return 0; } int setMinElevationLimit(int fd, int min) { char temp_string[16]; snprintf(temp_string, sizeof( temp_string ), "#:Sh%02d#", min); return (setStandardProcedure(fd, temp_string)); } int setMaxElevationLimit(int fd, int max) { char temp_string[16]; snprintf(temp_string, sizeof( temp_string ), "#:So%02d*#", max); return (setStandardProcedure(fd, temp_string)); } int setMaxSlewRate(int fd, int slewRate) { char temp_string[16]; if (slewRate < 2 || slewRate > 8) return -1; snprintf(temp_string, sizeof( temp_string ), "#:Sw%d#", slewRate); return (setStandardProcedure(fd, temp_string)); } int setObjectRA(int fd, double ra) { int h, m, s, frac_m; char temp_string[16]; getSexComponents(ra, &h, &m, &s); frac_m = (s / 60.0) * 10.; if (controller_format == LX200_LONG_FORMAT) snprintf(temp_string, sizeof( temp_string ), "#:Sr %02d:%02d:%02d#", h, m, s); else snprintf(temp_string, sizeof( temp_string ), "#:Sr %02d:%02d.%01d#", h, m, frac_m); /*IDLog("Set Object RA String %s\n", temp_string);*/ return (setStandardProcedure(fd, temp_string)); } int setObjectDEC(int fd, double dec) { int d, m, s; char temp_string[16]; getSexComponents(dec, &d, &m, &s); switch(controller_format) { case LX200_SHORT_FORMAT: /* case with negative zero */ if (!d && dec < 0) snprintf(temp_string, sizeof( temp_string ), "#:Sd -%02d*%02d#", d, m); else snprintf(temp_string, sizeof( temp_string ), "#:Sd %+03d*%02d#", d, m); break; case LX200_LONG_FORMAT: /* case with negative zero */ if (!d && dec < 0) snprintf(temp_string, sizeof( temp_string ), "#:Sd -%02d:%02d:%02d#", d, m, s); else snprintf(temp_string, sizeof( temp_string ), "#:Sd %+03d:%02d:%02d#", d, m, s); break; } /*IDLog("Set Object DEC String %s\n", temp_string);*/ return (setStandardProcedure(fd, temp_string)); } int setCommandXYZ(int fd, int x, int y, int z, const char *cmd) { char temp_string[16]; snprintf(temp_string, sizeof( temp_string ), "%s %02d:%02d:%02d#", cmd, x, y, z); return (setStandardProcedure(fd, temp_string)); } int setAlignmentMode(int fd, unsigned int alignMode) { /*fprintf(stderr , "Set alignment mode %d\n", alignMode);*/ int error_type; int nbytes_write=0; switch (alignMode) { case LX200_ALIGN_POLAR: if ( (error_type = tty_write_string(fd, "#:AP#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:AP#") < 0) return -1;*/ break; case LX200_ALIGN_ALTAZ: if ( (error_type = tty_write_string(fd, "#:AA#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:AA#") < 0) return -1;*/ break; case LX200_ALIGN_LAND: if ( (error_type = tty_write_string(fd, "#:AL#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:AL#") < 0) return -1;*/ break; } tcflush(fd, TCIFLUSH); return 0; } int setCalenderDate(int fd, int dd, int mm, int yy) { char temp_string[32]; char dumpPlanetaryUpdateString[64]; char bool_return[2]; int error_type; int nbytes_write=0, nbytes_read=0; yy = yy % 100; snprintf(temp_string, sizeof( temp_string ), "#:SC %02d/%02d/%02d#", mm, dd, yy); if ( (error_type = tty_write_string(fd, temp_string, &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite(temp_string) < 0) return -1;*/ /*read_ret = portRead(boolRet, 1, LX200_TIMEOUT);*/ error_type = tty_read(fd, bool_return, 1, LX200_TIMEOUT, &nbytes_read); tcflush(fd, TCIFLUSH); if (nbytes_read < 1) return error_type; bool_return[1] = '\0'; if (bool_return[0] == '0') return -1; /* Read dumped data */ error_type = tty_read_section(fd, dumpPlanetaryUpdateString, '#', LX200_TIMEOUT, &nbytes_read); error_type = tty_read_section(fd, dumpPlanetaryUpdateString, '#', 5, &nbytes_read); return 0; } int setUTCOffset(int fd, double hours) { char temp_string[16]; snprintf(temp_string, sizeof( temp_string ), "#:SG %+03d#", (int) hours); /*IDLog("UTC string is %s\n", temp_string);*/ return (setStandardProcedure(fd, temp_string)); } int setSiteLongitude(int fd, double Long) { int d, m, s; char temp_string[32]; getSexComponents(Long, &d, &m, &s); snprintf(temp_string, sizeof( temp_string ), "#:Sg%03d:%02d#", d, m); return (setStandardProcedure(fd, temp_string)); } int setSiteLatitude(int fd, double Lat) { int d, m, s; char temp_string[32]; getSexComponents(Lat, &d, &m, &s); snprintf(temp_string, sizeof( temp_string ), "#:St%+03d:%02d:%02d#", d, m, s); return (setStandardProcedure(fd, temp_string)); } int setObjAz(int fd, double az) { int d,m,s; char temp_string[16]; getSexComponents(az, &d, &m, &s); snprintf(temp_string, sizeof( temp_string ), "#:Sz%03d:%02d#", d, m); return (setStandardProcedure(fd, temp_string)); } int setObjAlt(int fd, double alt) { int d, m, s; char temp_string[16]; getSexComponents(alt, &d, &m, &s); snprintf(temp_string, sizeof( temp_string ), "#:Sa%+02d*%02d#", d, m); return (setStandardProcedure(fd, temp_string)); } int setSiteName(int fd, char * siteName, int siteNum) { char temp_string[16]; switch (siteNum) { case 1: snprintf(temp_string, sizeof( temp_string ), "#:SM %s#", siteName); break; case 2: snprintf(temp_string, sizeof( temp_string ), "#:SN %s#", siteName); break; case 3: snprintf(temp_string, sizeof( temp_string ), "#:SO %s#", siteName); break; case 4: snprintf(temp_string, sizeof( temp_string ), "#:SP %s#", siteName); break; default: return -1; } return (setStandardProcedure(fd, temp_string)); } int setSlewMode(int fd, int slewMode) { int error_type; int nbytes_write=0; switch (slewMode) { case LX200_SLEW_MAX: if ( (error_type = tty_write_string(fd, "#:RS#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:RS#") < 0) return -1;*/ break; case LX200_SLEW_FIND: if ( (error_type = tty_write_string(fd, "#:RM#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:RM#") < 0) return -1;*/ break; case LX200_SLEW_CENTER: if ( (error_type = tty_write_string(fd, "#:RC#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:RC#") < 0) return -1;*/ break; case LX200_SLEW_GUIDE: if ( (error_type = tty_write_string(fd, "#:RG#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:RG#") < 0) return -1;*/ break; default: break; } tcflush(fd, TCIFLUSH); return 0; } int setFocuserMotion(int fd, int motionType) { int error_type; int nbytes_write=0; switch (motionType) { case LX200_FOCUSIN: if ( (error_type = tty_write_string(fd, "#:F+#", &nbytes_write)) != TTY_OK) return error_type; #ifdef INDI_DEBUG /*IDLog("Focus IN Command\n");*/ #endif /*if (portWrite("#:F+#") < 0) return -1;*/ break; case LX200_FOCUSOUT: if ( (error_type = tty_write_string(fd, "#:F-#", &nbytes_write)) != TTY_OK) return error_type; #ifdef INDI_DEBUG /*IDLog("Focus OUT Command\n");*/ #endif /*if (portWrite("#:F-#") < 0) return -1;*/ break; } tcflush(fd, TCIFLUSH); return 0; } int setFocuserSpeedMode (int fd, int speedMode) { int error_type; int nbytes_write=0; switch (speedMode) { case LX200_HALTFOCUS: if ( (error_type = tty_write_string(fd, "#:FQ#", &nbytes_write)) != TTY_OK) return error_type; #ifdef INDI_DEBUG /*IDLog("Halt Focus Command\n");*/ #endif /* if (portWrite("#:FQ#") < 0) return -1;*/ break; case LX200_FOCUSSLOW: if ( (error_type = tty_write_string(fd, "#:FS#", &nbytes_write)) != TTY_OK) return error_type; #ifdef INDI_DEBUG /*IDLog("Focus Slow (FS) Command\n");*/ #endif /*if (portWrite("#:FS#") < 0) return -1;*/ break; case LX200_FOCUSFAST: if ( (error_type = tty_write_string(fd, "#:FF#", &nbytes_write)) != TTY_OK) return error_type; #ifdef INDI_DEBUG /*IDLog("Focus Fast (FF) Command\n");*/ #endif /*if (portWrite("#:FF#") < 0) return -1;*/ break; } tcflush(fd, TCIFLUSH); return 0; } int setGPSFocuserSpeed (int fd, int speed) { char speed_str[8]; int error_type; int nbytes_write=0; if (speed == 0) { /*if (portWrite("#:FQ#") < 0) return -1;*/ if ( (error_type = tty_write_string(fd, "#:FQ#", &nbytes_write)) != TTY_OK) return error_type; #ifdef INDI_DEBUG /*IDLog("GPS Focus HALT Command (FQ) \n");*/ #endif return 0; } snprintf(speed_str, 8, "#:F%d#", speed); if ( (error_type = tty_write_string(fd, speed_str, &nbytes_write)) != TTY_OK) return error_type; #ifdef INDI_DEBUG /*IDLog("GPS Focus Speed command %s \n", speed_str);*/ #endif /*if (portWrite(speed_str) < 0) return -1;*/ tcflush(fd, TCIFLUSH); return 0; } int setTrackFreq(int fd, double trackF) { char temp_string[16]; snprintf(temp_string, sizeof( temp_string ), "#:ST %04.1f#", trackF); return (setStandardProcedure(fd, temp_string)); } /********************************************************************** * Misc *********************************************************************/ int Slew(int fd) { char slewNum[2]; int error_type; int nbytes_write=0, nbytes_read=0; if ( (error_type = tty_write_string(fd, "#:MS#", &nbytes_write)) != TTY_OK) return error_type; error_type = tty_read(fd, slewNum, 1, LX200_TIMEOUT, &nbytes_read); if (nbytes_read < 1) return error_type; /* We don't need to read the string message, just return corresponding error code */ tcflush(fd, TCIFLUSH); if (slewNum[0] == '0') return 0; else if (slewNum[0] == '1') return 1; else return 2; } int MoveTo(int fd, int direction) { int nbytes_write=0; switch (direction) { case LX200_NORTH: tty_write_string(fd, "#:Mn#", &nbytes_write); /*portWrite("#:Mn#");*/ break; case LX200_WEST: tty_write_string(fd, "#:Mw#", &nbytes_write); /*portWrite("#:Mw#");*/ break; case LX200_EAST: tty_write_string(fd, "#:Me#", &nbytes_write); /*portWrite("#:Me#");*/ break; case LX200_SOUTH: tty_write_string(fd, "#:Ms#", &nbytes_write); /*portWrite("#:Ms#");*/ break; default: break; } tcflush(fd, TCIFLUSH); return 0; } int HaltMovement(int fd, int direction) { int error_type; int nbytes_write=0; switch (direction) { case LX200_NORTH: /*if (portWrite("#:Qn#") < 0) return -1;*/ if ( (error_type = tty_write_string(fd, "#:Qn#", &nbytes_write)) != TTY_OK) return error_type; break; case LX200_WEST: /*if (portWrite("#:Qw#") < 0) return -1;*/ if ( (error_type = tty_write_string(fd, "#:Qw#", &nbytes_write)) != TTY_OK) return error_type; break; case LX200_EAST: /*if (portWrite("#:Qe#") < 0) return -1;*/ if ( (error_type = tty_write_string(fd, "#:Qe#", &nbytes_write)) != TTY_OK) return error_type; break; case LX200_SOUTH: if ( (error_type = tty_write_string(fd, "#:Qs#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:Qs#") < 0) return -1;*/ break; case LX200_ALL: /*if (portWrite("#:Q#") < 0) return -1;*/ if ( (error_type = tty_write_string(fd, "#:Q#", &nbytes_write)) != TTY_OK) return error_type; break; default: return -1; break; } tcflush(fd, TCIFLUSH); return 0; } int abortSlew(int fd) { /*if (portWrite("#:Q#") < 0) return -1;*/ int error_type; int nbytes_write=0; if ( (error_type = tty_write_string(fd, "#:Q#", &nbytes_write)) != TTY_OK) return error_type; tcflush(fd, TCIFLUSH); return 0; } int Sync(int fd, char *matchedObject) { int error_type; int nbytes_write=0, nbytes_read=0; if ( (error_type = tty_write_string(fd, "#:CM#", &nbytes_write)) != TTY_OK) return error_type; /*portWrite("#:CM#");*/ /*read_ret = portRead(matchedObject, -1, LX200_TIMEOUT);*/ error_type = tty_read_section(fd, matchedObject, '#', LX200_TIMEOUT, &nbytes_read); if (nbytes_read < 1) return error_type; matchedObject[nbytes_read-1] = '\0'; /*IDLog("Matched Object: %s\n", matchedObject);*/ /* Sleep 10ms before flushing. This solves some issues with LX200 compatible devices. */ usleep(10000); tcflush(fd, TCIFLUSH); return 0; } int selectSite(int fd, int siteNum) { int error_type; int nbytes_write=0; switch (siteNum) { case 1: if ( (error_type = tty_write_string(fd, "#:W1#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:W1#") < 0) return -1;*/ break; case 2: if ( (error_type = tty_write_string(fd, "#:W2#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:W2#") < 0) return -1;*/ break; case 3: if ( (error_type = tty_write_string(fd, "#:W3#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:W3#") < 0) return -1;*/ break; case 4: if ( (error_type = tty_write_string(fd, "#:W4#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:W4#") < 0) return -1;*/ break; default: return -1; break; } tcflush(fd, TCIFLUSH); return 0; } int selectCatalogObject(int fd, int catalog, int NNNN) { char temp_string[16]; int error_type; int nbytes_write=0; switch (catalog) { case LX200_STAR_C: snprintf(temp_string, sizeof( temp_string ), "#:LS%d#", NNNN); break; case LX200_DEEPSKY_C: snprintf(temp_string, sizeof( temp_string ), "#:LC%d#", NNNN); break; case LX200_MESSIER_C: snprintf(temp_string, sizeof( temp_string ), "#:LM%d#", NNNN); break; default: return -1; } if ( (error_type = tty_write_string(fd, temp_string, &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite(temp_string) < 0) return -1;*/ tcflush(fd, TCIFLUSH); return 0; } int selectSubCatalog(int fd, int catalog, int subCatalog) { char temp_string[16]; switch (catalog) { case LX200_STAR_C: snprintf(temp_string, sizeof( temp_string ), "#:LsD%d#", subCatalog); break; case LX200_DEEPSKY_C: snprintf(temp_string, sizeof( temp_string ), "#:LoD%d#", subCatalog); break; case LX200_MESSIER_C: return 1; default: return 0; } return (setStandardProcedure(fd, temp_string)); } int checkLX200Format(int fd) { char temp_string[16]; controller_format = LX200_LONG_FORMAT; int error_type; int nbytes_write=0, nbytes_read=0; if ( (error_type = tty_write_string(fd, "#:GR#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:GR#") < 0) return -1;*/ /*read_ret = portRead(temp_string, -1, LX200_TIMEOUT);*/ error_type = tty_read_section(fd, temp_string, '#', LX200_TIMEOUT, &nbytes_read); if (nbytes_read < 1) return error_type; temp_string[nbytes_read - 1] = '\0'; /* Check whether it's short or long */ if (temp_string[5] == '.') { controller_format = LX200_SHORT_FORMAT; return 0; } else return 0; } int selectTrackingMode(int fd, int trackMode) { int error_type; int nbytes_write=0; switch (trackMode) { case LX200_TRACK_DEFAULT: #ifdef INDI_DEBUG IDLog("Setting tracking mode to sidereal.\n"); #endif if ( (error_type = tty_write_string(fd, "#:TQ#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:TQ#") < 0) return -1;*/ break; case LX200_TRACK_LUNAR: #ifdef INDI_DEBUG IDLog("Setting tracking mode to LUNAR.\n"); #endif if ( (error_type = tty_write_string(fd, "#:TL#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:TL#") < 0) return -1;*/ break; case LX200_TRACK_MANUAL: #ifdef INDI_DEBUG IDLog("Setting tracking mode to CUSTOM.\n"); #endif if ( (error_type = tty_write_string(fd, "#:TM#", &nbytes_write)) != TTY_OK) return error_type; /*if (portWrite("#:TM#") < 0) return -1;*/ break; default: return -1; break; } tcflush(fd, TCIFLUSH); return 0; } indi-0.5/src/v4ldriver.h0000644000175000017500000001123210610474336012775 0ustar jrjr#if 0 V4L INDI Driver INDI Interface for V4L devices Copyright (C) 2003-2005 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #ifndef V4L_DRIVER_H #define V4L_DRIVER_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "indidevapi.h" #include "indicom.h" #include "cfitsio/fitsio.h" #include "eventloop.h" /* N.B. INDI is INDEPENDENT from KStars */ #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_LINUX_VIDEODEV2_H #include "webcam/v4l2_base.h" #else #include "webcam/v4l1_base.h" #endif #define COMM_GROUP "Main Control" #define IMAGE_CONTROL "Image Control" #define IMAGE_GROUP "Image Settings" #define MAX_PIXELS 4096 /* Max number of pixels in one dimension */ #define ERRMSGSIZ 1024 #define TEMPFILE_LEN 16 class V4L_Driver { public: V4L_Driver(); virtual ~V4L_Driver(); /* INDI Functions that must be called from indidrivermain */ virtual void ISGetProperties (const char *dev); virtual void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); virtual void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n); virtual void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); virtual void initCamBase(); virtual void initProperties(const char *dev); static void newFrame(void *p); void updateFrame(); protected: /* Structs */ typedef struct { int width; int height; int expose; unsigned char *Y; unsigned char *U; unsigned char *V; unsigned char *colorBuffer; unsigned char *compressedFrame; } img_t; /* Switches */ ISwitch PowerS[2]; ISwitch StreamS[2]; ISwitch CompressS[2]; ISwitch ImageTypeS[2]; /* Texts */ IText PortT[1]; IText camNameT[1]; /* Numbers */ INumber ExposeTimeN[1]; INumber FrameRateN[1]; INumber FrameN[4]; #ifndef HAVE_LINUX_VIDEODEV2_H INumber ImageAdjustN[5]; #endif /* BLOBs */ IBLOB imageB; /* Switch vectors */ ISwitchVectorProperty PowerSP; /* Connection switch */ ISwitchVectorProperty StreamSP; /* Stream switch */ ISwitchVectorProperty CompressSP; /* Compress stream switch */ ISwitchVectorProperty ImageTypeSP; /* Color or grey switch */ /* Number vectors */ INumberVectorProperty ExposeTimeNP; /* Exposure */ INumberVectorProperty FrameRateNP; /* Frame rate */ INumberVectorProperty FrameNP; /* Stream dimenstion */ INumberVectorProperty ImageAdjustNP; /* Image controls */ /* Text vectors */ ITextVectorProperty PortTP; ITextVectorProperty camNameTP; /* BLOB vectors */ IBLOBVectorProperty imageBP; /* Data stream */ /* Initilization functions */ virtual void connectCamera(void); virtual void getBasicData(void); /* Stream/FITS functions */ void updateStream(); void uploadFile(const char * filename); int writeFITS(const char *filename, char errmsg[]); int grabImage(void); void addFITSKeywords(fitsfile *fptr); /* Helper functions */ int checkPowerN(INumberVectorProperty *np); int checkPowerS(ISwitchVectorProperty *sp); int checkPowerT(ITextVectorProperty *tp); #ifndef HAVE_LINUX_VIDEODEV2_H virtual void updateV4L1Controls(); V4L1_Base *v4l_base; #else virtual void updateV4L2Controls(); V4L2_Base *v4l_base; #endif char device_name[MAXINDIDEVICE]; int frameCount; /* For debugging */ double divider; /* For limits */ img_t * V4LFrame; /* Video frame */ time_t capture_start; /* To calculate how long a frame take */ time_t capture_end; }; #endif indi-0.5/src/Makefile.in0000644000175000017500000011474410610536734012765 0ustar jrjr# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = indiserver$(EXEEXT) lx200basic$(EXEEXT) \ lx200generic$(EXEEXT) celestrongps$(EXEEXT) temma$(EXEEXT) \ skycommander$(EXEEXT) intelliscope$(EXEEXT) robofocus$(EXEEXT) \ orionatlas$(EXEEXT) trutechwheel$(EXEEXT) stv$(EXEEXT) \ $(am__EXEEXT_1) subdir = src DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru libindicom_a_AR = $(AR) $(ARFLAGS) libindicom_a_LIBADD = am_libindicom_a_OBJECTS = indicom.$(OBJEXT) base64.$(OBJEXT) \ observer.$(OBJEXT) libindicom_a_OBJECTS = $(am_libindicom_a_OBJECTS) liblilxml_a_AR = $(AR) $(ARFLAGS) liblilxml_a_LIBADD = am_liblilxml_a_OBJECTS = lilxml.$(OBJEXT) liblilxml_a_OBJECTS = $(am_liblilxml_a_OBJECTS) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ "$(DESTDIR)$(pkgdatadir)" libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) libsbigudrv_la_DEPENDENCIES = am__libsbigudrv_la_SOURCES_DIST = sbig_dummy.cpp @HAVE_LIBSBIGUDRV_FALSE@@LINUX_TRUE@am_libsbigudrv_la_OBJECTS = \ @HAVE_LIBSBIGUDRV_FALSE@@LINUX_TRUE@ sbig_dummy.lo libsbigudrv_la_OBJECTS = $(am_libsbigudrv_la_OBJECTS) @HAVE_LIBSBIGUDRV_FALSE@@LINUX_TRUE@am_libsbigudrv_la_rpath = -rpath \ @HAVE_LIBSBIGUDRV_FALSE@@LINUX_TRUE@ $(libdir) @LINUX_TRUE@am__EXEEXT_1 = sbigccd$(EXEEXT) apogee_ppi$(EXEEXT) \ @LINUX_TRUE@ v4ldriver$(EXEEXT) v4lphilips$(EXEEXT) \ @LINUX_TRUE@ meade_lpi$(EXEEXT) fliccd$(EXEEXT) \ @LINUX_TRUE@ fliwheel$(EXEEXT) flipdf$(EXEEXT) binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(bin_PROGRAMS) am_apogee_ppi_OBJECTS = apogee_ppi.$(OBJEXT) base64.$(OBJEXT) \ eventloop.$(OBJEXT) indidrivermain.$(OBJEXT) apogee_ppi_OBJECTS = $(am_apogee_ppi_OBJECTS) apogee_ppi_DEPENDENCIES = libindicom.a liblilxml.a \ apogee/libapogee_PPI.la am_celestrongps_OBJECTS = indidrivermain.$(OBJEXT) base64.$(OBJEXT) \ eventloop.$(OBJEXT) celestronprotocol.$(OBJEXT) \ celestrongps.$(OBJEXT) celestrongps_OBJECTS = $(am_celestrongps_OBJECTS) celestrongps_DEPENDENCIES = liblilxml.a libindicom.a am_fliccd_OBJECTS = eventloop.$(OBJEXT) base64.$(OBJEXT) \ fli_ccd.$(OBJEXT) indidrivermain.$(OBJEXT) fliccd_OBJECTS = $(am_fliccd_OBJECTS) fliccd_DEPENDENCIES = fli/libfli.la libindicom.a liblilxml.a am_flipdf_OBJECTS = eventloop.$(OBJEXT) base64.$(OBJEXT) \ fli_pdf.$(OBJEXT) indidrivermain.$(OBJEXT) flipdf_OBJECTS = $(am_flipdf_OBJECTS) flipdf_DEPENDENCIES = fli/libfli.la libindicom.a liblilxml.a am_fliwheel_OBJECTS = eventloop.$(OBJEXT) base64.$(OBJEXT) \ fli_wheel.$(OBJEXT) indidrivermain.$(OBJEXT) fliwheel_OBJECTS = $(am_fliwheel_OBJECTS) fliwheel_DEPENDENCIES = fli/libfli.la libindicom.a liblilxml.a am_indiserver_OBJECTS = indiserver.$(OBJEXT) fq.$(OBJEXT) indiserver_OBJECTS = $(am_indiserver_OBJECTS) indiserver_DEPENDENCIES = liblilxml.a am_intelliscope_OBJECTS = indidrivermain.$(OBJEXT) base64.$(OBJEXT) \ eventloop.$(OBJEXT) lx200driver.$(OBJEXT) \ intelliscope.$(OBJEXT) intelliscope_OBJECTS = $(am_intelliscope_OBJECTS) intelliscope_DEPENDENCIES = liblilxml.a libindicom.a am_lx200basic_OBJECTS = indidrivermain.$(OBJEXT) base64.$(OBJEXT) \ eventloop.$(OBJEXT) lx200driver.$(OBJEXT) lx200basic.$(OBJEXT) lx200basic_OBJECTS = $(am_lx200basic_OBJECTS) lx200basic_DEPENDENCIES = liblilxml.a libindicom.a am_lx200generic_OBJECTS = indidrivermain.$(OBJEXT) base64.$(OBJEXT) \ eventloop.$(OBJEXT) lx200driver.$(OBJEXT) \ lx200autostar.$(OBJEXT) lx200_16.$(OBJEXT) lx200gps.$(OBJEXT) \ lx200generic.$(OBJEXT) lx200classic.$(OBJEXT) lx200generic_OBJECTS = $(am_lx200generic_OBJECTS) lx200generic_DEPENDENCIES = liblilxml.a libindicom.a am_meade_lpi_OBJECTS = eventloop.$(OBJEXT) base64.$(OBJEXT) \ indidrivermain.$(OBJEXT) v4ldriver.$(OBJEXT) \ indi_lpi.$(OBJEXT) meade_lpi_OBJECTS = $(am_meade_lpi_OBJECTS) meade_lpi_DEPENDENCIES = libindicom.a liblilxml.a webcam/libwebcam.la am_orionatlas_OBJECTS = indidrivermain.$(OBJEXT) base64.$(OBJEXT) \ eventloop.$(OBJEXT) orionatlas.$(OBJEXT) orionatlas_OBJECTS = $(am_orionatlas_OBJECTS) orionatlas_DEPENDENCIES = liblilxml.a libindicom.a am_robofocus_OBJECTS = indidrivermain.$(OBJEXT) base64.$(OBJEXT) \ eventloop.$(OBJEXT) lx200driver.$(OBJEXT) \ robofocusdriver.$(OBJEXT) robofocus.$(OBJEXT) robofocus_OBJECTS = $(am_robofocus_OBJECTS) robofocus_DEPENDENCIES = liblilxml.a libindicom.a am_sbigccd_OBJECTS = sbigcam.$(OBJEXT) base64.$(OBJEXT) \ eventloop.$(OBJEXT) indidrivermain.$(OBJEXT) sbigccd_OBJECTS = $(am_sbigccd_OBJECTS) sbigccd_DEPENDENCIES = libindicom.a liblilxml.a am_skycommander_OBJECTS = indidrivermain.$(OBJEXT) base64.$(OBJEXT) \ eventloop.$(OBJEXT) lx200driver.$(OBJEXT) \ skycommander.$(OBJEXT) skycommander_OBJECTS = $(am_skycommander_OBJECTS) skycommander_DEPENDENCIES = liblilxml.a libindicom.a am_stv_OBJECTS = eventloop.$(OBJEXT) base64.$(OBJEXT) \ indidrivermain.$(OBJEXT) stv.$(OBJEXT) stvdriver.$(OBJEXT) stv_OBJECTS = $(am_stv_OBJECTS) stv_DEPENDENCIES = libindicom.a liblilxml.a am_temma_OBJECTS = indidrivermain.$(OBJEXT) base64.$(OBJEXT) \ eventloop.$(OBJEXT) temmadriver.$(OBJEXT) temma_OBJECTS = $(am_temma_OBJECTS) temma_DEPENDENCIES = liblilxml.a libindicom.a am_trutechwheel_OBJECTS = eventloop.$(OBJEXT) base64.$(OBJEXT) \ trutech_wheel.$(OBJEXT) indidrivermain.$(OBJEXT) trutechwheel_OBJECTS = $(am_trutechwheel_OBJECTS) trutechwheel_DEPENDENCIES = libindicom.a liblilxml.a am_v4ldriver_OBJECTS = eventloop.$(OBJEXT) base64.$(OBJEXT) \ indidrivermain.$(OBJEXT) v4ldriver.$(OBJEXT) \ indi_v4l.$(OBJEXT) v4ldriver_OBJECTS = $(am_v4ldriver_OBJECTS) v4ldriver_DEPENDENCIES = libindicom.a liblilxml.a webcam/libwebcam.la am_v4lphilips_OBJECTS = eventloop.$(OBJEXT) base64.$(OBJEXT) \ indidrivermain.$(OBJEXT) v4ldriver.$(OBJEXT) \ v4lphilips.$(OBJEXT) indi_philips.$(OBJEXT) v4lphilips_OBJECTS = $(am_v4lphilips_OBJECTS) v4lphilips_DEPENDENCIES = libindicom.a liblilxml.a webcam/libwebcam.la DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libindicom_a_SOURCES) $(liblilxml_a_SOURCES) \ $(libsbigudrv_la_SOURCES) $(apogee_ppi_SOURCES) \ $(celestrongps_SOURCES) $(fliccd_SOURCES) $(flipdf_SOURCES) \ $(fliwheel_SOURCES) $(indiserver_SOURCES) \ $(intelliscope_SOURCES) $(lx200basic_SOURCES) \ $(lx200generic_SOURCES) $(meade_lpi_SOURCES) \ $(orionatlas_SOURCES) $(robofocus_SOURCES) $(sbigccd_SOURCES) \ $(skycommander_SOURCES) $(stv_SOURCES) $(temma_SOURCES) \ $(trutechwheel_SOURCES) $(v4ldriver_SOURCES) \ $(v4lphilips_SOURCES) DIST_SOURCES = $(libindicom_a_SOURCES) $(liblilxml_a_SOURCES) \ $(am__libsbigudrv_la_SOURCES_DIST) $(apogee_ppi_SOURCES) \ $(celestrongps_SOURCES) $(fliccd_SOURCES) $(flipdf_SOURCES) \ $(fliwheel_SOURCES) $(indiserver_SOURCES) \ $(intelliscope_SOURCES) $(lx200basic_SOURCES) \ $(lx200generic_SOURCES) $(meade_lpi_SOURCES) \ $(orionatlas_SOURCES) $(robofocus_SOURCES) $(sbigccd_SOURCES) \ $(skycommander_SOURCES) $(stv_SOURCES) $(temma_SOURCES) \ $(trutechwheel_SOURCES) $(v4ldriver_SOURCES) \ $(v4lphilips_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-exec-recursive install-info-recursive \ install-recursive installcheck-recursive installdirs-recursive \ pdf-recursive ps-recursive uninstall-info-recursive \ uninstall-recursive pkgdataDATA_INSTALL = $(INSTALL_DATA) DATA = $(pkgdata_DATA) ETAGS = etags CTAGS = ctags DIST_SUBDIRS = @EXTRA_SUBDIR@ fli webcam apogee DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BSD_FALSE = @BSD_FALSE@ BSD_TRUE = @BSD_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_SUBDIR = @EXTRA_SUBDIR@ F77 = @F77@ FFLAGS = @FFLAGS@ GREP = @GREP@ HAVE_LIBSBIGUDRV_FALSE = @HAVE_LIBSBIGUDRV_FALSE@ HAVE_LIBSBIGUDRV_TRUE = @HAVE_LIBSBIGUDRV_TRUE@ HAVE_LIBUSB_FALSE = @HAVE_LIBUSB_FALSE@ HAVE_LIBUSB_TRUE = @HAVE_LIBUSB_TRUE@ HAVE_V4L2_FALSE = @HAVE_V4L2_FALSE@ HAVE_V4L2_TRUE = @HAVE_V4L2_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBCFITSIO = @LIBCFITSIO@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSBIGUDRV = @LIBSBIGUDRV@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LINUX_FALSE = @LINUX_FALSE@ LINUX_TRUE = @LINUX_TRUE@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ NULL_FALSE = @NULL_FALSE@ NULL_TRUE = @NULL_TRUE@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_F77 = @ac_ct_F77@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ AM_CPPFLAGS = @CPPFLAGS@ -DTOP_DATADIR=\"$(pkgdatadir)\" @HAVE_LIBSBIGUDRV_FALSE@@LINUX_TRUE@lib_LTLIBRARIES = libsbigudrv.la @HAVE_LIBSBIGUDRV_FALSE@@LINUX_TRUE@libsbigudrv_la_LIBADD = -lm @HAVE_LIBSBIGUDRV_FALSE@@LINUX_TRUE@libsbigudrv_la_SOURCES = sbig_dummy.cpp @LINUX_TRUE@bin_add = sbigccd apogee_ppi v4ldriver v4lphilips meade_lpi fliccd fliwheel flipdf liblilxml_a_SOURCES = lilxml.c libindicom_a_SOURCES = indicom.c base64.c observer.c noinst_LIBRARIES = liblilxml.a libindicom.a indiserver_SOURCES = indiserver.c fq.c indiserver_LDADD = liblilxml.a $(LIBSOCKET) lx200generic_SOURCES = indidrivermain.c base64.c eventloop.c lx200driver.c lx200autostar.cpp lx200_16.cpp lx200gps.cpp lx200generic.cpp lx200classic.cpp lx200generic_LDADD = liblilxml.a libindicom.a -lm lx200basic_SOURCES = indidrivermain.c base64.c eventloop.c lx200driver.c lx200basic.cpp lx200basic_LDADD = liblilxml.a libindicom.a celestrongps_SOURCES = indidrivermain.c base64.c eventloop.c celestronprotocol.c celestrongps.cpp celestrongps_LDADD = liblilxml.a libindicom.a -lm robofocus_SOURCES = indidrivermain.c base64.c eventloop.c lx200driver.c robofocusdriver.c robofocus.c robofocus_LDADD = liblilxml.a libindicom.a -lm fliccd_SOURCES = eventloop.c base64.c fli_ccd.c indidrivermain.c fliccd_LDADD = fli/libfli.la libindicom.a liblilxml.a @LIBCFITSIO@ -lm -lz $(LIBSOCKET) fliwheel_SOURCES = eventloop.c base64.c fli_wheel.c indidrivermain.c fliwheel_LDADD = fli/libfli.la libindicom.a liblilxml.a -lm flipdf_SOURCES = eventloop.c base64.c fli_pdf.c indidrivermain.c flipdf_LDADD = fli/libfli.la libindicom.a liblilxml.a -lm trutechwheel_SOURCES = eventloop.c base64.c trutech_wheel.c indidrivermain.c trutechwheel_LDADD = libindicom.a liblilxml.a -lm stv_SOURCES = eventloop.c base64.c indidrivermain.c stv.cpp stvdriver.c stv_LDADD = libindicom.a liblilxml.a @LIBCFITSIO@ -lm -lz v4ldriver_SOURCES = eventloop.c base64.c indidrivermain.c v4ldriver.cpp indi_v4l.cpp v4ldriver_LDADD = libindicom.a liblilxml.a webcam/libwebcam.la @LIBCFITSIO@ -lm -lz v4lphilips_SOURCES = eventloop.c base64.c indidrivermain.c v4ldriver.cpp v4lphilips.cpp indi_philips.cpp v4lphilips_LDADD = libindicom.a liblilxml.a webcam/libwebcam.la @LIBCFITSIO@ -lm -lz meade_lpi_SOURCES = eventloop.c base64.c indidrivermain.c v4ldriver.cpp indi_lpi.cpp meade_lpi_LDADD = libindicom.a liblilxml.a webcam/libwebcam.la @LIBCFITSIO@ -lz temma_SOURCES = indidrivermain.c base64.c eventloop.c temmadriver.c temma_LDADD = liblilxml.a libindicom.a -lm skycommander_SOURCES = indidrivermain.c base64.c eventloop.c lx200driver.c skycommander.c skycommander_LDADD = liblilxml.a libindicom.a -lm intelliscope_SOURCES = indidrivermain.c base64.c eventloop.c lx200driver.c intelliscope.c intelliscope_LDADD = liblilxml.a libindicom.a -lm orionatlas_SOURCES = indidrivermain.c base64.c eventloop.c orionatlas.cpp orionatlas_LDADD = liblilxml.a libindicom.a -lm apogee_ppi_SOURCES = apogee_ppi.cpp base64.c eventloop.c indidrivermain.c apogee_ppi_LDADD = libindicom.a liblilxml.a apogee/libapogee_PPI.la -lz sbigccd_SOURCES = sbigcam.cpp base64.c eventloop.c indidrivermain.c sbigccd_LDADD = libindicom.a liblilxml.a @LIBCFITSIO@ @LIBSBIGUDRV@ -lz pkgdata_DATA = apogee_caminfo.xml @LINUX_TRUE@SUBDIRS = @EXTRA_SUBDIR@ fli webcam apogee all: all-recursive .SUFFIXES: .SUFFIXES: .c .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libindicom.a: $(libindicom_a_OBJECTS) $(libindicom_a_DEPENDENCIES) -rm -f libindicom.a $(libindicom_a_AR) libindicom.a $(libindicom_a_OBJECTS) $(libindicom_a_LIBADD) $(RANLIB) libindicom.a liblilxml.a: $(liblilxml_a_OBJECTS) $(liblilxml_a_DEPENDENCIES) -rm -f liblilxml.a $(liblilxml_a_AR) liblilxml.a $(liblilxml_a_OBJECTS) $(liblilxml_a_LIBADD) $(RANLIB) liblilxml.a install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libsbigudrv.la: $(libsbigudrv_la_OBJECTS) $(libsbigudrv_la_DEPENDENCIES) $(CXXLINK) $(am_libsbigudrv_la_rpath) $(libsbigudrv_la_LDFLAGS) $(libsbigudrv_la_OBJECTS) $(libsbigudrv_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ || test -f $$p1 \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ rm -f "$(DESTDIR)$(bindir)/$$f"; \ done clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ echo " rm -f $$p $$f"; \ rm -f $$p $$f ; \ done apogee_ppi$(EXEEXT): $(apogee_ppi_OBJECTS) $(apogee_ppi_DEPENDENCIES) @rm -f apogee_ppi$(EXEEXT) $(CXXLINK) $(apogee_ppi_LDFLAGS) $(apogee_ppi_OBJECTS) $(apogee_ppi_LDADD) $(LIBS) celestrongps$(EXEEXT): $(celestrongps_OBJECTS) $(celestrongps_DEPENDENCIES) @rm -f celestrongps$(EXEEXT) $(CXXLINK) $(celestrongps_LDFLAGS) $(celestrongps_OBJECTS) $(celestrongps_LDADD) $(LIBS) fliccd$(EXEEXT): $(fliccd_OBJECTS) $(fliccd_DEPENDENCIES) @rm -f fliccd$(EXEEXT) $(LINK) $(fliccd_LDFLAGS) $(fliccd_OBJECTS) $(fliccd_LDADD) $(LIBS) flipdf$(EXEEXT): $(flipdf_OBJECTS) $(flipdf_DEPENDENCIES) @rm -f flipdf$(EXEEXT) $(LINK) $(flipdf_LDFLAGS) $(flipdf_OBJECTS) $(flipdf_LDADD) $(LIBS) fliwheel$(EXEEXT): $(fliwheel_OBJECTS) $(fliwheel_DEPENDENCIES) @rm -f fliwheel$(EXEEXT) $(LINK) $(fliwheel_LDFLAGS) $(fliwheel_OBJECTS) $(fliwheel_LDADD) $(LIBS) indiserver$(EXEEXT): $(indiserver_OBJECTS) $(indiserver_DEPENDENCIES) @rm -f indiserver$(EXEEXT) $(LINK) $(indiserver_LDFLAGS) $(indiserver_OBJECTS) $(indiserver_LDADD) $(LIBS) intelliscope$(EXEEXT): $(intelliscope_OBJECTS) $(intelliscope_DEPENDENCIES) @rm -f intelliscope$(EXEEXT) $(LINK) $(intelliscope_LDFLAGS) $(intelliscope_OBJECTS) $(intelliscope_LDADD) $(LIBS) lx200basic$(EXEEXT): $(lx200basic_OBJECTS) $(lx200basic_DEPENDENCIES) @rm -f lx200basic$(EXEEXT) $(CXXLINK) $(lx200basic_LDFLAGS) $(lx200basic_OBJECTS) $(lx200basic_LDADD) $(LIBS) lx200generic$(EXEEXT): $(lx200generic_OBJECTS) $(lx200generic_DEPENDENCIES) @rm -f lx200generic$(EXEEXT) $(CXXLINK) $(lx200generic_LDFLAGS) $(lx200generic_OBJECTS) $(lx200generic_LDADD) $(LIBS) meade_lpi$(EXEEXT): $(meade_lpi_OBJECTS) $(meade_lpi_DEPENDENCIES) @rm -f meade_lpi$(EXEEXT) $(CXXLINK) $(meade_lpi_LDFLAGS) $(meade_lpi_OBJECTS) $(meade_lpi_LDADD) $(LIBS) orionatlas$(EXEEXT): $(orionatlas_OBJECTS) $(orionatlas_DEPENDENCIES) @rm -f orionatlas$(EXEEXT) $(CXXLINK) $(orionatlas_LDFLAGS) $(orionatlas_OBJECTS) $(orionatlas_LDADD) $(LIBS) robofocus$(EXEEXT): $(robofocus_OBJECTS) $(robofocus_DEPENDENCIES) @rm -f robofocus$(EXEEXT) $(LINK) $(robofocus_LDFLAGS) $(robofocus_OBJECTS) $(robofocus_LDADD) $(LIBS) sbigccd$(EXEEXT): $(sbigccd_OBJECTS) $(sbigccd_DEPENDENCIES) @rm -f sbigccd$(EXEEXT) $(CXXLINK) $(sbigccd_LDFLAGS) $(sbigccd_OBJECTS) $(sbigccd_LDADD) $(LIBS) skycommander$(EXEEXT): $(skycommander_OBJECTS) $(skycommander_DEPENDENCIES) @rm -f skycommander$(EXEEXT) $(LINK) $(skycommander_LDFLAGS) $(skycommander_OBJECTS) $(skycommander_LDADD) $(LIBS) stv$(EXEEXT): $(stv_OBJECTS) $(stv_DEPENDENCIES) @rm -f stv$(EXEEXT) $(CXXLINK) $(stv_LDFLAGS) $(stv_OBJECTS) $(stv_LDADD) $(LIBS) temma$(EXEEXT): $(temma_OBJECTS) $(temma_DEPENDENCIES) @rm -f temma$(EXEEXT) $(LINK) $(temma_LDFLAGS) $(temma_OBJECTS) $(temma_LDADD) $(LIBS) trutechwheel$(EXEEXT): $(trutechwheel_OBJECTS) $(trutechwheel_DEPENDENCIES) @rm -f trutechwheel$(EXEEXT) $(LINK) $(trutechwheel_LDFLAGS) $(trutechwheel_OBJECTS) $(trutechwheel_LDADD) $(LIBS) v4ldriver$(EXEEXT): $(v4ldriver_OBJECTS) $(v4ldriver_DEPENDENCIES) @rm -f v4ldriver$(EXEEXT) $(CXXLINK) $(v4ldriver_LDFLAGS) $(v4ldriver_OBJECTS) $(v4ldriver_LDADD) $(LIBS) v4lphilips$(EXEEXT): $(v4lphilips_OBJECTS) $(v4lphilips_DEPENDENCIES) @rm -f v4lphilips$(EXEEXT) $(CXXLINK) $(v4lphilips_LDFLAGS) $(v4lphilips_OBJECTS) $(v4lphilips_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apogee_ppi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base64.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/celestrongps.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/celestronprotocol.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventloop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fli_ccd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fli_pdf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fli_wheel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fq.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indi_lpi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indi_philips.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indi_v4l.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicom.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indidrivermain.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indiserver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intelliscope.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lilxml.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lx200_16.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lx200autostar.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lx200basic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lx200classic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lx200driver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lx200generic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lx200gps.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/observer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orionatlas.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/robofocus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/robofocusdriver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sbig_dummy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sbigcam.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skycommander.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stvdriver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/temmadriver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trutech_wheel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v4ldriver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v4lphilips.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool uninstall-info-am: install-pkgdataDATA: $(pkgdata_DATA) @$(NORMAL_INSTALL) test -z "$(pkgdatadir)" || $(mkdir_p) "$(DESTDIR)$(pkgdatadir)" @list='$(pkgdata_DATA)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(pkgdataDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgdatadir)/$$f'"; \ $(pkgdataDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgdatadir)/$$f"; \ done uninstall-pkgdataDATA: @$(NORMAL_UNINSTALL) @list='$(pkgdata_DATA)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(pkgdatadir)/$$f'"; \ rm -f "$(DESTDIR)$(pkgdatadir)/$$f"; \ done # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(mkdir_p) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(PROGRAMS) $(DATA) install-binPROGRAMS: install-libLTLIBRARIES installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdatadir)"; do \ test -z "$$dir" || $(mkdir_p) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool clean-noinstLIBRARIES mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-pkgdataDATA install-exec-am: install-binPROGRAMS install-libLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-info: install-info-recursive install-man: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-info-am \ uninstall-libLTLIBRARIES uninstall-local uninstall-pkgdataDATA uninstall-info: uninstall-info-recursive .PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ clean clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool clean-noinstLIBRARIES clean-recursive ctags \ ctags-recursive distclean distclean-compile distclean-generic \ distclean-libtool distclean-recursive distclean-tags distdir \ dvi dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-exec \ install-exec-am install-exec-hook install-info install-info-am \ install-libLTLIBRARIES install-man install-pkgdataDATA \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ maintainer-clean-recursive mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \ pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-info-am \ uninstall-libLTLIBRARIES uninstall-local uninstall-pkgdataDATA install-exec-hook: $(mkinstalldirs) $(DESTDIR)$(bindir) rm -f $(DESTDIR)$(bindir)/lx200classic $(LN_S) lx200generic $(DESTDIR)$(bindir)/lx200classic rm -f $(DESTDIR)$(bindir)/lx200autostar $(LN_S) lx200generic $(DESTDIR)$(bindir)/lx200autostar rm -f $(DESTDIR)$(bindir)/lx200_16 $(LN_S) lx200generic $(DESTDIR)$(bindir)/lx200_16 rm -f $(DESTDIR)$(bindir)/lx200gps $(LN_S) lx200generic $(DESTDIR)$(bindir)/lx200gps uninstall-local: rm $(DESTDIR)$(bindir)/lx200autostar $(DESTDIR)$(bindir)/lx200_16 $(DESTDIR)$(bindir)/lx200gps # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: indi-0.5/src/apogee_ppi.cpp0000644000175000017500000011167710610474326013534 0ustar jrjr#if 0 FLI CCD INDI Interface for Apogee PPI Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include #include #include #include #include #include "apogee_ppi.h" #include "lilxml.h" #include "base64.h" static void ISPoll(void *); extern char* me; /* argv[0] */ ApogeeCam *MainCam = NULL; /* Main and only camera */ /* send client definitions of all properties */ void ISInit() { if (MainCam == NULL) { MainCam = new ApogeeCam(); IEAddTimer (POLLMS, ISPoll, NULL); } } void ISGetProperties (const char *dev) { if (dev && strcmp (mydev, dev)) return; ISInit(); MainCam->ISGetProperties(dev); } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; ISInit(); MainCam->ISNewSwitch(dev, name, states, names, n); } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (mydev, dev)) return; ISInit(); MainCam->ISNewText(dev, name, texts, names, n); } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { /* ignore if not ours */ if (dev && strcmp (dev, mydev)) return; ISInit(); MainCam->ISNewNumber(dev, name, values, names, n); } void ISNewBLOB (const char */*dev*/, const char */*name*/, int */*sizes[]*/, char **/*blobs[]*/, char **/*formats[]*/, char **/*names[]*/, int /*n*/) { } void ISPoll(void *) { MainCam->ISPoll(); IEAddTimer (POLLMS, ISPoll, NULL); } ApogeeCam::ApogeeCam() { ApogeeModelS = NULL; initProperties(); } ApogeeCam::~ApogeeCam() { } void ApogeeCam::initProperties() { IUFillSwitch(&PowerS[0], "CONNECT", "Connect", ISS_OFF); IUFillSwitch(&PowerS[1], "DISCONNECT", "Disconnect", ISS_ON); IUFillSwitchVector(&PowerSP, PowerS, NARRAY(PowerS), mydev, "CONNECTION", "Connection", COMM_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE); IUFillSwitch(&FrameTypeS[0], "FRAME_LIGHT", "Light", ISS_ON); IUFillSwitch(&FrameTypeS[1], "FRAME_BIAS", "Bias", ISS_OFF); IUFillSwitch(&FrameTypeS[2], "FRAME_DARK", "Dark", ISS_OFF); IUFillSwitch(&FrameTypeS[3], "FRAME_FLAT", "Flat Field", ISS_OFF); IUFillSwitchVector(&FrameTypeSP, FrameTypeS, NARRAY(FrameTypeS), mydev, "CCD_FRAME_TYPE", "Frame Type", EXPOSE_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE); IUFillNumber(&FrameN[0], "X", "X", "%.0f", 0., MAX_PIXELS, 1., 0.); IUFillNumber(&FrameN[1], "Y", "Y", "%.0f", 0., MAX_PIXELS, 1., 0.); IUFillNumber(&FrameN[2], "WIDTH", "Width", "%.0f", 0., MAX_PIXELS, 1., 0.); IUFillNumber(&FrameN[3], "HEIGHT", "Height", "%.0f", 0., MAX_PIXELS, 1., 0.); IUFillNumberVector(&FrameNP, FrameN, NARRAY(FrameN), mydev, "CCD_FRAME", "Frame", IMAGE_GROUP, IP_RW, 60, IPS_IDLE); IUFillNumber(&BinningN[0], "HOR_BIN", "X", "%0.f", 1., MAXHBIN, 1., 1.); IUFillNumber(&BinningN[1], "VER_BIN", "Y", "%0.f", 1., MAXVBIN, 1., 1.); IUFillNumberVector(&BinningNP, BinningN, NARRAY(BinningN), mydev, "CCD_BINNING", "Binning", IMAGE_GROUP, IP_RW, 60, IPS_IDLE); IUFillNumber(&ExposeTimeN[0], "DURATION", "Duration (s)", "%5.2f", 0., 36000., 0.5, 1.); IUFillNumberVector(&ExposeTimeNP, ExposeTimeN, NARRAY(ExposeTimeN), mydev, "CCD_EXPOSE_DURATION", "Expose", EXPOSE_GROUP, IP_RW, 60, IPS_IDLE); IUFillNumber(&TemperatureN[0], "TEMPERATURE", "Temperature", "%+06.2f", MIN_CCD_TEMP, MAX_CCD_TEMP, 0.2, 0.); IUFillNumberVector(&TemperatureNP, TemperatureN, NARRAY(TemperatureN), mydev, "CCD_TEMPERATURE", "Expose", EXPOSE_GROUP, IP_RW, 60, IPS_IDLE); strcpy(imageB.name, "CCD1"); strcpy(imageB.label, "Feed"); strcpy(imageB.format, ""); imageB.blob = 0; imageB.bloblen = 0; imageB.size = 0; imageB.bvp = 0; imageB.aux0 = 0; imageB.aux1 = 0; imageB.aux2 = 0; strcpy(imageBP.device, mydev); strcpy(imageBP.name, "Video"); strcpy(imageBP.label, "Video"); strcpy(imageBP.group, COMM_GROUP); strcpy(imageBP.timestamp, ""); imageBP.p = IP_RO; imageBP.timeout = 0; imageBP.s = IPS_IDLE; imageBP.bp = &imageB; imageBP.nbp = 1; imageBP.aux = 0; //loadXMLModel(); } bool ApogeeCam::loadXMLModel() { LilXML *XMLParser = newLilXML(); XMLEle *root = NULL, *camera = NULL; XMLAtt *modelName; FILE *modelSpecFile = NULL; char errmsg[1024]; int ncams = 0; //IDLog("Top dir is "TOP_DATADIR, NULL); modelSpecFile = fopen(TOP_DATADIR"/apogee_caminfo.xml", "r"); //modelSpecFile = fopen("/opt/kde3/share/apps/kstars/apogee_caminfo.xml", "r"); if (modelSpecFile == NULL) { IDLog("Error: Unable to open file apogee_caminfo.xml\n"); IDMessage(mydev, "Error: Unable to open file apogee_caminfo.xml"); return false; } root = readXMLFile(modelSpecFile, XMLParser, errmsg); if (root == NULL) { IDLog("Error: Unable to process apogee_caminfo.xml. %s\n", errmsg); IDMessage(mydev, "Error: Unable to process apogee_caminfo.xml. %s\n", errmsg); fclose(modelSpecFile); delLilXML(XMLParser); return false; } for (camera = nextXMLEle (root, 1); camera != NULL; camera = nextXMLEle (root, 0)) { modelName = findXMLAtt(camera, "model"); if (modelName == NULL) continue; ApogeeModelS = (ApogeeModelS == NULL) ? (ISwitch *) malloc (sizeof(ISwitch)) : (ISwitch *) realloc(ApogeeModelS, sizeof(ISwitch) * (ncams + 1)); snprintf(ApogeeModelS[ncams].name, MAXINDINAME, "Model%d", ncams); strcpy(ApogeeModelS[ncams].label, valuXMLAtt(modelName)); ApogeeModelS[ncams].s = (ncams == 0) ? ISS_ON : ISS_OFF; ApogeeModelS[ncams].svp = NULL; ApogeeModelS[ncams].aux = NULL; ncams++; } fclose(modelSpecFile); delLilXML(XMLParser); if (ncams > 0) { IUFillSwitchVector(&ApogeeModelSP, ApogeeModelS, ncams, mydev, "Model", "", COMM_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE); return true; } return false; } void ApogeeCam::ISGetProperties(const char */*dev*/) { /* COMM_GROUP */ IDDefSwitch(&PowerSP, NULL); if (loadXMLModel()) IDDefSwitch(&ApogeeModelSP, NULL); else IDMessage(mydev, "Error: Unable to read camera specifications. Driver is disabled."); IDDefBLOB(&imageBP, NULL); /* Expose */ IDDefSwitch(&FrameTypeSP, NULL); IDDefNumber(&ExposeTimeNP, NULL); IDDefNumber(&TemperatureNP, NULL); /* Image Group */ IDDefNumber(&FrameNP, NULL); IDDefNumber(&BinningNP, NULL); IDLog("Apogee Driver Debug Enabled\n"); } void ApogeeCam::ISNewSwitch (const char */*dev*/, const char *name, ISState *states, char *names[], int n) { /* Connection */ if (!strcmp (name, PowerSP.name)) { IUResetSwitches(&PowerSP); IUUpdateSwitches(&PowerSP, states, names, n); connectCCD(); return; } /* Frame Type */ if (!strcmp(FrameTypeSP.name, name)) { if (checkPowerS(&FrameTypeSP)) return; IUResetSwitches(&FrameTypeSP); IUUpdateSwitches(&FrameTypeSP, states, names, n); FrameTypeSP.s = IPS_OK; IDSetSwitch(&FrameTypeSP, NULL); return; } /* Apogee Model */ if (!strcmp(ApogeeModelSP.name, name)) { IUResetSwitches(&ApogeeModelSP); IUUpdateSwitches(&ApogeeModelSP, states, names, n); ApogeeModelSP.s = IPS_OK; IDSetSwitch(&ApogeeModelSP, NULL); return; } } void ApogeeCam::ISNewText (const char */*dev*/, const char */*name*/, char **/*texts[]*/, char **/*names[]*/, int /*n*/) { } void ApogeeCam::ISNewNumber (const char */*dev*/, const char *name, double values[], char *names[], int n) { /* Exposure time */ if (!strcmp (ExposeTimeNP.name, name)) { if (checkPowerN(&ExposeTimeNP)) return; if (ExposeTimeNP.s == IPS_BUSY) { cam->Reset(); ExposeTimeNP.s = IPS_IDLE; ExposeTimeN[0].value = 0; IDSetNumber(&ExposeTimeNP, "Exposure cancelled."); IDLog("Exposure Cancelled.\n"); return; } ExposeTimeNP.s = IPS_IDLE; IUUpdateNumbers(&ExposeTimeNP, values, names, n); IDLog("Exposure Time is: %g\n", ExposeTimeN[0].value); handleExposure(NULL); return; } if (!strcmp(TemperatureNP.name, name)) { if (checkPowerN(&TemperatureNP)) return; TemperatureNP.s = IPS_IDLE; if (values[0] < MIN_CCD_TEMP || values[0] > MAX_CCD_TEMP) { IDSetNumber(&TemperatureNP, "Error: valid range of temperature is from %d to %d", MIN_CCD_TEMP, MAX_CCD_TEMP); return; } targetTemp = values[0]; cam->write_CoolerMode(0); cam->write_CoolerMode(1); cam->write_CoolerSetPoint(targetTemp); TemperatureNP.s = IPS_BUSY; IDSetNumber(&TemperatureNP, "Setting CCD temperature to %+06.2f C", values[0]); IDLog("Setting CCD temperature to %+06.2f C\n", values[0]); return; } if (!strcmp(FrameNP.name, name)) { if (checkPowerN(&FrameNP)) return; FrameNP.s = IPS_OK; IUUpdateNumbers(&FrameNP, values, names, n); cam->m_StartX = (int) FrameN[0].value; cam->m_StartY = (int) FrameN[1].value; cam->m_NumX = (int) FrameN[2].value; cam->m_NumY = (int) FrameN[3].value; IDSetNumber(&FrameNP, NULL); } /* end FrameNP */ if (!strcmp(BinningNP.name, name)) { if (checkPowerN(&BinningNP)) return; BinningNP.s = IPS_OK; IUUpdateNumbers(&BinningNP, values, names, n); cam->m_BinX = (int) BinningN[0].value; cam->m_BinY = (int) BinningN[1].value; IDLog("Binning is: %.0f x %.0f\n", BinningN[0].value, BinningN[1].value); return; } } void ApogeeCam::ISPoll() { static int mtc=5; int readStatus=0; double ccdTemp; if (!isCCDConnected()) return; switch (ExposeTimeNP.s) { case IPS_IDLE: case IPS_OK: break; case IPS_BUSY: readStatus = cam->read_Status(); if (readStatus < 0) { IDLog("Error in exposure! Read status: %d\n", readStatus); ExposeTimeNP.s = IPS_ALERT; ExposeTimeN[0].value = 0; IDSetNumber(&ExposeTimeNP, "Error in exposure procedure. Read states: %d", readStatus); return; } else if (readStatus == Camera_Status_ImageReady) { ExposeTimeN[0].value = 0; ExposeTimeNP.s = IPS_OK; IDSetNumber(&ExposeTimeNP, "Exposure done, downloading image..."); IDLog("Exposure done, downloading image...\n"); /* grab and save image */ grabImage(); return; } ExposeTimeN[0].value --; IDSetNumber(&ExposeTimeNP, NULL); break; case IPS_ALERT: break; } switch (TemperatureNP.s) { case IPS_IDLE: case IPS_OK: mtc--; if (mtc == 0) { TemperatureN[0].value = cam->read_Temperature(); IDSetNumber(&TemperatureNP, NULL); mtc = 5; } break; case IPS_BUSY: ccdTemp = cam->read_Temperature(); if (fabs(targetTemp - ccdTemp) <= TEMP_THRESHOLD) TemperatureNP.s = IPS_OK; mtc = 1; TemperatureN[0].value = ccdTemp; IDSetNumber(&TemperatureNP, NULL); break; case IPS_ALERT: break; } } /* Downloads the image from the CCD row by row and store them in a raw file. N.B. No processing is done on the image */ void ApogeeCam::grabImage() { long err; int img_size, fd; char errmsg[1024]; char filename[] = "/tmp/fitsXXXXXX"; IDLog("In grab Image\n"); if ((fd = mkstemp(filename)) < 0) { IDMessage(mydev, "Error making temporary filename."); IDLog("Error making temporary filename.\n"); return; } close(fd); img_size = APGFrame.width * APGFrame.height * sizeof(unsigned short); IDLog("Allocating memory buffer. Width: %d - Height: %d\n", APGFrame.width, APGFrame.height); APGFrame.img = (unsigned short *) malloc (img_size); if (APGFrame.img == NULL) { IDMessage(mydev, "Not enough memory to store image."); IDLog("Not enough memory to store image.\n"); return; } IDLog("Getting frame buffer from camera...\n"); if (!cam->GetImage( APGFrame.img , APGFrame.width, APGFrame.height )) { free(APGFrame.img); IDMessage(mydev, "GetImage() failed."); IDLog("GetImage() failed."); return; } IDLog("Done with getting frame buffer, writing FITS file\n"); err = writeFITS(filename, errmsg); if (err) { free(APGFrame.img); IDMessage(mydev, errmsg, NULL); return; } free(APGFrame.img); IDLog("All good, returning\n"); } int ApogeeCam::writeFITS(char *filename, char errmsg[]) { #if 0 FITS_FILE* ofp; int bpp, bpsl, width, height; long nbytes; FITS_HDU_LIST *hdu; IDLog("in write FITS, opening filename %s\n", filename); ofp = fits_open (filename, "w"); if (!ofp) { sprintf(errmsg, "Error: cannot open file for writing."); return (-1); } width = APGFrame.width; height = APGFrame.height; bpp = sizeof(unsigned short); /* Bytes per Pixel */ bpsl = bpp * APGFrame.width; /* Bytes per Line */ nbytes = 0; IDLog("Creating FITS header\n"); hdu = create_fits_header (ofp, width, height, bpp); if (hdu == NULL) { sprintf(errmsg, "Error: creating FITS header failed."); return (-1); } if (fits_write_header (ofp, hdu) < 0) { sprintf(errmsg, "Error: writing to FITS header failed."); return (-1); } IDLog("Converting to BIG Endian\n"); for (int i=0; i < height; i++) for (int j=0 ; j < width; j++) APGFrame.img[width * i + j] = getBigEndian( (APGFrame.img[width * i + j]) ); IDLog("Writing frame to disk\n"); for (int i= 0; i < height ; i++) { fwrite(APGFrame.img + (i * width), 2, width, ofp->fp); nbytes += bpsl; } IDLog("Calculating nbytes\n"); nbytes = nbytes % FITS_RECORD_SIZE; if (nbytes) { while (nbytes++ < FITS_RECORD_SIZE) putc (0, ofp->fp); } if (ferror (ofp->fp)) { sprintf(errmsg, "Error: write error occurred"); return (-1); } IDLog("Closing ofp\n"); fits_close (ofp); /* Success */ ExposeTimeNP.s = IPS_OK; IDSetNumber(&ExposeTimeNP, NULL); IDLog("Loading FITS image...\n"); IDLog("Uploading filename\n"); uploadFile(filename); IDLog("Uploading done, returning\n"); #endif return 0; } void ApogeeCam::uploadFile(char * filename) { FILE * fitsFile; unsigned char *fitsData, *compressedData; int r=0; unsigned int i =0, nr = 0; uLongf compressedBytes=0; uLong totalBytes; struct stat stat_p; IDLog("in upload file, will stat file now\n"); if ( -1 == stat (filename, &stat_p)) { IDLog(" Error occurred attempting to stat %s\n", filename); return; } totalBytes = stat_p.st_size; fitsData = (unsigned char *) malloc (sizeof(unsigned char) * totalBytes); compressedData = (unsigned char *) malloc (sizeof(unsigned char) * totalBytes + totalBytes / 64 + 16 + 3); if (fitsData == NULL || compressedData == NULL) { IDLog("Error! low memory. Unable to initialize fits buffers.\n"); if (fitsData) free(fitsData); if (compressedData) free(compressedData); return; } IDLog("opening file\n"); fitsFile = fopen(filename, "r"); if (fitsFile == NULL) return; IDLog("Reading file from disk\n"); /* #1 Read file from disk */ for (i=0; i < totalBytes; i+= nr) { nr = fread(fitsData + i, 1, totalBytes - i, fitsFile); if (nr <= 0) { IDLog("Error reading temporary FITS file.\n"); return; } } fclose(fitsFile); compressedBytes = sizeof(char) * totalBytes + totalBytes / 64 + 16 + 3; IDLog("Compressing data\n"); /* #2 Compress it */ r = compress2(compressedData, &compressedBytes, fitsData, totalBytes, 9); if (r != Z_OK) { /* this should NEVER happen */ IDLog("internal error - compression failed: %d\n", r); return; } IDLog("Sending blob. bloblen %ld - size %ld\n", compressedBytes, totalBytes); /* #3 Send it */ imageB.blob = compressedData; imageB.bloblen = compressedBytes; imageB.size = totalBytes; strcpy(imageB.format, ".fits.z"); imageBP.s = IPS_OK; IDSetBLOB (&imageBP, NULL); free (fitsData); free (compressedData); } /* Initiates the exposure procedure */ void ApogeeCam::handleExposure(void */*p*/) { int curFrame = getOnSwitch(&FrameTypeSP); switch (curFrame) { /* Light frame */ case LIGHT_FRAME: if (!cam->Expose( (int) ExposeTimeN[0].value, true )) { ExposeTimeNP.s = IPS_IDLE; IDSetNumber(&ExposeTimeNP, "Light Camera exposure failed."); IDLog("Light Camera exposure failed.\n"); return; } break; /* BIAS frame is the same as DARK but with minimum period. i.e. readout from camera electronics. */ case BIAS_FRAME: if (!cam->Expose( 0.05 , false )) { ExposeTimeNP.s = IPS_IDLE; IDSetNumber(&ExposeTimeNP, "Bias Camera exposure failed."); IDLog("Bias Camera exposure failed.\n"); return; } break; /* Dark frame */ case DARK_FRAME: if (!cam->Expose( (int) ExposeTimeN[0].value , false )) { ExposeTimeNP.s = IPS_IDLE; IDSetNumber(&ExposeTimeNP, "Dark Camera exposure failed."); IDLog("Dark Camera exposure failed.\n"); return; } break; case FLAT_FRAME: if (!cam->Expose( (int) ExposeTimeN[0].value , true )) { ExposeTimeNP.s = IPS_IDLE; IDSetNumber(&ExposeTimeNP, "Flat Camera exposure failed."); IDLog("Flat Camera exposure failed.\n"); return; } break; } APGFrame.frameType = curFrame; APGFrame.width = (int) FrameN[2].value; APGFrame.height = (int) FrameN[3].value; APGFrame.expose = (int) ExposeTimeN[0].value; APGFrame.temperature = TemperatureN[0].value; APGFrame.binX = (int) BinningN[0].value; APGFrame.binY = (int) BinningN[1].value; ExposeTimeNP.s = IPS_BUSY; IDSetNumber(&ExposeTimeNP, "Taking a %g seconds frame...", ExposeTimeN[0].value); IDLog("Taking a frame. Width: %d - Height: %d - expose %d - temperature %g - binX %d - binY %d\n", APGFrame.width, APGFrame.height, APGFrame.expose, APGFrame.temperature, APGFrame.binX, APGFrame.binY); } /* Retrieves basic data from the CCD upon connection like temperature, array size, firmware..etc */ void ApogeeCam::getBasicData() { // Maximum resolution FrameN[2].max = cam->m_NumX; FrameN[3].max = cam->m_NumY; IUUpdateMinMax(&FrameNP); // Maximum Bin BinningN[0].max = cam->m_MaxBinX; BinningN[1].max = cam->m_MaxBinX; IUUpdateMinMax(&BinningNP); FrameN[0].value = 0; FrameN[1].value = 0; FrameN[2].min = 0; FrameN[2].max = cam->m_ImgColumns; FrameN[2].value = cam->m_ImgColumns; FrameN[3].min = 0; FrameN[3].max = cam->m_ImgRows; FrameN[3].value = cam->m_ImgRows; IUUpdateMinMax(&FrameNP); IDSetNumber(&FrameNP, NULL); // Current Temperature TemperatureN[0].value = cam->read_Temperature(); IDSetNumber(&TemperatureNP, NULL); } int ApogeeCam::getOnSwitch(ISwitchVectorProperty *sp) { int i=0; for (i=0; i < sp->nsp ; i++) { /*IDLog("Switch %s is %s\n", sp->sp[i].name, sp->sp[i].s == ISS_ON ? "On" : "Off");*/ if (sp->sp[i].s == ISS_ON) return i; } return -1; } int ApogeeCam::checkPowerS(ISwitchVectorProperty *sp) { if (PowerSP.s != IPS_OK) { if (!strcmp(sp->label, "")) IDMessage (mydev, "Cannot change property %s while the CCD is offline.", sp->name); else IDMessage (mydev, "Cannot change property %s while the CCD is offline.", sp->label); sp->s = IPS_IDLE; IDSetSwitch(sp, NULL); return -1; } return 0; } int ApogeeCam::checkPowerN(INumberVectorProperty *np) { if (PowerSP.s != IPS_OK) { if (!strcmp(np->label, "")) IDMessage (mydev, "Cannot change property %s while the CCD is offline.", np->name); else IDMessage (mydev, "Cannot change property %s while the CCD is offline.", np->label); np->s = IPS_IDLE; IDSetNumber(np, NULL); return -1; } return 0; } int ApogeeCam::checkPowerT(ITextVectorProperty *tp) { if (PowerSP.s != IPS_OK) { if (!strcmp(tp->label, "")) IDMessage (mydev, "Cannot change property %s while the CCD is offline.", tp->name); else IDMessage (mydev, "Cannot change property %s while the CCD is offline.", tp->label); tp->s = IPS_IDLE; IDSetText(tp, NULL); return -1; } return 0; } void ApogeeCam::connectCCD() { /* USB by default {USB, SERIAL, PARALLEL, INET} */ switch (PowerS[0].s) { case ISS_ON: if (initCamera()) { /* Sucess! */ PowerS[0].s = ISS_ON; PowerS[1].s = ISS_OFF; PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "CCD is online. Retrieving basic data."); IDLog("CCD is online. Retrieving basic data.\n"); getBasicData(); } else { PowerSP.s = IPS_IDLE; PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch(&PowerSP, "Error: no cameras were detected."); IDLog("Error: no cameras were detected.\n"); return; } break; case ISS_OFF: PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_IDLE; IDSetSwitch(&PowerSP, "CCD is offline."); break; } } bool ApogeeCam::initCamera() { LilXML *XMLParser = newLilXML(); XMLEle *root = NULL, *camera = NULL, *ele = NULL; XMLEle *system = NULL, *geometry = NULL, *temp = NULL, *ccd = NULL; XMLAtt *ap; FILE *spFile = NULL; char errmsg[1024]; spFile = fopen(TOP_DATADIR"/apogee_caminfo.xml", "r"); //spFile = fopen("/opt/kde3/share/apps/kstars/apogee_caminfo.xml", "r"); if (spFile == NULL) { IDLog("Error: Unable to open file apogee_caminfo.xml\n"); IDMessage(mydev, "Error: Unable to open file apogee_caminfo.xml"); return false; } root = readXMLFile(spFile, XMLParser, errmsg); if (root == NULL) { IDLog("Error: Unable to process apogee_caminfo.xml. %s\n", errmsg); IDMessage(mydev, "Error: Unable to process apogee_caminfo.xml. %s\n", errmsg); fclose(spFile); delLilXML(XMLParser); return false; } fclose(spFile); // Let's locate which camera to load the configuration for camera = findXMLEle(root, "Apogee_Camera"); if (camera == NULL) { IDLog("Error: Unable to find Apogee_Camera element.\n"); IDMessage(mydev, "Error: Unable to find Apogee_Camera element."); delLilXML(XMLParser); return false; } IDLog("Looking for %s - len %d\n", ApogeeModelS[getOnSwitch(&ApogeeModelSP)].label, strlen(ApogeeModelS[getOnSwitch(&ApogeeModelSP)].label)); ap = findXMLAtt(camera, "model"); if (!ap) { IDLog("Error: Unable to find attribute model.\n"); IDMessage(mydev, "Error: Unable to find attribute model."); return false; } if (strcmp(valuXMLAtt(ap), ApogeeModelS[getOnSwitch(&ApogeeModelSP)].label)) { IDLog("Camera %s not found in XML file\n", ApogeeModelS[getOnSwitch(&ApogeeModelSP)].label); IDMessage(mydev, "Camera %s not found in XML file\n", ApogeeModelS[getOnSwitch(&ApogeeModelSP)].label); delLilXML(XMLParser); return false; } // Let's get the subsections now system = findXMLEle(camera, "System"); geometry = findXMLEle(camera, "Geometry"); temp = findXMLEle(camera, "Temp"); ccd = findXMLEle(camera, "CCD"); if (system == NULL) { IDLog("Error: Unable to find System element in camera.\n"); IDMessage(mydev, "Error: Unable to find System element in camera."); delLilXML(XMLParser); return false; } if (geometry == NULL) { IDLog("Error: Unable to find Geometry element in camera.\n"); IDMessage(mydev, "Error: Unable to find Geometry element in camera."); delLilXML(XMLParser); return false; } if (temp == NULL) { IDLog("Error: Unable to find Temp element in camera.\n"); IDMessage(mydev, "Error: Unable to find Temp element in camera."); delLilXML(XMLParser); return false; } if (ccd == NULL) { IDLog("Error: Unable to find CCD element in camera.\n"); IDMessage(mydev, "Error: Unable to find CCD element in camera."); delLilXML(XMLParser); return false; } cam = new CCameraIO(); if (cam == NULL) { IDLog("Error: Failed to create CCameraIO object.\n"); IDMessage(mydev, "Error: Failed to create CCameraIO object."); delLilXML(XMLParser); return false; } int bAddr = 0x378; int val = 0; XMLAtt* baseAtt = findXMLAtt(system, "Base"); if (baseAtt) bAddr = hextoi(valuXMLAtt(baseAtt)) & 0xFFF; // Rows ap = findXMLAtt(geometry, "Rows"); if (!ap) { IDLog("Error: Unable to find attribute Rows.\n"); IDMessage(mydev, "Error: Unable to find attribute Rows."); delLilXML(XMLParser); return false; } cam->m_Rows = hextoi(valuXMLAtt(ap)); // Columns ap = findXMLAtt(geometry, "Columns"); if (!ap) { IDLog("Error: Unable to find attribute Columns.\n"); IDMessage(mydev, "Error: Unable to find attribute Columns."); delLilXML(XMLParser); return false; } cam->m_Columns = hextoi(valuXMLAtt(ap)); // pp_repeat ele = findXMLEle(system, "PP_Repeat"); if (!ele) { IDLog("Error: Unable to find element PP_Repeat.\n"); IDMessage(mydev, "Error: Unable to find element PP_Repeat."); delLilXML(XMLParser); return false; } val = hextoi(pcdataXMLEle(ele)); if (val > 0 && val <= 1000) cam->m_PPRepeat = val; // Initiate driver if (!cam->InitDriver(0)) { IDLog("Error: Failed to Init Driver.\n"); IDMessage(mydev, "Error: Failed to Init Driver."); delLilXML(XMLParser); return false; } cam->Reset(); // Cable length ele = findXMLEle(system, "Cable"); if (!ele) { IDLog("Error: Unable to find element Cable.\n"); IDMessage(mydev, "Error: Unable to find element Cable."); delLilXML(XMLParser); return false; } if (!strcmp("Long", pcdataXMLEle(ele))) { cam->write_LongCable( true ); IDLog("Cable is long\n"); } else { cam->write_LongCable( false ); IDLog("Cable is short\n"); } if (!cam->read_Present()) { IDLog("Error: read_Present() failed.\n"); IDMessage(mydev, "Error: read_Present() failed."); delLilXML(XMLParser); return false; } // Default settings cam->write_UseTrigger( false ); cam->write_ForceShutterOpen( false ); // High priority ele = findXMLEle(system, "High_Priority"); if (ele) { if (!strcmp(pcdataXMLEle(ele), "True")) cam->m_HighPriority = true; else cam->m_HighPriority = false; } // Data bits ele = findXMLEle(system, "Data_Bits"); if (ele) { val = hextoi(pcdataXMLEle(ele)); if (val >= 8 && val <= 18) cam->m_DataBits = val; } // Sensor ele = findXMLEle(system, "Sensor"); if (ele) { if (!strcmp(pcdataXMLEle(ele), "CCD")) cam->m_SensorType = Camera_SensorType_CCD; else cam->m_SensorType = Camera_SensorType_CMOS; } // Mode ele = findXMLEle(system, "Mode"); if (ele) { val = hextoi(pcdataXMLEle(ele)) & 0xF; cam->write_Mode( val ); IDLog("Mode %d\n", val); } else cam->write_Mode( 0 ); // Test ele = findXMLEle(system, "Test"); if (ele) { val = hextoi(pcdataXMLEle(ele)) & 0xF; cam->write_TestBits( val ); IDLog("Test bits %d\n", val); } else cam->write_TestBits( 0 ); // Test2 ele = findXMLEle(system, "Test2"); if (ele) { val = hextoi(pcdataXMLEle(ele)) & 0xF; cam->write_Test2Bits( val ); IDLog("Test 2 bits %d\n", val); } else cam->write_Test2Bits( 0 ); // Shutter Speed ele = findXMLEle(system, "Shutter_Speed"); if (ele) { cam->m_MaxExposure = 10485.75; if (!strcmp(pcdataXMLEle(ele), "Normal")) { cam->m_FastShutter = false; cam->m_MinExposure = 0.01; IDLog("Shutter speed normal\n"); } else if ( (!strcmp(pcdataXMLEle(ele), "Fast")) || (!strcmp(pcdataXMLEle(ele), "Dual")) ) { cam->m_FastShutter = true; cam->m_MinExposure = 0.001; IDLog("Shutter speed fast\n"); } } // Shutter Bits ele = findXMLEle(system, "Shutter_Bits"); if (ele) { val = hextoi(pcdataXMLEle(ele)); cam->m_FastShutterBits_Mode = val & 0x0F; cam->m_FastShutterBits_Test = ( val & 0xF0 ) >> 4; IDLog("Shutter bits %d\n", val); } // Max X Bin ele = findXMLEle(system, "MaxBinX"); if (ele) { val = hextoi(pcdataXMLEle(ele)); if (val >= 1 && val <= MAXHBIN) cam->m_MaxBinX = val; } // Max Y Bin ele = findXMLEle(system, "MaxBinY"); if (ele) { val = hextoi(pcdataXMLEle(ele)); if (val >= 1 && val <= MAXVBIN) cam->m_MaxBinY = val; } // Guider Relays ele = findXMLEle(system, "Guider_Relays"); if (ele) { if (!strcmp(pcdataXMLEle(ele), "True")) cam->m_GuiderRelays = true; else cam->m_GuiderRelays = false; } // Timeout ele = findXMLEle(system, "Timeout"); if (ele) { double dval = atof(pcdataXMLEle(ele)); if (dval >= 0.0 && dval <= 10000.0) cam->m_Timeout = dval; } // BIC ele = findXMLEle(geometry, "BIC"); if (ele) { val = hextoi(pcdataXMLEle(ele)); if (val >= 1 && val <= MAXCOLUMNS) cam->m_BIC = val; } // BIR ele = findXMLEle(geometry, "BIR"); if (ele) { val = hextoi(pcdataXMLEle(ele)); if (val >= 1 && val <= MAXROWS) cam->m_BIR = val; } // SKIPC ele = findXMLEle(geometry, "SKIPC"); if (ele) { val = hextoi(pcdataXMLEle(ele)); if (val >= 1 && val <= MAXCOLUMNS) cam->m_SkipC = val; } // SKIPR ele = findXMLEle(geometry, "SKIPR"); if (ele) { val = hextoi(pcdataXMLEle(ele)); if (val >= 1 && val <= MAXROWS) cam->m_SkipR = val; } // IMG COlS ele = findXMLEle(geometry, "ImgCols"); if (ele) { val = hextoi(pcdataXMLEle(ele)); if (val >= 1 && val <= MAXTOTALCOLUMNS) cam->m_ImgColumns = val; } else cam->m_ImgColumns = cam->m_Columns - cam->m_BIC - cam->m_SkipC; // IMG ROWS ele = findXMLEle(geometry, "ImgRows"); if (ele) { val = hextoi(pcdataXMLEle(ele)); if (val >= 1 && val <= MAXTOTALROWS) cam->m_ImgRows = val; } else cam->m_ImgRows = cam->m_Rows - cam->m_BIR - cam->m_SkipR; // Hor Flush ele = findXMLEle(geometry, "HFlush"); if (ele) { val = hextoi(pcdataXMLEle(ele)); if (val >= 1 && val <= MAXHBIN) cam->m_HFlush = val; } // Ver Flush ele = findXMLEle(geometry, "VFlush"); if (ele) { val = hextoi(pcdataXMLEle(ele)); if (val >= 1 && val <= MAXVBIN) cam->m_VFlush = val; } // Default to full frame cam->m_NumX = cam->m_ImgColumns; cam->m_NumY = cam->m_ImgRows; // Temp Control ap = findXMLAtt(temp, "Control"); if (ap) { if (!strcmp(valuXMLAtt(ap), "True")) cam->m_TempControl = true; else cam->m_TempControl = false; } // Calibration ap = findXMLAtt(temp, "Cal"); if (ap) { val = hextoi(valuXMLAtt(ap)); if (val >= 1 && val <= 255) cam->m_TempCalibration = val; } // Scale ap = findXMLAtt(temp, "Scale"); if (ap) { double dval = atof(valuXMLAtt(ap)); if (dval >= 1.0 && dval <= 10.0) cam->m_TempScale = dval; } // Target ap = findXMLAtt(temp, "Target"); if (ap) { double dval = atof(valuXMLAtt(ap)); if (dval >= -60.0 && dval <= 40.0) cam->write_CoolerSetPoint( dval ); else cam->write_CoolerSetPoint( -10.0 ); // Default IDLog("Target: %g\n", dval); } // Sensor ap = findXMLAtt(ccd, "Sensor"); if (ap) { strncpy (cam->m_Sensor, valuXMLAtt(ap), 255); IDLog("Sensor: %s\n", cam->m_Sensor); } // Color ele = findXMLEle(ccd, "Color"); if (ele) { if (!strcmp(pcdataXMLEle(ele), "True")) { cam->m_Color = true; IDLog("Color: true\n"); } else { cam->m_Color = false; IDLog("Color: false\n"); } } // Noise ele = findXMLEle(ccd, "Noise"); if (ele) cam->m_Noise = atof( pcdataXMLEle(ele) ); // Noise ele = findXMLEle(ccd, "Gain"); if (ele) cam->m_Gain = atof( pcdataXMLEle(ele) ); // Pixel X Size ele = findXMLEle(ccd, "PixelXSize"); if (ele) { cam->m_PixelXSize = atof( pcdataXMLEle(ele) ); IDLog("Pixel X Size: %g\n", cam->m_PixelXSize); } // Pixel Y Size ele = findXMLEle(ccd, "PixelYSize"); if (ele) { cam->m_PixelYSize = atof( pcdataXMLEle(ele) ); IDLog("Pixel Y Size: %g\n", cam->m_PixelYSize); } // Log all values IDLog("Cam Row: %d - Cam Cols: %d - PP_Repeat %d\n",cam->m_Rows, cam->m_Columns, cam->m_PPRepeat); IDLog("High_Priority %s - Data_Bits %d - Sensor %s\n", cam->m_HighPriority ? "true" : "false", cam->m_DataBits, (cam->m_SensorType == Camera_SensorType_CCD) ? "CCD" : "CMOS"); IDLog("Max X Bin: %d - Max Y Bin: %d - Guider Relays: %s\n", cam->m_MaxBinX, cam->m_MaxBinY, cam->m_GuiderRelays ? "true" : "false"); IDLog("BIC: %d - BIR: %d - SKIPC: %d - SKIPR: %d - ImgRows: %d - ImgCols %d\n", cam->m_BIC, cam->m_BIR, cam->m_SkipC, cam->m_SkipR, cam->m_ImgRows, cam->m_ImgColumns); IDLog("HFlush: %d - VFlush: %d - Control: %s - Cal: %d - Scale: %g\n", cam->m_HFlush, cam->m_VFlush, cam->m_TempControl ? "true" : "false", cam->m_TempCalibration, cam->m_TempScale); delLilXML(XMLParser); return true; } /* isCCDConnected: return 1 if we have a connection, 0 otherwise */ int ApogeeCam::isCCDConnected(void) { return ((PowerS[0].s == ISS_ON) ? 1 : 0); } #if 0 FITS_HDU_LIST * ApogeeCam::create_fits_header (FITS_FILE *ofp, uint width, uint height, uint bpp) { FITS_HDU_LIST *hdulist; char temp_s[FITS_CARD_SIZE], expose_s[FITS_CARD_SIZE], binning_s[FITS_CARD_SIZE], frame_s[FITS_CARD_SIZE], pixel_s[FITS_CARD_SIZE]; char obsDate[FITS_CARD_SIZE]; snprintf(obsDate, FITS_CARD_SIZE, "DATE-OBS= '%s' /Observation Date UTC", timestamp()); hdulist = fits_add_hdu (ofp); if (hdulist == NULL) return (NULL); hdulist->used.simple = 1; hdulist->bitpix = 16; hdulist->naxis = 2; hdulist->naxisn[0] = width; hdulist->naxisn[1] = height; hdulist->naxisn[2] = bpp; hdulist->used.datamin = 1; hdulist->datamin = min(); hdulist->used.datamax = 1; hdulist->datamax = max(); hdulist->used.bzero = 1; hdulist->bzero = 0.0; hdulist->used.bscale = 1; hdulist->bscale = 1.0; snprintf(temp_s, FITS_CARD_SIZE, "CCD-TEMP= %g / degrees celcius", APGFrame.temperature); snprintf(expose_s, FITS_CARD_SIZE, "EXPOSURE= %d / milliseconds", APGFrame.expose); snprintf(binning_s, FITS_CARD_SIZE, "BINNING = '(%d x %d)'", APGFrame.binX, APGFrame.binY); snprintf(pixel_s, FITS_CARD_SIZE, "PIX-SIZ = '%0.f x %0.f microns square'", cam->m_PixelXSize, cam->m_PixelYSize); switch (APGFrame.frameType) { case LIGHT_FRAME: strcpy(frame_s, "FRAME = 'Light'"); break; case BIAS_FRAME: strcpy(frame_s, "FRAME = 'Bias'"); break; case FLAT_FRAME: strcpy(frame_s, "FRAME = 'Flat Field'"); break; case DARK_FRAME: strcpy(frame_s, "FRAME = 'Dark'"); break; } fits_add_card (hdulist, frame_s); fits_add_card (hdulist, temp_s); fits_add_card (hdulist, expose_s); fits_add_card (hdulist, pixel_s); fits_add_card (hdulist, "INSTRUME= 'Apogee CCD'"); fits_add_card (hdulist, obsDate); return (hdulist); } #endif // Convert a string to a decimal or hexadecimal integer // Code taken from Dave Mills Apogee driver unsigned short ApogeeCam::hextoi(char *instr) { unsigned short val, tot = 0; bool IsHEX = false; long n = strlen( instr ); if ( n > 1 ) { // Look for hex format e.g. 8Fh, A3H or 0x5D if ( instr[ n - 1 ] == 'h' || instr[ n - 1 ] == 'H' ) IsHEX = true; else if ( *instr == '0' && *(instr+1) == 'x' ) { IsHEX = true; instr += 2; } } if ( IsHEX ) { while (instr && *instr && isxdigit(*instr)) { val = *instr++ - '0'; if (9 < val) val -= 7; tot <<= 4; tot |= (val & 0x0f); } } else tot = atoi( instr ); return tot; } double ApogeeCam::min() { double lmin = APGFrame.img[0]; int ind=0, i, j; for (i= 0; i < APGFrame.height ; i++) for (j= 0; j < APGFrame.width; j++) { ind = (i * APGFrame.width) + j; if (APGFrame.img[ind] < lmin) lmin = APGFrame.img[ind]; } return lmin; } double ApogeeCam::max() { double lmax = APGFrame.img[0]; int ind=0, i, j; for (i= 0; i < APGFrame.height ; i++) for (j= 0; j < APGFrame.width; j++) { ind = (i * APGFrame.width) + j; if (APGFrame.img[ind] > lmax) lmax = APGFrame.img[ind]; } return lmax; } indi-0.5/src/lx200_16.cpp0000644000175000017500000002320610610474326012565 0ustar jrjr/* LX200 16" Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include "lx200_16.h" #include "lx200driver.h" #define LX16GROUP "GPS/16 inch Features" extern LX200Generic *telescope; extern ITextVectorProperty Time; extern int MaxReticleFlashRate; //void turnFanOn(); //void turnFanOff(); //void seekHomeAndSave(); // void seekHomeAndSet(); /** Turns the field derotator On or Off. This command applies only to 16" LX200. @param turnOn if turnOn is true, the derotator is turned on, otherwise, it is turned off. */ // void fieldDeRotator(bool turnOn); /** Sets object Altitude. \n @returns true if object's altitude is successfully set. */ //bool setObjAlt(int degrees, int minutes); /** Sets object Azimuth. \n @returns true if object's azimuth is successfully set. */ // bool setObjAz(int degrees, int minutes); static ISwitch FanStatusS[] = { {"On", "", ISS_OFF, 0, 0}, {"Off", "", ISS_OFF, 0, 0}}; static ISwitch HomeSearchS[] = { {"Save home", "", ISS_OFF, 0, 0} , {"Set home", "", ISS_OFF, 0, 0}}; static ISwitch FieldDeRotatorS[] = { {"On", "", ISS_OFF, 0, 0}, {"Off", "", ISS_OFF,0 ,0}}; //static ISwitch SlewAltAzS[] = { {"Slew To Alt/Az", ISS_ON}}; #define MAXINDINAME 32 #define MAXINDILABEL 32 #define MAXINDIDEVICE 32 #define MAXINDIGROUP 32 #define MAXINDIFORMAT 32 static ISwitchVectorProperty FanStatusSw = { mydev, "Fan", "", LX16GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, FanStatusS, NARRAY(FanStatusS), "", 0}; static ISwitchVectorProperty HomeSearchSw = { mydev, "Park", "", LX16GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, HomeSearchS, NARRAY(HomeSearchS), "", 0}; static ISwitchVectorProperty FieldDeRotatorSw = { mydev, "Field De-rotator", "", LX16GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, FieldDeRotatorS, NARRAY(FieldDeRotatorS), "", 0}; //static ISwitches SlewAltAzSw = { mydev, "AltAzSet", "On Alt/Az Set", SlewAltAzS, NARRAY(SlewAltAzS), ILS_IDLE, 0, LX16Group}; /* horizontal position */ static INumber hor[] = { {"ALT", "Alt D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}, {"AZ", "Az D:M:S", "%10.6m", 0., 360., 0., 0., 0, 0, 0}}; static INumberVectorProperty horNum = { mydev, "HORIZONTAL_COORD", "Horizontal Coords", LX16GROUP, IP_RW, 0, IPS_IDLE, hor, NARRAY(hor), "", 0}; void changeLX200_16DeviceName(const char * newName) { strcpy(horNum.device, newName); strcpy(FanStatusSw.device, newName); strcpy(HomeSearchSw.device, newName); strcpy(FieldDeRotatorSw.device,newName); } LX200_16::LX200_16() : LX200Autostar() { } void LX200_16::ISGetProperties (const char *dev) { if (dev && strcmp (thisDevice, dev)) return; // process parent first LX200Autostar::ISGetProperties(dev); IDDefNumber (&horNum, NULL); IDDefSwitch (&FanStatusSw, NULL); IDDefSwitch (&HomeSearchSw, NULL); IDDefSwitch (&FieldDeRotatorSw, NULL); } void LX200_16::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { // ignore if not ours // if (strcmp (dev, thisDevice)) return; LX200Autostar::ISNewText (dev, name, texts, names, n); } void LX200_16::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { double newAlt=0, newAz=0; char altStr[64], azStr[64]; int err; // ignore if not ours // if (strcmp (dev, thisDevice)) return; if ( !strcmp (name, horNum.name) ) { int i=0, nset=0; if (checkPower(&horNum)) return; for (nset = i = 0; i < n; i++) { INumber *horp = IUFindNumber (&horNum, names[i]); if (horp == &hor[0]) { newAlt = values[i]; nset += newAlt >= -90. && newAlt <= 90.0; } else if (horp == &hor[1]) { newAz = values[i]; nset += newAz >= 0. && newAz <= 360.0; } } if (nset == 2) { if ( (err = setObjAz(fd, newAz)) < 0 || (err = setObjAlt(fd, newAlt)) < 0) { handleError(&horNum, err, "Setting Alt/Az"); return; } horNum.s = IPS_OK; //horNum.n[0].value = values[0]; //horNum.n[1].value = values[1]; targetAz = newAz; targetAlt = newAlt; fs_sexa(azStr, targetAz, 2, 3600); fs_sexa(altStr, targetAlt, 2, 3600); IDSetNumber (&horNum, "Attempting to slew to Alt %s - Az %s", altStr, azStr); handleAltAzSlew(); } else { horNum.s = IPS_IDLE; IDSetNumber(&horNum, "Altitude or Azimuth missing or invalid"); } return; } LX200Autostar::ISNewNumber (dev, name, values, names, n); } void LX200_16::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { int index; int err; if (strcmp (dev, thisDevice)) return; if (!strcmp(name, FanStatusSw.name)) { if (checkPower(&FanStatusSw)) return; IUResetSwitches(&FanStatusSw); IUUpdateSwitches(&FanStatusSw, states, names, n); index = getOnSwitch(&FanStatusSw); if (index == 0) { if ( (err = turnFanOn(fd)) < 0) { handleError(&FanStatusSw, err, "Changing fan status"); return; } } else { if ( (err = turnFanOff(fd)) < 0) { handleError(&FanStatusSw, err, "Changing fan status"); return; } } FanStatusSw.s = IPS_OK; IDSetSwitch (&FanStatusSw, index == 0 ? "Fan is ON" : "Fan is OFF"); return; } if (!strcmp(name, HomeSearchSw.name)) { if (checkPower(&HomeSearchSw)) return; IUResetSwitches(&HomeSearchSw); IUUpdateSwitches(&HomeSearchSw, states, names, n); index = getOnSwitch(&HomeSearchSw); index == 0 ? seekHomeAndSave(fd) : seekHomeAndSet(fd); HomeSearchSw.s = IPS_BUSY; IDSetSwitch (&HomeSearchSw, index == 0 ? "Seek Home and Save" : "Seek Home and Set"); return; } if (!strcmp(name, FieldDeRotatorSw.name)) { if (checkPower(&FieldDeRotatorSw)) return; IUResetSwitches(&FieldDeRotatorSw); IUUpdateSwitches(&FieldDeRotatorSw, states, names, n); index = getOnSwitch(&FieldDeRotatorSw); index == 0 ? seekHomeAndSave(fd) : seekHomeAndSet(fd); FieldDeRotatorSw.s = IPS_OK; IDSetSwitch (&FieldDeRotatorSw, index == 0 ? "Field deRotator is ON" : "Field deRotator is OFF"); return; } LX200Autostar::ISNewSwitch (dev, name, states, names, n); } void LX200_16::handleAltAzSlew() { int i=0; char altStr[64], azStr[64]; if (horNum.s == IPS_BUSY) { abortSlew(fd); // sleep for 100 mseconds usleep(100000); } if ((i = slewToAltAz(fd))) { horNum.s = IPS_IDLE; IDSetNumber(&horNum, "Slew not possible"); return; } horNum.s = IPS_BUSY; fs_sexa(azStr, targetAz, 2, 3600); fs_sexa(altStr, targetAlt, 2, 3600); IDSetNumber(&horNum, "Slewing to Alt %s - Az %s", altStr, azStr); return; } void LX200_16::ISPoll () { int searchResult=0; double dx, dy; int err; LX200Autostar::ISPoll(); switch (HomeSearchSw.s) { case IPS_IDLE: break; case IPS_BUSY: if ( (err = getHomeSearchStatus(fd, &searchResult)) < 0) { handleError(&HomeSearchSw, err, "Home search"); return; } if (searchResult == 0) { HomeSearchSw.s = IPS_IDLE; IDSetSwitch(&HomeSearchSw, "Home search failed."); } else if (searchResult == 1) { HomeSearchSw.s = IPS_OK; IDSetSwitch(&HomeSearchSw, "Home search successful."); } else if (searchResult == 2) IDSetSwitch(&HomeSearchSw, "Home search in progress..."); else { HomeSearchSw.s = IPS_IDLE; IDSetSwitch(&HomeSearchSw, "Home search error."); } break; case IPS_OK: break; case IPS_ALERT: break; } switch (horNum.s) { case IPS_IDLE: break; case IPS_BUSY: if ( (err = getLX200Az(fd, ¤tAz)) < 0 || (err = getLX200Alt(fd, ¤tAlt)) < 0) { IDSetNumber(&horNum, NULL); handleError(&horNum, err, "Get Alt/Az"); return; } dx = targetAz - currentAz; dy = targetAlt - currentAlt; horNum.np[0].value = currentAlt; horNum.np[1].value = currentAz; IDLog("targetAz is %g, currentAz is %g\n", targetAz, currentAz); IDLog("targetAlt is %g, currentAlt is %g\n**********************\n", targetAlt, currentAlt); // accuracy threshold (3'), can be changed as desired. if ( fabs(dx) <= 0.05 && fabs(dy) <= 0.05) { horNum.s = IPS_OK; currentAz = targetAz; currentAlt = targetAlt; IDSetNumber (&horNum, "Slew is complete"); } else IDSetNumber (&horNum, NULL); break; case IPS_OK: break; case IPS_ALERT: break; } } void LX200_16::getBasicData() { getLX200Az(fd, &targetAz); getLX200Alt(fd, &targetAlt); horNum.np[0].value = targetAlt; horNum.np[1].value = targetAz; IDSetNumber (&horNum, NULL); LX200Autostar::getBasicData(); } indi-0.5/src/LICENSE0000644000175000017500000006350610605175713011724 0ustar jrjr GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! indi-0.5/src/base64.h0000644000175000017500000000317610610474336012150 0ustar jrjr#if 0 INDI Copyright (C) 2003 Elwood C. Downey This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #ifndef BASE64_H #define BASE64_H #ifdef __cplusplus extern "C" { #endif /** * \defgroup base64 Base 64 Functions: Convert from and to base64 */ /*@{*/ /** \brief Convert bytes array to base64. \param out output buffer in base64. The buffer size must be at least (4 * inlen / 3 + 4) bytes long. \param in input binary buffer \param inlen number of bytes to convert \return 0 on success, -1 on failure. */ extern int to64frombits(unsigned char *out, const unsigned char *in, int inlen); /** \brief Convert base64 to bytes array. \param out output buffer in bytes. The buffer size must be at least (3 * size_of_in_buffer / 4) bytes long. \param in input base64 buffer \return 0 on success, -1 on failure. */ extern int from64tobits(char *out, const char *in); /*@}*/ #ifdef __cplusplus } #endif #endif indi-0.5/src/robofocus.c0000644000175000017500000010107210610474331013045 0ustar jrjr #if 0 Robofocus driver Copyright (C) 2006 Markus Wildi, markus.wildi@datacomm.ch This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif /* Standard headers */ #include #include #include /* INDI Core headers */ /* indidevapi.h contains API declerations */ #include "indidevapi.h" /* INDI Eventloop mechanism */ #include "eventloop.h" /* INDI Common Routines/RS232 */ #include "indicom.h" #include "robofocusdriver.h" /* Definitions */ #define mydev "Robofocus" /* Device name */ #define CONNECTION_GROUP "Connection" /* Group name */ #define MOTION_GROUP "Motion" #define currentSpeed SpeedN[0].value #define currentPosition PositionN[0].value #define currentTemperature TemperatureN[0].value #define currentBacklash SetBacklashN[0].value #define currentDuty SettingsN[0].value #define currentDelay SettingsN[1].value #define currentTicks SettingsN[2].value #define currentRelativeMovement RelMovementN[0].value #define currentAbsoluteMovement AbsMovementN[0].value #define currentSetBacklash SetBacklashN[0].value #define currentMinPosition MinMaxPositionN[0].value #define currentMaxPosition MinMaxPositionN[1].value #define currentMaxTravel MaxTravelN[0].value int fd; /* Rs 232 file handle */ int wp ; /* Work proc ID */ /* Function protptypes */ void connectRobofocus(void); static void ISInit() ; void ISWorkProc (void) ; int updateRFPosition(int fd, double *value) ; int updateRFTemperature(int fd, double *value) ; int updateRFBacklash(int fd, double *value) ; int updateRFFirmware(int fd, char *rf_cmd) ; int updateRFMotorSettings(int fd, double *duty, double *delay, double *ticks) ; int updateRFPositionRelativeInward(int fd, double *value) ; int updateRFPositionRelativeOutward(int fd, double *value) ; int updateRFPositionAbsolute(int fd, double *value) ; int updateRFPowerSwitches(int fd, int s, int i, int *cur_s1LL, int *cur_s2LR, int *cur_s3RL, int *cur_s4RR) ; int updateRFMaxPosition(int fd, double *value) ; int updateRFSetPosition(int fd, double *value) ; /* operational info */ /* RS 232 Connection */ static ISwitch PowerS[] = { {"CONNECT", "Connect", ISS_OFF, 0, 0}, {"DISCONNECT", "Disconnect", ISS_OFF, 0, 0}, }; static ISwitchVectorProperty PowerSP = { mydev /* Device name */ , "CONNECTION" /* Property name */ , "Connection" /* Property label */ , CONNECTION_GROUP /* Property group */ , IP_RW /* Property premission, it's both read and write */ , ISR_1OFMANY /* Switch behavior. Only 1 of many switches are allowed to be on at the same time */ , 0 /* Timeout, 0 seconds */ , IPS_IDLE /* Initial state is idle */ , PowerS /* Switches comprimising this vector that we defined above */ , NARRAY(PowerS) /* Number of Switches. NARRAY is defined in indiapi.h */ , "" /* Timestamp, set to 0 */ , 0}; /* auxiluary, set to 0 for now */ /* Serial */ static IText PortT[]= {{"PORT", "Port", 0, 0, 0, 0}}; /* Attention malloc */ static ITextVectorProperty PortTP= { mydev, "DEVICE_PORT", "Ports", CONNECTION_GROUP, IP_RW, 0, IPS_IDLE, PortT, NARRAY(PortT), "", 0 } ; /* Focuser temperature */ static INumber TemperatureN[] = { { "TEMPERATURE", "Celsius", "%6.2f", 0, 65000., 0., 10000., 0, 0, 0}, } ; static INumberVectorProperty TemperatureNP = { mydev, "FOCUS_TEMPERATURE", "Temperature", CONNECTION_GROUP, IP_RO, 0, IPS_IDLE, TemperatureN, NARRAY(TemperatureN), "", 0 } ; /* Settings of the Robofocus */ static INumber SettingsN[] = { { "Duty cycle", "Duty cycle", "%6.0f", 0., 255., 0., 1., 0, 0, 0}, { "Step delay", "Step delay", "%6.0f", 0., 255., 0., 1., 0, 0, 0}, { "Motor Steps", "Motor steps per tick", "%6.0f", 0, 255., 0., 1., 0, 0, 0}, }; static INumberVectorProperty SettingsNP = { mydev, "FOCUS_SETTINGS", "Settings", CONNECTION_GROUP, IP_RW, 0, IPS_IDLE, SettingsN, NARRAY(SettingsN), "", 0 } ; /* Power Switches of the Robofocus */ static ISwitch PowerSwitchesS[]= { {"1", "Switch 1", ISS_OFF, 0, 0}, {"2", "Switch 2", ISS_OFF, 0, 0}, {"3", "Switch 3", ISS_OFF, 0, 0}, {"4", "Switch 4", ISS_ON , 0, 0} }; static ISwitchVectorProperty PowerSwitchesSP = { mydev, "SWITCHES", "Power", CONNECTION_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, PowerSwitchesS, NARRAY(PowerSwitchesS), "", 0 } ; /* Direction of the focuser movement - or IGNORE */ static ISwitch DirectionS[] = { {"FOCUSIN", "inward", ISS_OFF, 0, 0}, {"FOCUSOUT", "outward", ISS_OFF, 0, 0}, {"FOCUSIGNORE", "IGNORE", ISS_ON, 0, 0}, } ; static ISwitchVectorProperty DirectionSP = { mydev, "DIRECTION", "Movement", MOTION_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE, DirectionS, NARRAY(DirectionS), "", 0 } ; /* Robofocus should stay within these limits */ static INumber MinMaxPositionN[] = { { "MINPOS", "Minimum Tick", "%6.0f", 1., 65000., 0., 100., 0, 0, 0}, { "MAXPOS", "Maximum Tick", "%6.0f", 1., 65000., 0., 55000., 0, 0, 0}, }; static INumberVectorProperty MinMaxPositionNP = { mydev, "FOCUS_MINMXPOSITION", "Extrema", MOTION_GROUP, IP_RW, 0, IPS_IDLE, MinMaxPositionN, NARRAY(MinMaxPositionN), "", 0 }; static INumber MaxTravelN[] = { { "MAXTRAVEL", "Maximum travel", "%6.0f", 1., 64000., 0., 10000., 0, 0, 0}, }; static INumberVectorProperty MaxTravelNP = { mydev, "FOCUS_MAXTRAVEL", "Max. travel", MOTION_GROUP, IP_RW, 0, IPS_IDLE, MaxTravelN, NARRAY(MaxTravelN), "", 0 }; /* Set Robofocus position register to the this position */ static INumber SetRegisterPositionN[] = { /* 64000: see Robofocus manual */ { "SETPOS", "Position", "%6.0f", 0, 64000., 0., 0., 0, 0, 0}, }; static INumberVectorProperty SetRegisterPositionNP = { mydev, "FOCUS_REGISTERPOSITION", "Set register", MOTION_GROUP, IP_RW, 0, IPS_IDLE, SetRegisterPositionN, NARRAY(SetRegisterPositionN), "", 0 }; /* Set Robofocus' backlash behaviour */ static INumber SetBacklashN[] = { { "SETBACKLASH", "Backlash", "%6.0f", -255., 255., 0., 0., 0, 0, 0}, }; static INumberVectorProperty SetBacklashNP = { mydev, "FOCUS_Backlash", "Set register", MOTION_GROUP, IP_RW, 0, IPS_IDLE, SetBacklashN, NARRAY(SetBacklashN), "", 0 }; /* Speed */ static INumber SpeedN[] = { {"SPEED", "Ticks/sec", "%6.0f",0., 999., 0., 50., 0, 0, 0}, } ; static INumberVectorProperty SpeedNP = { mydev, "FOCUS_SPEED", "Speed", MOTION_GROUP, IP_RW, 0, IPS_IDLE, SpeedN, NARRAY(SpeedN), "", 0 } ; /* Timer */ static INumber TimerN[] = { {"TIMER","sec", "%6.0f",0., 999., 0., 0., 0, 0, 0}, } ; static INumberVectorProperty TimerNP = { mydev, "FOCUS_TIMER", "Timer", MOTION_GROUP, IP_RW, 0, IPS_IDLE, TimerN, NARRAY(TimerN), "", 0 } ; /* Robofocus` position (RO) */ static INumber PositionN[] = { { "POSITION", "Tick", "%6.0f", 0, 65000., 0., 10000., 0, 0, 0}, } ; static INumberVectorProperty PositionNP = { mydev, "FOCUS_POSITION", "Position", MOTION_GROUP, IP_RO, 0, IPS_IDLE, PositionN, NARRAY(PositionN), "", 0 } ; /* Relative and absolute movement */ static INumber RelMovementN[] = { { "RELMOVEMENT", "Ticks", "%6.0f", -65000., 65000., 0., 100., 0, 0, 0}, }; static INumberVectorProperty RelMovementNP = { mydev, "FOCUS_RELMOVEMENT", "Relative goto", MOTION_GROUP, IP_RW, 0, IPS_IDLE, RelMovementN, NARRAY(RelMovementN), "", 0 } ; static INumber AbsMovementN[] = { { "ABSMOVEMENT", "Tick", "%6.0f", 0, 65000., 0., 10000., 0, 0, 0}, } ; static INumberVectorProperty AbsMovementNP = { mydev, "FOCUS_ABSMOVEMENT", "Absolute goto", MOTION_GROUP, IP_RW, 0, IPS_IDLE, AbsMovementN, NARRAY(AbsMovementN), "", 0 } ; /* Initlization routine */ static void ISInit() { static int isInit=0; /* set once mountInit is called */ /*fprintf(stderr, "ISInit\n") ;*/ if (isInit) return; /* stolen from temmadriver.c :-)*/ PortT[0].text = malloc( 13); if (!PortT[0].text ){ fprintf(stderr,"Memory allocation error"); return; } IUSaveText( &PortT[0], "/dev/ttyUSB0"); /* fprintf(stderr, "PORT:%s<\n", PortT->text) ; */ IDSetText( &PortTP, NULL) ; fd=-1; isInit = 1; } void ISWorkProc () { char firmeware[]="FV0000000" ; int ret = -1 ; int cur_s1LL=0 ; int cur_s2LR=0 ; int cur_s3RL=0 ; int cur_s4RR=0 ; /* fprintf(stderr, "ISWorkProc\n") ; */ if (PowerS[0].s == ISS_ON) { switch (PowerSP.s) { case IPS_IDLE: case IPS_OK: if((ret= updateRFFirmware(fd, firmeware)) < 0) { /* This would be the end*/ IDMessage( mydev, "Unknown error while reading Robofocus firmware\n"); break; } PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, NULL); if((ret= updateRFPosition(fd, ¤tPosition)) < 0) { PositionNP.s = IPS_ALERT; IDSetNumber(&PositionNP, "Unknown error while reading Robofocus position: %d", ret); break; } PositionNP.s = IPS_OK; IDSetNumber(&PositionNP, NULL); if(( ret= updateRFTemperature(fd, ¤tTemperature)) < 0) { TemperatureNP.s = IPS_ALERT; IDSetNumber(&TemperatureNP, "Unknown error while reading Robofocus temperature"); break; } TemperatureNP.s = IPS_OK; IDSetNumber(&TemperatureNP, NULL); currentBacklash= BACKLASH_READOUT ; if(( ret= updateRFBacklash(fd, ¤tBacklash)) < 0) { SetBacklashNP.s = IPS_ALERT; IDSetNumber(&SetBacklashNP, "Unknown error while reading Robofocus backlash"); break; } SetBacklashNP.s = IPS_OK; IDSetNumber(&SetBacklashNP, NULL); currentDuty= currentDelay= currentTicks=0 ; if(( ret= updateRFMotorSettings(fd, ¤tDuty, ¤tDelay, ¤tTicks )) < 0) { SettingsNP.s = IPS_ALERT; IDSetNumber(&SettingsNP, "Unknown error while reading Robofocus motor settings"); break; } SettingsNP.s = IPS_OK; IDSetNumber(&SettingsNP, NULL); if(( ret= updateRFPowerSwitches(fd, -1, -1, &cur_s1LL, &cur_s2LR, &cur_s3RL, &cur_s4RR)) < 0) { PowerSwitchesSP.s = IPS_ALERT; IDSetSwitch(&PowerSwitchesSP, "Unknown error while reading Robofocus power swicht settings"); break; } PowerSwitchesS[0].s= PowerSwitchesS[1].s= PowerSwitchesS[2].s= PowerSwitchesS[3].s= ISS_OFF ; if(cur_s1LL== ISS_ON) { PowerSwitchesS[0].s= ISS_ON ; } if(cur_s2LR== ISS_ON) { PowerSwitchesS[1].s= ISS_ON ; } if(cur_s3RL== ISS_ON) { PowerSwitchesS[2].s= ISS_ON ; } if(cur_s4RR== ISS_ON) { PowerSwitchesS[3].s= ISS_ON ; } PowerSwitchesSP.s = IPS_OK ; IDSetSwitch(&PowerSwitchesSP, NULL); currentMaxTravel= MAXTRAVEL_READOUT ; if(( ret= updateRFMaxPosition(fd, ¤tMaxTravel)) < 0) { MaxTravelNP.s = IPS_ALERT; IDSetNumber(&MaxTravelNP, "Unknown error while reading Robofocus maximum travel"); break; } MaxTravelNP.s = IPS_OK; IDSetNumber(&MaxTravelNP, NULL); case IPS_BUSY: break; case IPS_ALERT: break; } } } /* void ISGetProperties (const char *dev) * INDI will call this function when the client inquires about the device properties. * Here we will use IDxxx functions to define new properties to the client */ void ISGetProperties (const char *dev) { /* fprintf(stderr, "ISGetProperties\n") ; */ /* #1 Let's make sure everything has been initialized properly */ ISInit(); /* #2 Let's make sure that the client is asking for the properties of our device, otherwise ignore */ if (dev && strcmp (mydev, dev)) return; /* #3 Tell the client to create a new Switch property PowerSP */ IDDefSwitch(&PowerSP, NULL); IDDefText(&PortTP, NULL); IDDefSwitch(&PowerSwitchesSP, NULL); IDDefNumber(&TemperatureNP, NULL); IDDefNumber(&SettingsNP, NULL); IDDefNumber(&MinMaxPositionNP, NULL); IDDefNumber(&MaxTravelNP, NULL); IDDefNumber(&SetRegisterPositionNP, NULL); IDDefNumber(&SetBacklashNP, NULL); IDDefSwitch(&DirectionSP, NULL); IDDefNumber(&PositionNP, NULL); IDDefNumber(&SpeedNP, NULL); IDDefNumber(&TimerNP, NULL); IDDefNumber(&AbsMovementNP, NULL); IDDefNumber(&RelMovementNP, NULL); } /* void ISNewSwitch(...) * INDI will call this function when the client wants to set a new state of existing switches ** Parameters ** * dev: the device name * name: the property name the client wants to update * states: an array of states of members switches (ISS_ON and ISS_OFF) * names: names of the switches. The names are parallel to the states. That is, member names[0] has a state states[0], and so on... * n: number of switches to update, which is also the dimension of *states and names[] */ void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { /* fprintf(stderr, "ISNewSwitch\n") ; */ /* #1 Let's make sure everything has been initialized properly */ ISInit(); /* #2 Let's make sure that the client is asking to update the properties of our device, otherwise ignore */ if (dev && strcmp (dev, mydev)) return; /* #3 Now let's check if the property the client wants to change is the PowerSP (name: CONNECTION) property*/ if (!strcmp (name, PowerSP.name)) { /* If the clients wants to update this property, let's perform the following */ /* A. We reset all switches (in this case CONNECT and DISCONNECT) to ISS_OFF */ IUResetSwitches(&PowerSP); /* B. We update the switches by sending their names and updated states IUUpdateSwitches function */ IUUpdateSwitches(&PowerSP, states, names, n); /* C. We try to establish a connection to our device */ connectRobofocus(); return ; } if (!strcmp (name, PowerSwitchesSP.name)) { int ret= -1 ; int nset= 0 ; int i= 0 ; int new_s= -1 ; int new_sn= -1 ; int cur_s1LL=0 ; int cur_s2LR=0 ; int cur_s3RL=0 ; int cur_s4RR=0 ; ISwitch *sp ; PowerSwitchesSP.s = IPS_BUSY ; IDSetSwitch(&PowerSwitchesSP, NULL) ; for( nset = i = 0; i < n; i++) { /* Find numbers with the passed names in the SettingsNP property */ sp = IUFindSwitch (&PowerSwitchesSP, names[i]) ; /* If the state found is (PowerSwitchesS[0]) then process it */ if( sp == &PowerSwitchesS[0]){ new_s = (states[i]) ; new_sn= 0; nset++ ; } else if( sp == &PowerSwitchesS[1]){ new_s = (states[i]) ; new_sn= 1; nset++ ; } else if( sp == &PowerSwitchesS[2]){ new_s = (states[i]) ; new_sn= 2; nset++ ; } else if( sp == &PowerSwitchesS[3]){ new_s = (states[i]) ; new_sn= 3; nset++ ; } } if (nset == 1) { cur_s1LL= cur_s2LR= cur_s3RL= cur_s4RR= 0 ; if(( ret= updateRFPowerSwitches(fd, new_s, new_sn, &cur_s1LL, &cur_s2LR, &cur_s3RL, &cur_s4RR)) < 0) { PowerSwitchesSP.s = IPS_ALERT; IDSetSwitch(&PowerSwitchesSP, "Unknown error while reading Robofocus power swicht settings"); return ; } } else { /* Set property state to idle */ PowerSwitchesSP.s = IPS_IDLE ; IDSetNumber(&SettingsNP, "Power switch settings absent or bogus."); return ; } PowerSwitchesS[0].s= PowerSwitchesS[1].s= PowerSwitchesS[2].s= PowerSwitchesS[3].s= ISS_OFF ; if(cur_s1LL== ISS_ON) { PowerSwitchesS[0].s= ISS_ON ; } if(cur_s2LR== ISS_ON) { PowerSwitchesS[1].s= ISS_ON ; } if(cur_s3RL== ISS_ON) { PowerSwitchesS[2].s= ISS_ON ; } if(cur_s4RR== ISS_ON) { PowerSwitchesS[3].s= ISS_ON ; } PowerSwitchesSP.s = IPS_OK ; IDSetSwitch(&PowerSwitchesSP, "Setting power switches"); } } /* void ISNewText(...) * INDI will call this function when the client wants to update an existing text. ** Parameters ** * dev: the device name * name: the property name the client wants to update * texts: an array of texts. * names: names of the members. The names are parallel to the texts. * n: number of texts to update, which is also the dimension of *texts and names[] */ void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { /* fprintf(stderr, "ISNewText\n") ; */ /* #1 Let's make sure everything has been initialized properly */ ISInit(); /* #2 Let's make sure that the client is asking to update the properties of our device, otherwise ignore */ if (dev && strcmp (dev, mydev)) return; dev=dev; names=names; n=n; if (!strcmp(name, PortTP.name)) { IUSaveText(&PortT[0], texts[0]); PortTP.s = IPS_OK; IDSetText(&PortTP, NULL); return; } return; } /* void ISNewNumber(...) * INDI will call this function when the client wants to update an existing number. ** Parameters ** * dev: the device name * name: the property name the client wants to update * values: an array of values. * names: names of the members. The names are parallel to the values. * n: number of numbers to update, which is the dimension of *numbers and names[] */ void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { int i, nset; /* fprintf(stderr, "ISNewNumber\n") ; */ /* Make sure to initialize */ ISInit(); /* ignore if not ours */ if (strcmp (dev, mydev)) return; if (!strcmp (name, SettingsNP.name)) { /* new speed */ double new_duty = 0 ; double new_delay = 0 ; double new_ticks = 0 ; int ret = -1 ; /* Check power, if it is off, then return */ if (PowerS[0].s != ISS_ON){ SettingsNP.s = IPS_IDLE; IDSetNumber(&SettingsNP, "Power is off"); return; } for (nset = i = 0; i < n; i++){ /* Find numbers with the passed names in the SettingsNP property */ INumber *eqp = IUFindNumber (&SettingsNP, names[i]); /* If the number found is (SettingsN[0]) then process it */ if (eqp == &SettingsN[0]){ new_duty = (values[i]); nset += new_duty >= 0 && new_duty <= 255; } else if (eqp == &SettingsN[1]){ new_delay = (values[i]); nset += new_delay >= 0 && new_delay <= 255; } else if (eqp == &SettingsN[2]){ new_ticks = (values[i]); nset += new_ticks >= 0 && new_ticks <= 255; } } /* Did we process the three numbers? */ if (nset == 3) { /* Set the robofocus state to BUSY */ SettingsNP.s = IPS_BUSY; IDSetNumber(&SettingsNP, NULL); if(( ret= updateRFMotorSettings(fd, &new_duty, &new_delay, &new_ticks))< 0) { IDSetNumber(&SettingsNP, "Changing to new settings failed"); return ; } ; currentDuty = new_duty ; currentDelay= new_delay ; currentTicks= new_ticks ; SettingsNP.s = IPS_OK; IDSetNumber(&SettingsNP, "Motor settings are now %3.0f %3.0f %3.0f", currentDuty, currentDelay, currentTicks); } else { /* Set property state to idle */ SettingsNP.s = IPS_IDLE; IDSetNumber(&SettingsNP, "Settings absent or bogus."); return ; } } if (!strcmp (name, RelMovementNP.name)) { double cur_rpos=0 ; double new_rpos = 0 ; int nset = 0; int ret= -1 ; if (PowerS[0].s != ISS_ON){ RelMovementNP.s = IPS_IDLE; IDSetNumber(&RelMovementNP, "Power is off"); return; } for (nset = i = 0; i < n; i++) { /* Find numbers with the passed names in the RelMovementNP property */ INumber *eqp = IUFindNumber (&RelMovementNP, names[i]); /* If the number found is RelMovement (RelMovementN[0]) then process it */ if (eqp == &RelMovementN[0]){ cur_rpos= new_rpos = (values[i]); /* CHECK 2006-01-26, limmits are relative to the actual position */ nset += new_rpos >= -0xffff && new_rpos <= 0xffff; } if (nset == 1) { /* Set the robofocus state to BUSY */ RelMovementNP.s = IPS_BUSY; IDSetNumber(&RelMovementNP, NULL); if((currentPosition + new_rpos < currentMinPosition) || (currentPosition + new_rpos > currentMaxPosition)) { RelMovementNP.s = IPS_ALERT ; IDSetNumber(&RelMovementNP, "Value out of limits %5.0f", currentPosition + new_rpos); return ; } if( new_rpos > 0) { ret= updateRFPositionRelativeOutward(fd, &new_rpos) ; } else { new_rpos= -new_rpos ; ret= updateRFPositionRelativeInward(fd, &new_rpos) ; } if( ret < 0) { RelMovementNP.s = IPS_IDLE; IDSetNumber(&RelMovementNP, "Read out of the relative movement failed, trying to recover position."); if((ret= updateRFPosition(fd, ¤tPosition)) < 0) { PositionNP.s = IPS_ALERT; IDSetNumber(&PositionNP, "Unknown error while reading Robofocus position: %d", ret); return ; } PositionNP.s = IPS_ALERT; IDSetNumber(&PositionNP, "Robofocus position recovered %5.0f", currentPosition); IDMessage( mydev, "Robofocus position recovered resuming normal operation"); /* We have to leave here, because new_rpos is not set */ return ; } RelMovementNP.s = IPS_OK; currentRelativeMovement= cur_rpos ; IDSetNumber(&RelMovementNP, NULL) ; AbsMovementNP.s = IPS_OK; currentAbsoluteMovement= new_rpos - cur_rpos ; IDSetNumber(&AbsMovementNP, NULL) ; PositionNP.s = IPS_OK; currentPosition= new_rpos ; IDSetNumber(&PositionNP, "Last position was %5.0f", currentAbsoluteMovement); } else { RelMovementNP.s = IPS_IDLE; IDSetNumber(&RelMovementNP, "Need exactly one parameter."); return ; } } } if (!strcmp (name, AbsMovementNP.name)) { double new_apos = 0 ; int nset = 0; int ret= -1 ; if (PowerS[0].s != ISS_ON){ AbsMovementNP.s = IPS_IDLE; IDSetNumber(&AbsMovementNP, "Power is off"); return; } for (nset = i = 0; i < n; i++) { /* Find numbers with the passed names in the AbsMovementNP property */ INumber *eqp = IUFindNumber (&AbsMovementNP, names[i]); /* If the number found is AbsMovement (AbsMovementN[0]) then process it */ if (eqp == &AbsMovementN[0]){ new_apos = (values[i]); /* limits are absolute to the actual position */ nset += new_apos >= 0 && new_apos <= 0xffff; } if (nset == 1) { /* Set the robofocus state to BUSY */ AbsMovementNP.s = IPS_BUSY; IDSetNumber(&AbsMovementNP, NULL); if((new_apos < currentMinPosition) || (new_apos > currentMaxPosition)) { AbsMovementNP.s = IPS_ALERT ; IDSetNumber(&AbsMovementNP, "Value out of limits %5.0f", new_apos); return ; } if(( ret= updateRFPositionAbsolute(fd, &new_apos)) < 0) { AbsMovementNP.s = IPS_IDLE; IDSetNumber(&AbsMovementNP, "Read out of the absolute movement failed %3d, trying to recover position.", ret); if((ret= updateRFPosition(fd, ¤tPosition)) < 0) { PositionNP.s = IPS_ALERT; IDSetNumber(&PositionNP, "Unknown error while reading Robofocus position: %d.", ret); return ; } PositionNP.s = IPS_OK; IDSetNumber(&PositionNP, "Robofocus position recovered %5.0f", currentPosition); IDMessage( mydev, "Robofocus position recovered resuming normal operation"); /* We have to leave here, because new_apos is not set */ return ; } currentAbsoluteMovement= currentPosition ; AbsMovementNP.s = IPS_OK; IDSetNumber(&AbsMovementNP, NULL) ; PositionNP.s = IPS_OK; currentPosition= new_apos ; IDSetNumber(&PositionNP, "Absolute position was %5.0f", currentAbsoluteMovement); } else { AbsMovementNP.s = IPS_IDLE; IDSetNumber(&RelMovementNP, "Need exactly one parameter."); return ; } } } if (!strcmp (name, SetBacklashNP.name)) { double new_back = 0 ; int nset = 0; int ret= -1 ; if (PowerS[0].s != ISS_ON){ SetBacklashNP.s = IPS_IDLE; IDSetNumber(&SetBacklashNP, "Power is off"); return; } for (nset = i = 0; i < n; i++) { /* Find numbers with the passed names in the SetBacklashNP property */ INumber *eqp = IUFindNumber (&SetBacklashNP, names[i]); /* If the number found is SetBacklash (SetBacklashN[0]) then process it */ if (eqp == &SetBacklashN[0]){ new_back = (values[i]); /* limits */ nset += new_back >= -0xff && new_back <= 0xff; } if (nset == 1) { /* Set the robofocus state to BUSY */ SetBacklashNP.s = IPS_BUSY; IDSetNumber(&SetBacklashNP, NULL); if(( ret= updateRFBacklash(fd, &new_back)) < 0) { SetBacklashNP.s = IPS_IDLE; IDSetNumber(&SetBacklashNP, "Setting new backlash failed."); return ; } currentSetBacklash= new_back ; SetBacklashNP.s = IPS_OK; IDSetNumber(&SetBacklashNP, "Backlash is now %3.0f", currentSetBacklash) ; } else { SetBacklashNP.s = IPS_IDLE; IDSetNumber(&SetBacklashNP, "Need exactly one parameter."); return ; } } } if (!strcmp (name, MinMaxPositionNP.name)) { /* new positions */ double new_min = 0 ; double new_max = 0 ; /* Check power, if it is off, then return */ if (PowerS[0].s != ISS_ON){ MinMaxPositionNP.s = IPS_IDLE; IDSetNumber(&MinMaxPositionNP, "Power is off"); return; } for (nset = i = 0; i < n; i++){ /* Find numbers with the passed names in the MinMaxPositionNP property */ INumber *mmpp = IUFindNumber (&MinMaxPositionNP, names[i]); /* If the number found is (MinMaxPositionN[0]) then process it */ if (mmpp == &MinMaxPositionN[0]){ new_min = (values[i]); nset += new_min >= 1 && new_min <= 65000; } else if (mmpp == &MinMaxPositionN[1]){ new_max = (values[i]); nset += new_max >= 1 && new_max <= 65000; } } /* Did we process the two numbers? */ if (nset == 2) { /* Set the robofocus state to BUSY */ MinMaxPositionNP.s = IPS_BUSY; currentMinPosition = new_min ; currentMaxPosition= new_max ; MinMaxPositionNP.s = IPS_OK; IDSetNumber(&MinMaxPositionNP, "Minimum and Maximum settings are now %3.0f %3.0f", currentMinPosition, currentMaxPosition); } else { /* Set property state to idle */ MinMaxPositionNP.s = IPS_IDLE; IDSetNumber(&MinMaxPositionNP, "Minimum and maximum limits absent or bogus."); return ; } } if (!strcmp (name, MaxTravelNP.name)) { double new_maxt = 0 ; int ret = -1 ; /* Check power, if it is off, then return */ if (PowerS[0].s != ISS_ON){ MaxTravelNP.s = IPS_IDLE; IDSetNumber(&MaxTravelNP, "Power is off"); return; } for (nset = i = 0; i < n; i++){ /* Find numbers with the passed names in the MinMaxPositionNP property */ INumber *mmpp = IUFindNumber (&MaxTravelNP, names[i]); /* If the number found is (MaxTravelN[0]) then process it */ if (mmpp == &MaxTravelN[0]){ new_maxt = (values[i]); nset += new_maxt >= 1 && new_maxt <= 64000; } } /* Did we process the one number? */ if (nset == 1) { IDSetNumber(&MinMaxPositionNP, NULL); if(( ret= updateRFMaxPosition(fd, &new_maxt))< 0 ) { MaxTravelNP.s = IPS_IDLE; IDSetNumber(&MaxTravelNP, "Changing to new maximum travel failed"); return ; } ; currentMaxTravel= new_maxt ; MaxTravelNP.s = IPS_OK; IDSetNumber(&MaxTravelNP, "Maximum travel is now %3.0f", currentMaxTravel) ; } else { /* Set property state to idle */ MaxTravelNP.s = IPS_IDLE; IDSetNumber(&MaxTravelNP, "Maximum travel absent or bogus."); return ; } } if (!strcmp (name, SetRegisterPositionNP.name)) { double new_apos = 0 ; int nset = 0; int ret= -1 ; if (PowerS[0].s != ISS_ON){ SetRegisterPositionNP.s = IPS_IDLE; IDSetNumber(&SetRegisterPositionNP, "Power is off"); return; } for (nset = i = 0; i < n; i++) { /* Find numbers with the passed names in the SetRegisterPositionNP property */ INumber *srpp = IUFindNumber (&SetRegisterPositionNP, names[i]); /* If the number found is SetRegisterPosition (SetRegisterPositionN[0]) then process it */ if (srpp == &SetRegisterPositionN[0]){ new_apos = (values[i]); /* limits are absolute */ nset += new_apos >= 0 && new_apos <= 64000; } if (nset == 1) { if((new_apos < currentMinPosition) || (new_apos > currentMaxPosition)) { SetRegisterPositionNP.s = IPS_ALERT ; IDSetNumber(&SetRegisterPositionNP, "Value out of limits %5.0f", new_apos); return ; } /* Set the robofocus state to BUSY */ SetRegisterPositionNP.s = IPS_BUSY; IDSetNumber(&SetRegisterPositionNP, NULL); if(( ret= updateRFSetPosition(fd, &new_apos)) < 0) { SetRegisterPositionNP.s = IPS_OK; IDSetNumber(&SetRegisterPositionNP, "Read out of the set position to %3d failed. Trying to recover the position", ret); if((ret= updateRFPosition(fd, ¤tPosition)) < 0) { PositionNP.s = IPS_ALERT; IDSetNumber(&PositionNP, "Unknown error while reading Robofocus position: %d", ret); SetRegisterPositionNP.s = IPS_IDLE; IDSetNumber(&SetRegisterPositionNP, "Relative movement failed."); } SetRegisterPositionNP.s = IPS_OK; IDSetNumber(&SetRegisterPositionNP, NULL); PositionNP.s = IPS_OK; IDSetNumber(&PositionNP, "Robofocus position recovered %5.0f", currentPosition); IDMessage( mydev, "Robofocus position recovered resuming normal operation"); /* We have to leave here, because new_apos is not set */ return ; } currentPosition= new_apos ; SetRegisterPositionNP.s = IPS_OK; IDSetNumber(&SetRegisterPositionNP, "Robofocus register set to %5.0f", currentPosition); PositionNP.s = IPS_OK; IDSetNumber(&PositionNP, "Robofocus position is now %5.0f", currentPosition); return ; } else { SetRegisterPositionNP.s = IPS_IDLE; IDSetNumber(&SetRegisterPositionNP, "Need exactly one parameter."); return ; } if((ret= updateRFPosition(fd, ¤tPosition)) < 0) { PositionNP.s = IPS_ALERT; IDSetNumber(&PositionNP, "Unknown error while reading Robofocus position: %d", ret); return ; } SetRegisterPositionNP.s = IPS_OK; IDSetNumber(&SetRegisterPositionNP, "Robofocus has accepted new register setting" ) ; PositionNP.s = IPS_OK; IDSetNumber(&PositionNP, "Robofocus new position %5.0f", currentPosition); } } return; } void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n){} /* void connectRobofocus(void) * This function is called when the state of PowerSP is changed in the ISNewSwitch() function. * We check the state of CONNECT and DISCONNECT switches, and connect or disconnect our fake device accordingly */ void connectRobofocus(void) { /* fprintf(stderr, "connectRobofocus\n") ; */ switch (PowerS[0].s) { case ISS_ON: if (tty_connect(PortT[0].text, 9600, 8, 0, 1, &fd) != TTY_OK) { PowerSP.s = IPS_ALERT; IUResetSwitches(&PowerSP); IDSetSwitch(&PowerSP, "Error connecting to port >%s<", PortT[0].text); return; } PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "Robofocus is online."); wp= IEAddWorkProc( (IE_WPF *)ISWorkProc, NULL) ; break; case ISS_OFF: IERmWorkProc ( wp) ; tty_disconnect(fd); IUResetSwitches(&PowerSP); IUResetSwitches(&PowerSwitchesSP); IUResetSwitches(&DirectionSP); AbsMovementNP.s= RelMovementNP.s= TimerNP.s= SpeedNP.s= SetBacklashNP.s= SetRegisterPositionNP.s= MinMaxPositionNP.s= DirectionSP.s= PowerSwitchesSP.s= SettingsNP.s= TemperatureNP.s= PositionNP.s = PortTP.s = PowerSP.s = IPS_IDLE; IDSetSwitch(&PowerSP, "Robofocus is offline."); IDSetText(&PortTP, NULL); IDSetSwitch(&DirectionSP, NULL); IDSetSwitch(&PowerSwitchesSP, NULL); /* Write the last status */ IDSetNumber(&PositionNP, NULL); IDSetNumber(&AbsMovementNP, NULL); IDSetNumber(&RelMovementNP, NULL); IDSetNumber(&TimerNP, NULL); IDSetNumber(&SpeedNP, NULL); IDSetNumber(&SetBacklashNP, NULL); IDSetNumber(&SetRegisterPositionNP, NULL); IDSetNumber(&MinMaxPositionNP, NULL); IDSetNumber(&MaxTravelNP, NULL); IDSetNumber(&SettingsNP, NULL); IDSetNumber(&TemperatureNP, NULL); break; } } indi-0.5/src/lx200basic.cpp0000644000175000017500000005137310610474326013267 0ustar jrjr#if 0 LX200 Basic Driver Copyright (C) 2005 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include "config.h" #include #include #include #include #include #include #include #include "indicom.h" #include "lx200driver.h" #include "lx200basic.h" /* ** Return the timezone offset in hours (as a double, so fractional ** hours are possible, for instance in Newfoundland). Also sets ** daylight on non-Linux systems to record whether DST is in effect. */ LX200Basic *telescope = NULL; extern char* me; #define BASIC_GROUP "Main Control" #define currentRA EqN[0].value #define currentDEC EqN[1].value #define RA_THRESHOLD 0.01 #define DEC_THRESHOLD 0.05 #define TRACKING_THRESHOLD 0.05 #define LX200_SLEW 0 #define LX200_TRACK 1 #define LX200_SYNC 2 #define LX200_PARK 3 static void ISPoll(void *); static void retryConnection(void *); /*INDI controls */ /* send client definitions of all properties */ void ISInit() { static int isInit=0; if (isInit) return; isInit = 1; telescope = new LX200Basic(); IEAddTimer (POLLMS, ISPoll, NULL); } void ISGetProperties (const char *dev) { ISInit(); telescope->ISGetProperties(dev); } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { ISInit(); telescope->ISNewSwitch(dev, name, states, names, n); } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { ISInit(); telescope->ISNewText(dev, name, texts, names, n); } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { ISInit(); telescope->ISNewNumber(dev, name, values, names, n); } void ISPoll (void */*p*/) { telescope->ISPoll(); IEAddTimer (POLLMS, ISPoll, NULL); } void ISNewBLOB (const char */*dev*/, const char */*name*/, int */*sizes[]*/, char **/*blobs[]*/, char **/*formats[]*/, char **/*names[]*/, int /*n*/) {} /************************************************** *** AP Mount ***************************************************/ LX200Basic::LX200Basic() { struct tm *utp = (tm *) malloc (sizeof (struct tm)); time_t t; time (&t); gmtime_r (&t, utp); utp->tm_mon += 1; utp->tm_year += 1900; JD = UTtoJD(utp); free(utp); initProperties(); lastSet = -1; fd = -1; simulation = false; targetRA = 0; targetDEC = 0; lastRA = 0; lastDEC = 0; currentSet = 0; IDLog("Julian Day is %g\n", JD); IDLog("Initilizing from LX200 Basic device...\n"); IDLog("Driver Version: 2006-03-29\n"); //enableSimulation(true); } void LX200Basic::initProperties() { IUFillSwitch(&PowerS[0], "CONNECT", "Connect", ISS_OFF); IUFillSwitch(&PowerS[1], "DISCONNECT", "Disconnect", ISS_ON); IUFillSwitchVector(&PowerSP, PowerS, NARRAY(PowerS), mydev, "CONNECTION", "Connection", BASIC_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE); IUFillSwitch(&OnCoordSetS[0], "SLEW", "Slew", ISS_ON); IUFillSwitch(&OnCoordSetS[1], "TRACK", "Track", ISS_OFF); IUFillSwitch(&OnCoordSetS[2], "SYNC", "Sync", ISS_OFF); IUFillSwitchVector(&OnCoordSetSP, OnCoordSetS, NARRAY(OnCoordSetS), mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE); IUFillSwitch(&AbortSlewS[0], "ABORT", "Abort", ISS_OFF); IUFillSwitchVector(&AbortSlewSP, AbortSlewS, NARRAY(AbortSlewS), mydev, "ABORT_MOTION", "Abort Slew/Track", BASIC_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE); IUFillText(&PortT[0], "PORT", "Port", "/dev/ttyS0"); IUFillTextVector(&PortTP, PortT, NARRAY(PortT), mydev, "DEVICE_PORT", "Ports", BASIC_GROUP, IP_RW, 0, IPS_IDLE); IUFillText(&ObjectT[0], "OBJECT_NAME", "Name", "--"); IUFillTextVector(&ObjectTP, ObjectT, NARRAY(ObjectT), mydev, "OBJECT_INFO", "Object", BASIC_GROUP, IP_RW, 0, IPS_IDLE); IUFillNumber(&EqN[0], "RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0.); IUFillNumber(&EqN[1], "DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0.); IUFillNumberVector(&EqNP, EqN, NARRAY(EqN), mydev, "EQUATORIAL_EOD_COORD" , "Equatorial JNow", BASIC_GROUP, IP_RW, 0, IPS_IDLE); IUFillNumber(&SlewPrecisionN[0], "SlewRA", "RA (arcmin)", "%10.6m", 0., 60., 1., 3.0); IUFillNumber(&SlewPrecisionN[1], "SlewDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0); IUFillNumberVector(&SlewPrecisionNP, SlewPrecisionN, NARRAY(SlewPrecisionN), mydev, "Slew Precision", "", BASIC_GROUP, IP_RW, 0, IPS_IDLE); IUFillNumber(&TrackPrecisionN[0], "TrackRA", "RA (arcmin)", "%10.6m", 0., 60., 1., 3.0); IUFillNumber(&TrackPrecisionN[1], "TrackDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0); IUFillNumberVector(&TrackPrecisionNP, TrackPrecisionN, NARRAY(TrackPrecisionN), mydev, "Tracking Precision", "", BASIC_GROUP, IP_RW, 0, IPS_IDLE); } void LX200Basic::ISGetProperties(const char *dev) { if (dev && strcmp (mydev, dev)) return; // Main Control IDDefSwitch(&PowerSP, NULL); IDDefText(&PortTP, NULL); IDDefText(&ObjectTP, NULL); IDDefNumber(&EqNP, NULL); IDDefSwitch(&OnCoordSetSP, NULL); IDDefSwitch(&AbortSlewSP, NULL); IDDefNumber(&SlewPrecisionNP, NULL); IDDefNumber(&TrackPrecisionNP, NULL); } void LX200Basic::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int /*n*/) { IText *tp; // ignore if not ours if (strcmp (dev, mydev)) return; // Port name if (!strcmp(name, PortTP.name) ) { PortTP.s = IPS_OK; tp = IUFindText( &PortTP, names[0] ); if (!tp) return; IUSaveText(tp, texts[0]); IDSetText (&PortTP, NULL); return; } if (!strcmp (name, ObjectTP.name)) { if (checkPower(&ObjectTP)) return; IUSaveText(&ObjectT[0], texts[0]); ObjectTP.s = IPS_OK; IDSetText(&ObjectTP, NULL); return; } } void LX200Basic::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { int err; double newRA =0, newDEC =0; // ignore if not ours // if (strcmp (dev, mydev)) return; if (!strcmp (name, EqNP.name)) { int i=0, nset=0; if (checkPower(&EqNP)) return; for (nset = i = 0; i < n; i++) { INumber *eqp = IUFindNumber (&EqNP, names[i]); if (eqp == &EqN[0]) { newRA = values[i]; nset += newRA >= 0 && newRA <= 24.0; } else if (eqp == &EqN[1]) { newDEC = values[i]; nset += newDEC >= -90.0 && newDEC <= 90.0; } } if (nset == 2) { char RAStr[32], DecStr[32]; fs_sexa(RAStr, newRA, 2, 3600); fs_sexa(DecStr, newDEC, 2, 3600); #ifdef INDI_DEBUG IDLog("We received JNow RA %g - DEC %g\n", newRA, newDEC); IDLog("We received JNow RA %s - DEC %s\n", RAStr, DecStr); #endif if ( (err = setObjectRA(fd, newRA)) < 0 || ( err = setObjectDEC(fd, newDEC)) < 0) { handleError(&EqNP, err, "Setting RA/DEC"); return; } targetRA = newRA; targetDEC = newDEC; if (handleCoordSet()) { EqNP.s = IPS_IDLE; IDSetNumber(&EqNP, NULL); } } // end nset else { EqNP.s = IPS_IDLE; IDSetNumber(&EqNP, "RA or Dec missing or invalid"); } return; } /* end EqNP */ /* Update tracking precision limits */ if (!strcmp (name, TrackPrecisionNP.name)) { if (!IUUpdateNumbers(&TrackPrecisionNP, values, names, n)) { TrackPrecisionNP.s = IPS_OK; IDSetNumber(&TrackPrecisionNP, NULL); return; } TrackPrecisionNP.s = IPS_ALERT; IDSetNumber(&TrackPrecisionNP, "unknown error while setting tracking precision"); return; } /* Update slew precision limit */ if (!strcmp(name, SlewPrecisionNP.name)) { IUUpdateNumbers(&SlewPrecisionNP, values, names, n); { SlewPrecisionNP.s = IPS_OK; IDSetNumber(&SlewPrecisionNP, NULL); return; } SlewPrecisionNP.s = IPS_ALERT; IDSetNumber(&SlewPrecisionNP, "unknown error while setting slew precision"); return; } } void LX200Basic::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { // ignore if not ours // if (strcmp (mydev, dev)) return; // Connection if (!strcmp (name, PowerSP.name)) { IUResetSwitches(&PowerSP); IUUpdateSwitches(&PowerSP, states, names, n); connectTelescope(); return; } // Coord set if (!strcmp(name, OnCoordSetSP.name)) { if (checkPower(&OnCoordSetSP)) return; IUResetSwitches(&OnCoordSetSP); IUUpdateSwitches(&OnCoordSetSP, states, names, n); currentSet = getOnSwitch(&OnCoordSetSP); OnCoordSetSP.s = IPS_OK; IDSetSwitch(&OnCoordSetSP, NULL); } // Abort Slew if (!strcmp (name, AbortSlewSP.name)) { if (checkPower(&AbortSlewSP)) { AbortSlewSP.s = IPS_IDLE; IDSetSwitch(&AbortSlewSP, NULL); return; } IUResetSwitches(&AbortSlewSP); abortSlew(fd); if (EqNP.s == IPS_BUSY) { AbortSlewSP.s = IPS_OK; EqNP.s = IPS_IDLE; IDSetSwitch(&AbortSlewSP, "Slew aborted."); IDSetNumber(&EqNP, NULL); } return; } } void LX200Basic::handleError(ISwitchVectorProperty *svp, int err, const char *msg) { svp->s = IPS_ALERT; /* First check to see if the telescope is connected */ if (check_lx200_connection(fd)) { /* The telescope is off locally */ PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_BUSY; IDSetSwitch(&PowerSP, "Telescope is not responding to commands, will retry in 10 seconds."); IDSetSwitch(svp, NULL); IEAddTimer(10000, retryConnection, &fd); return; } /* If the error is a time out, then the device doesn't support this property or busy*/ if (err == -2) { svp->s = IPS_ALERT; IDSetSwitch(svp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg); } else /* Changing property failed, user should retry. */ IDSetSwitch( svp , "%s failed.", msg); fault = true; } void LX200Basic::handleError(INumberVectorProperty *nvp, int err, const char *msg) { nvp->s = IPS_ALERT; /* First check to see if the telescope is connected */ if (check_lx200_connection(fd)) { /* The telescope is off locally */ PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_BUSY; IDSetSwitch(&PowerSP, "Telescope is not responding to commands, will retry in 10 seconds."); IDSetNumber(nvp, NULL); IEAddTimer(10000, retryConnection, &fd); return; } /* If the error is a time out, then the device doesn't support this property */ if (err == -2) { nvp->s = IPS_ALERT; IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg); } else /* Changing property failed, user should retry. */ IDSetNumber( nvp , "%s failed.", msg); fault = true; } void LX200Basic::handleError(ITextVectorProperty *tvp, int err, const char *msg) { tvp->s = IPS_ALERT; /* First check to see if the telescope is connected */ if (check_lx200_connection(fd)) { /* The telescope is off locally */ PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_BUSY; IDSetSwitch(&PowerSP, "Telescope is not responding to commands, will retry in 10 seconds."); IDSetText(tvp, NULL); IEAddTimer(10000, retryConnection, &fd); return; } /* If the error is a time out, then the device doesn't support this property */ if (err == -2) { tvp->s = IPS_ALERT; IDSetText(tvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg); } else /* Changing property failed, user should retry. */ IDSetText( tvp , "%s failed.", msg); fault = true; } void LX200Basic::correctFault() { fault = false; IDMessage(mydev, "Telescope is online."); } bool LX200Basic::isTelescopeOn(void) { if (simulation) return true; return (PowerSP.sp[0].s == ISS_ON); } static void retryConnection(void * p) { int fd = *((int *) p); if (check_lx200_connection(fd)) telescope->connectionLost(); else telescope->connectionResumed(); } void LX200Basic::ISPoll() { double dx, dy; int err=0; if (!isTelescopeOn()) return; switch (EqNP.s) { case IPS_IDLE: getLX200RA(fd, ¤tRA); getLX200DEC(fd, ¤tDEC); if ( fabs (currentRA - lastRA) > 0.01 || fabs (currentDEC - lastDEC) > 0.01) { lastRA = currentRA; lastDEC = currentDEC; IDSetNumber (&EqNP, NULL); } break; case IPS_BUSY: getLX200RA(fd, ¤tRA); getLX200DEC(fd, ¤tDEC); dx = targetRA - currentRA; dy = targetDEC - currentDEC; //IDLog("targetRA is %g, currentRA is %g\n", targetRA, currentRA); //IDLog("targetDEC is %g, currentDEC is %g\n*************************\n", targetDEC, currentDEC); // Wait until acknowledged or within threshold if ( fabs(dx) <= (SlewPrecisionN[0].value/(60.0*15.0)) && fabs(dy) <= (SlewPrecisionN[1].value/60.0)) { lastRA = currentRA; lastDEC = currentDEC; IUResetSwitches(&OnCoordSetSP); OnCoordSetSP.s = IPS_OK; EqNP.s = IPS_OK; IDSetNumber (&EqNP, NULL); switch (currentSet) { case LX200_SLEW: OnCoordSetSP.sp[0].s = ISS_ON; IDSetSwitch (&OnCoordSetSP, "Slew is complete."); break; case LX200_TRACK: OnCoordSetSP.sp[1].s = ISS_ON; IDSetSwitch (&OnCoordSetSP, "Slew is complete. Tracking..."); break; case LX200_SYNC: break; } } else IDSetNumber (&EqNP, NULL); break; case IPS_OK: if ( (err = getLX200RA(fd, ¤tRA)) < 0 || (err = getLX200DEC(fd, ¤tDEC)) < 0) { handleError(&EqNP, err, "Getting RA/DEC"); return; } if (fault) correctFault(); if ( (currentRA != lastRA) || (currentDEC != lastDEC)) { lastRA = currentRA; lastDEC = currentDEC; IDSetNumber (&EqNP, NULL); } break; case IPS_ALERT: break; } } void LX200Basic::getBasicData() { checkLX200Format(fd); // Get current RA/DEC getLX200RA(fd, ¤tRA); getLX200DEC(fd, ¤tDEC); targetRA = currentRA; targetDEC = currentDEC; IDSetNumber (&EqNP, NULL); } int LX200Basic::handleCoordSet() { int err; char syncString[256]; char RAStr[32], DecStr[32]; double dx, dy; switch (currentSet) { // Slew case LX200_SLEW: lastSet = LX200_SLEW; if (EqNP.s == IPS_BUSY) { IDLog("Aboring Slew\n"); abortSlew(fd); // sleep for 100 mseconds usleep(100000); } if ((err = Slew(fd))) { slewError(err); return (-1); } EqNP.s = IPS_BUSY; fs_sexa(RAStr, targetRA, 2, 3600); fs_sexa(DecStr, targetDEC, 2, 3600); IDSetNumber(&EqNP, "Slewing to JNow RA %s - DEC %s", RAStr, DecStr); IDLog("Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr); break; // Track case LX200_TRACK: //IDLog("We're in LX200_TRACK\n"); if (EqNP.s == IPS_BUSY) { IDLog("Aboring Slew\n"); abortSlew(fd); // sleep for 200 mseconds usleep(200000); } dx = fabs ( targetRA - currentRA ); dy = fabs (targetDEC - currentDEC); if (dx >= (TrackPrecisionN[0].value/(60.0*15.0)) || (dy >= TrackPrecisionN[1].value/60.0)) { //IDLog("Exceeded Tracking threshold, will attempt to slew to the new target.\n"); //IDLog("targetRA is %g, currentRA is %g\n", targetRA, currentRA); //IDLog("targetDEC is %g, currentDEC is %g\n*************************\n", targetDEC, currentDEC); if ((err = Slew(fd))) { slewError(err); return (-1); } fs_sexa(RAStr, targetRA, 2, 3600); fs_sexa(DecStr, targetDEC, 2, 3600); EqNP.s = IPS_BUSY; IDSetNumber(&EqNP, "Slewing to JNow RA %s - DEC %s", RAStr, DecStr); IDLog("Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr); } else { //IDLog("Tracking called, but tracking threshold not reached yet.\n"); EqNP.s = IPS_OK; EqNP.np[0].value = currentRA; EqNP.np[1].value = currentDEC; if (lastSet != LX200_TRACK) IDSetNumber(&EqNP, "Tracking..."); else IDSetNumber(&EqNP, NULL); } lastSet = LX200_TRACK; break; // Sync case LX200_SYNC: lastSet = LX200_SYNC; EqNP.s = IPS_IDLE; if ( ( err = Sync(fd, syncString) < 0) ) { IDSetNumber( &EqNP , "Synchronization failed."); return (-1); } EqNP.s = IPS_OK; IDLog("Synchronization successful %s\n", syncString); IDSetNumber(&EqNP, "Synchronization successful."); break; } return (0); } int LX200Basic::getOnSwitch(ISwitchVectorProperty *sp) { for (int i=0; i < sp->nsp ; i++) if (sp->sp[i].s == ISS_ON) return i; return -1; } int LX200Basic::checkPower(ISwitchVectorProperty *sp) { if (simulation) return 0; if (PowerSP.s != IPS_OK) { if (!strcmp(sp->label, "")) IDMessage (mydev, "Cannot change property %s while the telescope is offline.", sp->name); else IDMessage (mydev, "Cannot change property %s while the telescope is offline.", sp->label); sp->s = IPS_IDLE; IDSetSwitch(sp, NULL); return -1; } return 0; } int LX200Basic::checkPower(INumberVectorProperty *np) { if (simulation) return 0; if (PowerSP.s != IPS_OK) { if (!strcmp(np->label, "")) IDMessage (mydev, "Cannot change property %s while the telescope is offline.", np->name); else IDMessage (mydev, "Cannot change property %s while the telescope is offline.", np->label); np->s = IPS_IDLE; IDSetNumber(np, NULL); return -1; } return 0; } int LX200Basic::checkPower(ITextVectorProperty *tp) { if (simulation) return 0; if (PowerSP.s != IPS_OK) { if (!strcmp(tp->label, "")) IDMessage (mydev, "Cannot change property %s while the telescope is offline.", tp->name); else IDMessage (mydev, "Cannot change property %s while the telescope is offline.", tp->label); tp->s = IPS_IDLE; IDSetText(tp, NULL); return -1; } return 0; } void LX200Basic::connectTelescope() { switch (PowerSP.sp[0].s) { case ISS_ON: if (simulation) { PowerSP.s = IPS_OK; IDSetSwitch (&PowerSP, "Simulated telescope is online."); return; } if (tty_connect(PortT[0].text, 9600, 8, 0, 1, &fd) != TTY_OK) { PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch (&PowerSP, "Error connecting to port %s. Make sure you have BOTH read and write permission to the port.", PortT[0].text); return; } if (check_lx200_connection(fd)) /*if (testTelescope())*/ { PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch (&PowerSP, "Error connecting to Telescope. Telescope is offline."); return; } //IDLog("telescope test successfful\n"); PowerSP.s = IPS_OK; IDSetSwitch (&PowerSP, "Telescope is online. Retrieving basic data..."); getBasicData(); break; case ISS_OFF: PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_IDLE; if (simulation) { IDSetSwitch (&PowerSP, "Simulated Telescope is offline."); return; } IDSetSwitch (&PowerSP, "Telescope is offline."); IDLog("Telescope is offline."); tty_disconnect(fd); break; } } void LX200Basic::slewError(int slewCode) { OnCoordSetSP.s = IPS_IDLE; if (slewCode == 1) IDSetSwitch (&OnCoordSetSP, "Object below horizon."); else if (slewCode == 2) IDSetSwitch (&OnCoordSetSP, "Object below the minimum elevation limit."); else IDSetSwitch (&OnCoordSetSP, "Slew failed."); } void LX200Basic::enableSimulation(bool enable) { simulation = enable; if (simulation) IDLog("Warning: Simulation is activated.\n"); else IDLog("Simulation is disabled.\n"); } void LX200Basic::connectionLost() { PowerSP.s = IPS_IDLE; IDSetSwitch(&PowerSP, "The connection to the telescope is lost."); return; } void LX200Basic::connectionResumed() { PowerS[0].s = ISS_ON; PowerS[1].s = ISS_OFF; PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "The connection to the telescope has been resumed."); } indi-0.5/src/indicom.c0000644000175000017500000005731610610511714012476 0ustar jrjr/* INDI LIB Common routines used by all drivers Copyright (C) 2003 by Jason Harris (jharris@30doradus.org) Elwood C. Downey This is the C version of the astronomical library in KStars modified by Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* needed for sincos() in math.h */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #ifdef _WIN32 #define CX _CX #define CY _CY #endif #include #include #include #include #include #include #include #include #include "indicom.h" #ifdef _WIN32 #undef CX #undef CY #endif const char * Direction[] = { "North", "West", "East", "South", "All"}; const char * SolarSystem[] = { "Mercury", "Venus", "Moon", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"}; /* make it compile on solaris */ #ifndef M_PI #define M_PI 3.14159265358979323846264338327950288419716939937510582097494459 #endif #ifndef _WIN32 #include #define PARITY_NONE 0 #define PARITY_EVEN 1 #define PARITY_ODD 2 #endif /******** Prototypes ***********/ double DegToRad( double num ); double RadToDeg( double num ); void SinCos( double Degrees, double *sina, double *cosa ); double obliquity(void); double constAberr(void); double sunMeanAnomaly(void); double sunMeanLongitude(void); double sunTrueAnomaly(void); double sunTrueLongitude(void); double earthPerihelionLongitude(void); double earthEccentricity(void); double dObliq(void); double dEcLong(void); double julianCenturies(void); double p1( int i1, int i2 ); double p2( int i1, int i2 ); void updateAstroValues( double jd ); void nutate(double *RA, double *Dec); void aberrate(double *RA, double *Dec); void precessFromAnyEpoch(double jd0, double jdf, double *RA, double *Dec); void apparentCoord(double jd0, double jdf, double *RA, double *Dec); void getSexComponents(double value, int *d, int *m, int *s); double K = ( 20.49552 / 3600. ); double Obliquity, K, L, L0, LM, M, M0, O, P; double XP, YP, ZP; double CX, SX, CY, SY, CZ, SZ; double P1[3][3], P2[3][3]; double deltaObliquity, deltaEcLong; double e, T; double obliquity() { return Obliquity; } double constAberr() { return K; } double sunMeanAnomaly() { return M; } double sunMeanLongitude() { return L; } double sunTrueAnomaly() { return M0; } double sunTrueLongitude() { return L0; } double earthPerihelionLongitude() { return P; } double earthEccentricity() { return e; } double dObliq() { return deltaObliquity; } double dEcLong() { return deltaEcLong; } double julianCenturies() { return T; } double p1( int i1, int i2 ) { return P1[i1][i2]; } double p2( int i1, int i2 ) { return P2[i1][i2]; } void updateAstroValues( double jd ) { static double days = 0; double jm; double C, U, dObliq2; /* Nutation parameters */ double L2, M2, O2; double sin2L, cos2L, sin2M, cos2M; double sinO, cosO, sin2O, cos2O; /* no need to recalculate if same as previous JD */ if (days == jd) return; days = jd; /* Julian Centuries since J2000.0 */ T = ( jd - J2000 ) / 36525.; /* Julian Millenia since J2000.0 */ jm = T / 10.0; /* Sun's Mean Longitude */ L = ( 280.46645 + 36000.76983*T + 0.0003032*T*T ); /* Sun's Mean Anomaly */ M = ( 357.52910 + 35999.05030*T - 0.0001559*T*T - 0.00000048*T*T*T ); /* Moon's Mean Longitude */ LM = ( 218.3164591 + 481267.88134236*T - 0.0013268*T*T + T*T*T/538841. - T*T*T*T/6519400.); /* Longitude of Moon's Ascending Node */ O = ( 125.04452 - 1934.136261*T + 0.0020708*T*T + T*T*T/450000.0 ); /* Earth's orbital eccentricity */ e = 0.016708617 - 0.000042037*T - 0.0000001236*T*T; C = ( 1.914600 - 0.004817*T - 0.000014*T*T ) * sin( DegToRad(M) ) + ( 0.019993 - 0.000101*T ) * sin( 2.0* DegToRad(M) ) + 0.000290 * sin( 3.0* DegToRad(M)); /* Sun's True Longitude */ L0 = ( L + C ); /* Sun's True Anomaly */ M0 = ( M + C ); /* Obliquity of the Ecliptic */ U = T/100.0; dObliq2 = -4680.93*U - 1.55*U*U + 1999.25*U*U*U - 51.38*U*U*U*U - 249.67*U*U*U*U*U - 39.05*U*U*U*U*U*U + 7.12*U*U*U*U*U*U*U + 27.87*U*U*U*U*U*U*U*U + 5.79*U*U*U*U*U*U*U*U*U + 2.45*U*U*U*U*U*U*U*U*U*U; Obliquity = ( 23.43929111 + dObliq2/3600.0); O2 = ( 2.0 * O ); L2 = ( 2.0 * L ); /* twice mean ecl. long. of Sun */ M2 = ( 2.0 * LM); /* twice mean ecl. long. of Moon */ SinCos( O, &sinO, &cosO ); SinCos( O2, &sin2O, &cos2O ); SinCos( L2, &sin2L, &cos2L ); SinCos( M2, &sin2M, &cos2M ); deltaEcLong = ( -17.2*sinO - 1.32*sin2L - 0.23*sin2M + 0.21*sin2O)/3600.0; /* Ecl. long. correction */ deltaObliquity = ( 9.2*cosO + 0.57*cos2L + 0.10*cos2M - 0.09*cos2O)/3600.0; /* Obliq. correction */ /* Compute Precession Matrices: */ XP = ( 0.6406161*T + 0.0000839*T*T + 0.0000050*T*T*T ); YP = ( 0.5567530*T - 0.0001185*T*T - 0.0000116*T*T*T ); ZP = ( 0.6406161*T + 0.0003041*T*T + 0.0000051*T*T*T ); SinCos(XP, &SX, &CX ); SinCos(YP, &SY, &CY ); SinCos(ZP, &SZ, &CZ ); /* P1 is used to precess from any epoch to J2000 */ P1[0][0] = CX*CY*CZ - SX*SZ; P1[1][0] = CX*CY*SZ + SX*CZ; P1[2][0] = CX*SY; P1[0][1] = -1.0*SX*CY*CZ - CX*SZ; P1[1][1] = -1.0*SX*CY*SZ + CX*CZ; P1[2][1] = -1.0*SX*SY; P1[0][2] = -1.0*SY*CZ; P1[1][2] = -1.0*SY*SZ; P1[2][2] = CY; /* P2 is used to precess from J2000 to any other epoch (it is the transpose of P1) */ P2[0][0] = CX*CY*CZ - SX*SZ; P2[1][0] = -1.0*SX*CY*CZ - CX*SZ; P2[2][0] = -1.0*SY*CZ; P2[0][1] = CX*CY*SZ + SX*CZ; P2[1][1] = -1.0*SX*CY*SZ + CX*CZ; P2[2][1] = -1.0*SY*SZ; P2[0][2] = CX*SY; P2[1][2] = -1.0*SX*SY; P2[2][2] = CY; } double DegToRad( double num ) { /*return (num * deg_rad);*/ return (num * (M_PI / 180.0)); } double RadToDeg( double num ) { return (num / (M_PI / 180.0)); } void SinCos( double Degrees, double *sina, double *cosa ) { /**We have two versions of this function. One is ANSI standard, but *slower. The other is faster, but is GNU only. *Using the __GLIBC_ and __GLIBC_MINOR_ constants to determine if the * GNU extension sincos() is defined. */ static int rDirty = 1; double Sin, Cos; if (rDirty) { #ifdef __GLIBC__ #if defined(__GLIBC__) && (__GLIBC_MINOR__ >=1 && !defined(__UCLIBC__)) /* GNU version */ sincos( DegToRad(Degrees), &Sin, &Cos ); #else /* For older GLIBC versions */ Sin = ::sin( DegToRad(Degrees) ); Cos = ::cos( DegToRad(Degrees) ); #endif #else /* ANSI-compliant version */ Sin = sin( DegToRad(Degrees) ); Cos = cos( DegToRad(Degrees) ); rDirty = 0; #endif } else { Sin = sin( DegToRad(Degrees) ); Cos = cos( DegToRad(Degrees) ); } *sina = Sin; *cosa = Cos; } double calculateDec(double latitude, double SDTime) { if (SDTime > 12) SDTime -= 12; return RadToDeg ( atan ( (cos (DegToRad (latitude)) / sin (DegToRad (latitude))) * cos (DegToRad (SDTime))) ); } double calculateRA(double SDTime) { double ra; ra = SDTime + 12; if (ra < 24) return ra; else return (ra - 24); } void nutate(double *RA, double *Dec) { double cosRA, sinRA, cosDec, sinDec, tanDec; double dRA1, dDec1; double cosOb, sinOb; SinCos( *RA, &sinRA, &cosRA ); SinCos( *Dec, &sinDec, &cosDec ); SinCos( obliquity(), &sinOb, &cosOb ); /* Step 2: Nutation */ /* approximate method */ tanDec = sinDec/cosDec; dRA1 = ( dEcLong()*( cosOb + sinOb*sinRA*tanDec ) - dObliq()*cosRA*tanDec ); dDec1 = ( dEcLong()*( sinOb*cosRA ) + dObliq()*sinRA ); *RA = ( *RA + dRA1 ); *Dec = ( *Dec+ dDec1); } void aberrate(double *RA, double *Dec) { double cosRA, sinRA, cosDec, sinDec; double dRA2, dDec2; double cosOb, sinOb, cosL, sinL, cosP, sinP; double K2, e2, tanOb; K2 = constAberr(); /* constant of aberration */ e2 = earthEccentricity(); SinCos( *RA, &sinRA, &cosRA ); SinCos( *Dec, &sinDec, &cosDec ); SinCos( obliquity(), &sinOb, &cosOb ); tanOb = sinOb/cosOb; SinCos( sunTrueLongitude(), &sinL, &cosL ); SinCos( earthPerihelionLongitude(), &sinP, &cosP ); /* Step 3: Aberration */ dRA2 = ( -1.0 * K2 * ( cosRA * cosL * cosOb + sinRA * sinL )/cosDec + e2 * K2 * ( cosRA * cosP * cosOb + sinRA * sinP )/cosDec ); dDec2 = ( -1.0 * K2 * ( cosL * cosOb * ( tanOb * cosDec - sinRA * sinDec ) + cosRA * sinDec * sinL ) + e2 * K2 * ( cosP * cosOb * ( tanOb * cosDec - sinRA * sinDec ) + cosRA * sinDec * sinP ) ); *RA = ( *RA + dRA2 ); *Dec = ( *Dec + dDec2); } void precessFromAnyEpoch(double jd0, double jdf, double *RA, double *Dec) { double cosRA0, sinRA0, cosDec0, sinDec0; double v[3], s[3]; unsigned int i=0; SinCos( *RA, &sinRA0, &cosRA0 ); SinCos( *Dec, &sinDec0, &cosDec0 ); /* Need first to precess to J2000.0 coords */ if ( jd0 != J2000 ) { /* v is a column vector representing input coordinates. */ updateAstroValues(jd0); v[0] = cosRA0*cosDec0; v[1] = sinRA0*cosDec0; v[2] = sinDec0; /*s is the product of P1 and v; s represents the coordinates precessed to J2000 */ for ( i=0; i<3; ++i ) { s[i] = p1( 0, i )*v[0] + p1( 1, i )*v[1] + p1( 2, i )*v[2]; } } else { /* Input coords already in J2000, set s accordingly. */ s[0] = cosRA0*cosDec0; s[1] = sinRA0*cosDec0; s[2] = sinDec0; } updateAstroValues(jdf); /* Multiply P2 and s to get v, the vector representing the new coords. */ for ( i=0; i<3; ++i ) { v[i] = p2( 0, i )*s[0] + p2( 1, i )*s[1] + p2( 2, i )*s[2]; } /*Extract RA, Dec from the vector: RA.setRadians( atan( v[1]/v[0] ) ); */ *RA = RadToDeg( atan2( v[1],v[0] ) ); *Dec = RadToDeg( asin( v[2] ) ); if (*RA < 0.0 ) *RA = ( *RA + 360.0 ); } void apparentCoord(double jd0, double jdf, double *RA, double *Dec) { *RA = *RA * 15.0; precessFromAnyEpoch(jd0,jdf, RA, Dec); updateAstroValues(jdf); nutate(RA, Dec); aberrate(RA, Dec); *RA = *RA / 15.0; } double UTtoJD(struct tm *utm) { int year, month, day, hour, minute, second; int m, y, A, B, C, D; double d, jd; year = utm->tm_year; month = utm->tm_mon; day = utm->tm_mday; hour = utm->tm_hour; minute = utm->tm_min; second = utm->tm_sec; if (month > 2) { m = month; y = year; } else { y = year - 1; m = month + 12; } /* If the date is after 10/15/1582, then take Pope Gregory's modification to the Julian calendar into account */ if (( year >1582 ) || ( year ==1582 && month >9 ) || ( year ==1582 && month ==9 && day >15 )) { A = (int) y/100; B = 2 - A + (int) A/4; } else { B = 0; } if (y < 0) { C = (int) ((365.25*y) - 0.75); } else { C = (int) (365.25*y); } D = (int) (30.6001*(m+1)); d = (double) day + ( (double) hour + ( (double) minute + (double) second/60.0)/60.0)/24.0; jd = B + C + D + d + 1720994.5; return jd; } double JDtoGMST( double jd ) { double Gmst; /* Julian Centuries since J2000.0 */ T = ( jd - J2000 ) / 36525.; /* Greewich Mean Sidereal Time */ Gmst = 280.46061837 + 360.98564736629*(jd-J2000) + 0.000387933*T*T - T*T*T/38710000.0; return Gmst; } int extractISOTime(char *timestr, struct tm *utm) { if (strptime(timestr, "%Y-%m-%dT%H:%M:%S", utm)) return (0); if (strptime(timestr, "%Y/%m/%dT%H:%M:%S", utm)) return (0); if (strptime(timestr, "%Y:%m:%dT%H:%M:%S", utm)) return (0); if (strptime(timestr, "%Y-%m-%dT%H-%M-%S", utm)) return (0); return (-1); } /* sprint the variable a in sexagesimal format into out[]. * w is the number of spaces for the whole part. * fracbase is the number of pieces a whole is to broken into; valid options: * 360000: :mm:ss.ss * 36000: :mm:ss.s * 3600: :mm:ss * 600: :mm.m * 60: :mm * return number of characters written to out, not counting final '\0'. */ int fs_sexa (char *out, double a, int w, int fracbase) { char *out0 = out; unsigned long n; int d; int f; int m; int s; int isneg; /* save whether it's negative but do all the rest with a positive */ isneg = (a < 0); if (isneg) a = -a; /* convert to an integral number of whole portions */ n = (unsigned long)(a * fracbase + 0.5); d = n/fracbase; f = n%fracbase; /* form the whole part; "negative 0" is a special case */ if (isneg && d == 0) out += sprintf (out, "%*s-0", w-2, ""); else out += sprintf (out, "%*d", w, isneg ? -d : d); /* do the rest */ switch (fracbase) { case 60: /* dd:mm */ m = f/(fracbase/60); out += sprintf (out, ":%02d", m); break; case 600: /* dd:mm.m */ out += sprintf (out, ":%02d.%1d", f/10, f%10); break; case 3600: /* dd:mm:ss */ m = f/(fracbase/60); s = f%(fracbase/60); out += sprintf (out, ":%02d:%02d", m, s); break; case 36000: /* dd:mm:ss.s*/ m = f/(fracbase/60); s = f%(fracbase/60); out += sprintf (out, ":%02d:%02d.%1d", m, s/10, s%10); break; case 360000: /* dd:mm:ss.ss */ m = f/(fracbase/60); s = f%(fracbase/60); out += sprintf (out, ":%02d:%02d.%02d", m, s/100, s%100); break; default: printf ("fs_sexa: unknown fracbase: %d\n", fracbase); exit(1); } return (out - out0); } /* convert sexagesimal string str AxBxC to double. * x can be anything non-numeric. Any missing A, B or C will be assumed 0. * optional - and + can be anywhere. * return 0 if ok, -1 if can't find a thing. */ int f_scansexa ( const char *str0, /* input string */ double *dp) /* cracked value, if return 0 */ { double a = 0, b = 0, c = 0; char str[128]; char *neg; int r; /* copy str0 so we can play with it */ strncpy (str, str0, sizeof(str)-1); str[sizeof(str)-1] = '\0'; neg = strchr(str, '-'); if (neg) *neg = ' '; r = sscanf (str, "%lf%*[^0-9]%lf%*[^0-9]%lf", &a, &b, &c); if (r < 1) return (-1); *dp = a + b/60 + c/3600; if (neg) *dp *= -1; return (0); } void getSexComponents(double value, int *d, int *m, int *s) { *d = (int) fabs(value); *m = (int) ((fabs(value) - *d) * 60.0); *s = (int) rint(((fabs(value) - *d) * 60.0 - *m) *60.0); if (value < 0) *d *= -1; } /* fill buf with properly formatted INumber string. return length */ int numberFormat (char *buf, const char *format, double value) { int w, f, s; char m; if (sscanf (format, "%%%d.%d%c", &w, &f, &m) == 3 && m == 'm') { /* INDI sexi format */ switch (f) { case 9: s = 360000; break; case 8: s = 36000; break; case 6: s = 3600; break; case 5: s = 600; break; default: s = 60; break; } return (fs_sexa (buf, value, w-f, s)); } else { /* normal printf format */ return (sprintf (buf, format, value)); } } double angularDistance(double fromRA, double fromDEC, double toRA, double toDEC) { double dalpha = DegToRad(fromRA) - DegToRad(toRA); double ddelta = DegToRad(fromDEC) - DegToRad(toDEC); double sa = sin(dalpha/2.); double sd = sin(ddelta/2.); double hava = sa*sa; double havd = sd*sd; double aux = havd + cos (DegToRad(fromDEC)) * cos(DegToRad(toDEC)) * hava; return (RadToDeg ( 2 * fabs(asin( sqrt(aux) )))); } /* log message locally. * this has nothing to do with XML or any Clients. */ void IDLog (const char *fmt, ...) { va_list ap; fprintf (stderr, "%s ", timestamp()); va_start (ap, fmt); vfprintf (stderr, fmt, ap); va_end (ap); } /* return current system time in message format */ const char * timestamp() { static char ts[32]; struct tm *tp; time_t t; time (&t); tp = gmtime (&t); strftime (ts, sizeof(ts), "%Y-%m-%dT%H:%M:%S", tp); return (ts); } int tty_timeout(int fd, int timeout) { struct timeval tv; fd_set readout; int retval; FD_ZERO(&readout); FD_SET(fd, &readout); /* wait for 'timeout' seconds */ tv.tv_sec = timeout; tv.tv_usec = 0; /* Wait till we have a change in the fd status */ retval = select (fd+1, &readout, NULL, NULL, &tv); /* Return 0 on successful fd change */ if (retval > 0) return TTY_OK; /* Return -1 due to an error */ else if (retval == -1) return TTY_SELECT_ERROR; /* Return -2 if time expires before anything interesting happens */ else return TTY_TIME_OUT; } int tty_write(int fd, const char * buf, int nbytes, int *nbytes_written) { int bytes_w = 0; *nbytes_written = 0; while (nbytes > 0) { bytes_w = write(fd, buf, nbytes); if (bytes_w < 0) return TTY_WRITE_ERROR; *nbytes_written += bytes_w; buf += bytes_w; nbytes -= bytes_w; } return TTY_OK; } int tty_write_string(int fd, const char * buf, int *nbytes_written) { unsigned int nbytes; int bytes_w = 0; *nbytes_written = 0; nbytes = strlen(buf); while (nbytes > 0) { bytes_w = write(fd, buf, nbytes); if (bytes_w < 0) return TTY_WRITE_ERROR; *nbytes_written += bytes_w; buf += bytes_w; nbytes -= bytes_w; } return TTY_OK; } int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read) { int bytesRead = 0; int err = 0; *nbytes_read =0; if (nbytes <=0) return TTY_PARAM_ERROR; while (nbytes > 0) { if ( (err = tty_timeout(fd, timeout)) ) return err; bytesRead = read(fd, buf, ((unsigned) nbytes)); if (bytesRead < 0 ) return TTY_READ_ERROR; buf += bytesRead; *nbytes_read += bytesRead; nbytes -= bytesRead; } return TTY_OK; } int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read) { int bytesRead = 0; int err = TTY_OK; *nbytes_read = 0; for (;;) { if ( (err = tty_timeout(fd, timeout)) ) return err; bytesRead = read(fd, buf, 1); if (bytesRead < 0 ) return TTY_READ_ERROR; if (bytesRead) (*nbytes_read)++; if (*buf == stop_char) return TTY_OK; buf += bytesRead; } return TTY_TIME_OUT; } int tty_connect(const char *device, int bit_rate, int word_size, int parity, int stop_bits, int *fd) { #ifdef _WIN32 return TTY_PORT_FAILURE; #else int t_fd=0; char *msg=NULL; int bps; struct termios tty_setting; if ( (t_fd = open(device, O_RDWR | O_NOCTTY )) == -1) return TTY_PORT_FAILURE; /* Control Modes Set bps rate */ switch (bit_rate) { case 0: bps = B0; break; case 50: bps = B50; break; case 75: bps = B75; break; case 110: bps = B110; break; case 134: bps = B134; break; case 150: bps = B150; break; case 200: bps = B200; break; case 300: bps = B300; break; case 600: bps = B600; break; case 1200: bps = B1200; break; case 1800: bps = B1800; break; case 2400: bps = B2400; break; case 4800: bps = B4800; break; case 9600: bps = B9600; break; case 19200: bps = B19200; break; case 38400: bps = B38400; break; case 57600: bps = B57600; break; case 115200: bps = B115200; break; case 230400: bps = B230400; break; default: if (asprintf(&msg, "tty_connect: %d is not a valid bit rate.", bit_rate) < 0) perror(NULL); else perror(msg); return TTY_PARAM_ERROR; } if ((cfsetispeed(&tty_setting, bps) < 0) || (cfsetospeed(&tty_setting, bps) < 0)) { perror("tty_connect: failed setting bit rate."); return TTY_PORT_FAILURE; } /* Control Modes set no flow control word size, parity and stop bits. Also don't hangup automatically and ignore modem status. Finally enable receiving characters. */ tty_setting.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | HUPCL | CRTSCTS); tty_setting.c_cflag |= (CLOCAL | CREAD); /* word size */ switch (word_size) { case 5: tty_setting.c_cflag |= CS5; break; case 6: tty_setting.c_cflag |= CS6; break; case 7: tty_setting.c_cflag |= CS7; break; case 8: tty_setting.c_cflag |= CS8; break; default: fprintf( stderr, "Default\n") ; if (asprintf(&msg, "tty_connect: %d is not a valid data bit count.", word_size) < 0) perror(NULL); else perror(msg); return TTY_PARAM_ERROR; } /* parity */ switch (parity) { case PARITY_NONE: break; case PARITY_EVEN: tty_setting.c_cflag |= PARENB; break; case PARITY_ODD: tty_setting.c_cflag |= PARENB | PARODD; break; default: fprintf( stderr, "Default1\n") ; if (asprintf(&msg, "tty_connect: %d is not a valid parity selection value.", parity) < 0) perror(NULL); else perror(msg); return TTY_PARAM_ERROR; } /* stop_bits */ switch (stop_bits) { case 1: break; case 2: tty_setting.c_cflag |= CSTOPB; break; default: fprintf( stderr, "Default2\n") ; if (asprintf(&msg, "tty_connect: %d is not a valid stop bit count.", stop_bits) < 0) perror(NULL); else perror(msg); return TTY_PARAM_ERROR; } /* Control Modes complete */ /* Ignore bytes with parity errors and make terminal raw and dumb.*/ tty_setting.c_iflag &= ~(PARMRK | ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON | IXANY); tty_setting.c_iflag |= INPCK | IGNPAR | IGNBRK; /* Raw output.*/ tty_setting.c_oflag &= ~(OPOST | ONLCR); /* Local Modes Don't echo characters. Don't generate signals. Don't process any characters.*/ tty_setting.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN | NOFLSH | TOSTOP); tty_setting.c_lflag |= NOFLSH; /* blocking read until 1 char arrives */ tty_setting.c_cc[VMIN] = 1; tty_setting.c_cc[VTIME] = 0; /* now clear input and output buffers and activate the new terminal settings */ tcflush(t_fd, TCIOFLUSH); if (tcsetattr(t_fd, TCSANOW, &tty_setting)) { perror("tty_connect: failed setting attributes on serial port."); tty_disconnect(t_fd); return TTY_PORT_FAILURE; } *fd = t_fd; /* return success */ return TTY_OK; #endif } int tty_disconnect(int fd) { #ifdef _WIN32 return TTY_ERRNO; #else int err; tcflush(fd, TCIOFLUSH); err = close(fd); if (err != 0) return TTY_ERRNO; return TTY_OK; #endif } void tty_error_msg(int err_code, char *err_msg, int err_msg_len) { char error_string[512]; switch (err_code) { case TTY_OK: strncpy(err_msg, "No Error", err_msg_len); break; case TTY_READ_ERROR: snprintf(error_string, 512, "Read Error: %s", strerror(errno)); strncpy(err_msg, error_string, err_msg_len); break; case TTY_WRITE_ERROR: snprintf(error_string, 512, "Write Error: %s", strerror(errno)); strncpy(err_msg, error_string, err_msg_len); break; case TTY_SELECT_ERROR: snprintf(error_string, 512, "Select Error: %s", strerror(errno)); strncpy(err_msg, error_string, err_msg_len); break; case TTY_TIME_OUT: strncpy(err_msg, "Timeout error", err_msg_len); break; case TTY_PORT_FAILURE: snprintf(error_string, 512, "Port failure Error: %s", strerror(errno)); strncpy(err_msg, error_string, err_msg_len); break; case TTY_PARAM_ERROR: strncpy(err_msg, "Parameter error", err_msg_len); break; case TTY_ERRNO: snprintf(error_string, 512, "%s", strerror(errno)); strncpy(err_msg, error_string, err_msg_len); break; default: strncpy(err_msg, "Error: unrecognized error code", err_msg_len); break; } } indi-0.5/src/eventloop.c0000644000175000017500000002447510610474331013072 0ustar jrjr#if 0 INDI Copyright (C) 2003 Elwood C. Downey This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif /* suite of functions to implement an event driven program. * * callbacks may be registered that are triggered when a file descriptor * will not block when read; * * timers may be registered that will run no sooner than a specified delay from * the moment they were registered; * * work procedures may be registered that are called when there is nothing * else to do; * #define MAIN_TEST for a stand-alone test program. */ #include #include #include #include #include #include #include #include "eventloop.h" /* info about one registered callback. * the malloced array cback is never shrunk, entries are reused. new id's are * the index of first unused slot in array (and thus reused like unix' open(2)). */ typedef struct { int in_use; /* flag to mark this record is active */ int fd; /* fd descriptor to watch for read */ void *ud; /* user's data handle */ CBF *fp; /* callback function */ } CB; static CB *cback; /* malloced list of callbacks */ static int ncback; /* n entries in cback[] */ static int ncbinuse; /* n entries in cback[] marked in_use */ static int lastcb; /* cback index of last cb called */ /* info about one registered timer function. * the entries are kept sorted by decreasing time remaining before firing. */ typedef struct { int tgo; /* trigger time, ms from epoch */ void *ud; /* user's data handle */ TCF *fp; /* timer function */ int tid; /* unique id for this timer */ } TF; static TF *timef; /* malloced list of timer functions */ static int ntimef; /* n entries in ntimef[] */ static struct timeval epoch; /* arbitrary t0 */ static int tid; /* source of unique timer ids */ #define EPOCHDT(tp) /* ms from epoch to timeval *tp */ \ (((tp)->tv_sec-epoch.tv_sec)*1000 + ((tp)->tv_usec-epoch.tv_usec)/1000) /* info about one registered work procedure. * the malloced array wproc is never shrunk, entries are reused. new id's are * the index of first unused slot in array (and thus reused like unix' open(2)). */ typedef struct { int in_use; /* flag to mark this record is active */ void *ud; /* user's data handle */ WPF *fp; /* work proc function function */ } WP; static WP *wproc; /* malloced list of work procedures */ static int nwproc; /* n entries in wproc[] */ static int nwpinuse; /* n entries in wproc[] marked in-use */ static int lastwp; /* wproc index of last workproc called*/ static void runWorkProc (void); static void callCallback(fd_set *rfdp); static void checkTimer(); static void oneLoop(void); /* inf loop to dispatch callbacks, work procs and timers as necessary. * never returns. */ void eventLoop() { /* init epoch to now */ gettimeofday (&epoch, NULL); /* run loop forever */ while (1) oneLoop(); } /* register a new callback, fp, to be called with ud as arg when fd is ready. * return a unique callback id for use with rmCallback(). */ int addCallback (int fd, CBF *fp, void *ud) { CB *cp; /* reuse first unused slot or grow */ for (cp = cback; cp < &cback[ncback]; cp++) if (!cp->in_use) break; if (cp == &cback[ncback]) { cback = cback ? (CB *) realloc (cback, (ncback+1)*sizeof(CB)) : (CB *) malloc (sizeof(CB)); cp = &cback[ncback++]; } /* init new entry */ cp->in_use = 1; cp->fp = fp; cp->ud = ud; cp->fd = fd; ncbinuse++; /* id is index into array */ return (cp - cback); } /* remove the callback with the given id, as returned from addCallback(). * silently ignore if id not valid. */ void rmCallback (int cid) { CB *cp; /* validate id */ if (cid < 0 || cid >= ncback) return; cp = &cback[cid]; if (!cp->in_use) return; /* mark for reuse */ cp->in_use = 0; ncbinuse--; } /* register a new timer function, fp, to be called with ud as arg after ms * milliseconds. add to list in order of decreasing time from epoch, ie, * last entry runs soonest. return id for use with rmTimer(). */ int addTimer (int ms, TCF *fp, void *ud) { struct timeval t; TF *tp; /* get time now */ gettimeofday (&t, NULL); /* add one entry */ timef = timef ? (TF *) realloc (timef, (ntimef+1)*sizeof(TF)) : (TF *) malloc (sizeof(TF)); tp = &timef[ntimef++]; /* init new entry */ tp->ud = ud; tp->fp = fp; tp->tgo = EPOCHDT(&t) + ms; /* bubble down sorted by start time */ for ( ; tp > timef && tp[0].tgo > tp[-1].tgo; tp--) { TF tmptf = tp[-1]; tp[-1] = tp[0]; tp[0] = tmptf; } /* store and return new unique id */ return (tp->tid = ++tid); } /* remove the timer with the given id, as returned from addTimer(). * silently ignore if id not found. */ void rmTimer (int timer_id) { TF *tp; /* find it */ for (tp = timef; tp < &timef[ntimef]; tp++) if (tp->tid == timer_id) break; if (tp == &timef[ntimef]) return; /* bubble it out */ for (++tp; tp < &timef[ntimef]; tp++) tp[-1] = tp[0]; /* shrink list */ timef = (TF *) realloc (timef, (--ntimef)*sizeof(CB)); } /* add a new work procedure, fp, to be called with ud when nothing else to do. * return unique id for use with rmWorkProc(). */ int addWorkProc (WPF *fp, void *ud) { WP *wp; /* reuse first unused slot or grow */ for (wp = wproc; wp < &wproc[nwproc]; wp++) if (!wp->in_use) break; if (wp == &wproc[nwproc]) { wproc = wproc ? (WP *) realloc (wproc, (nwproc+1)*sizeof(WP)) : (WP *) malloc (sizeof(WP)); wp = &wproc[nwproc++]; } /* init new entry */ wp->in_use = 1; wp->fp = fp; wp->ud = ud; nwpinuse++; /* id is index into array */ return (wp - wproc); } /* remove the work proc with the given id, as returned from addWorkProc(). * silently ignore if id not found. */ void rmWorkProc (int wid) { WP *wp; /* validate id */ if (wid < 0 || wid >= nwproc) return; wp = &wproc[wid]; if (!wp->in_use) return; /* mark for reuse */ wp->in_use = 0; nwpinuse--; } /* run next work procedure */ static void runWorkProc () { WP *wp; /* skip if list is empty */ if (!nwpinuse) return; /* find next */ do { lastwp = (lastwp+1) % nwproc; wp = &wproc[lastwp]; } while (!wp->in_use); /* run */ (*wp->fp) (wp->ud); } /* run next callback whose fd is listed as ready to go in rfdp */ static void callCallback(fd_set *rfdp) { CB *cp; /* skip if list is empty */ if (!ncbinuse) return; /* find next */ do { lastcb = (lastcb+1) % ncback; cp = &cback[lastcb]; } while (!cp->in_use || !FD_ISSET (cp->fd, rfdp)); /* run */ (*cp->fp) (cp->fd, cp->ud); } /* run the next timer callback whose time has come, if any. all we have to do * is is check the last entry in timef[] because it is sorted in decreasing * order of time from epoch to run, ie, last entry runs soonest. */ static void checkTimer() { struct timeval now; int tgonow; TF *tp; /* skip if list is empty */ if (!ntimef) return; gettimeofday (&now, NULL); tgonow = EPOCHDT (&now); tp = &timef[ntimef-1]; if (tp->tgo <= tgonow) { (*tp->fp) (tp->ud); ntimef--; /* we assume it didn't remove itself */ } } /* check fd's from each active callback. * if any ready, call their callbacks else call each registered work procedure. */ static void oneLoop() { struct timeval tv, *tvp; fd_set rfd; CB *cp; int maxfd, ns; /* build list of callback file descriptors to check */ FD_ZERO (&rfd); maxfd = -1; for (cp = cback; cp < &cback[ncback]; cp++) { if (cp->in_use) { FD_SET (cp->fd, &rfd); if (cp->fd > maxfd) maxfd = cp->fd; } } /* determine timeout: * if there are work procs * set delay = 0 * else if there is at least one timer func * set delay = time until soonest timer func expires * else * set delay = forever */ if (nwpinuse > 0) { tvp = &tv; tvp->tv_sec = tvp->tv_usec = 0; } else if (ntimef > 0) { struct timeval now; int late; gettimeofday (&now, NULL); late = timef[ntimef-1].tgo - EPOCHDT (&now); if (late < 0) late = 0; tvp = &tv; tvp->tv_sec = late/1000; tvp->tv_usec = 1000*(late%1000); } else tvp = NULL; /* check file descriptors, timeout depending on pending work */ ns = select (maxfd+1, &rfd, NULL, NULL, tvp); if (ns < 0) { perror ("select"); exit(1); } /* dispatch */ checkTimer(); if (ns == 0) runWorkProc(); else callCallback(&rfd); } #if defined(MAIN_TEST) /* make a small stand-alone test program. */ #include #include int mycid; int mywid; int mytid; int user_a; int user_b; int counter; void wp (void *ud) { struct timeval tv; gettimeofday (&tv, NULL); printf ("workproc @ %ld.%03ld %d %d\n", (long)tv.tv_sec, (long)tv.tv_usec/1000, counter, ++(*(int*)ud)); } void to (void *ud) { printf ("timeout %d\n", (int)ud); } void stdinCB (int fd, void *ud) { char c; if (read (fd, &c, 1) != 1) { perror ("read"); exit(1); } switch (c) { case '+': counter++; break; case '-': counter--; break; case 'W': mywid = addWorkProc (wp, &user_b); break; case 'w': rmWorkProc (mywid); break; case 'c': rmCallback (mycid); break; case 't': rmTimer (mytid); break; case '1': mytid = addTimer (1000, to, (void *)1); break; case '2': mytid = addTimer (2000, to, (void *)2); break; case '3': mytid = addTimer (3000, to, (void *)3); break; case '4': mytid = addTimer (4000, to, (void *)4); break; case '5': mytid = addTimer (5000, to, (void *)5); break; default: return; /* silently absorb other chars like \n */ } printf ("callback: %d\n", ++(*(int*)ud)); } int main (int ac, char *av[]) { (void) addCallback (0, stdinCB, &user_a); eventLoop(); exit(0); } #endif indi-0.5/src/tools/0000755000175000017500000000000011017761434012044 5ustar jrjrindi-0.5/src/tools/compiler.c0000644000175000017500000004306110605175651014030 0ustar jrjr/* module to compile and execute a c-style arithmetic expression made of INDI * operands. operand names must contain 2 dots and be surrounded by quotes. * The expression is compiled and the names of each operand are stored. The * values of an operand can be set later by name. Evaluation uses the last * known operand value. * * one reason this is so nice and tight is that all opcodes are the same size * (an int) and the tokens the parser returns are directly usable as opcodes. * constants and variables are compiled as an opcode with an offset into the * auxiliary consts and vars arrays. * * this is not reentrant, but new expressions can be compiled as desired. */ #include #include #include #include #include static int next_token (void); static int chk_funcs (void); static void skip_double (void); static int compile (int prec); static int execute (double *result); static int parse_fieldname (char name[], int len); /* parser tokens and opcodes, as necessary */ enum { HALT, /* HALT = 0 serves as good initial default */ /* binary operators (precedences in table, below) */ ADD, SUB, MULT, DIV, AND, OR, GT, GE, EQ, NE, LT, LE, /* unary ops, precedence all UNI_PREC */ NEG, NOT, /* symantically operands, ie, constants, variables and all functions */ CONST, VAR, ABS, FLOOR, SIN, COS, TAN, ASIN, ACOS, ATAN, PITOK, /* built-in constant, pi */ DEGRAD, RADDEG, LOG, LOG10, EXP, SQRT, POW, ATAN2, }; /* purely tokens - never get compiled as such */ #define LPAREN 255 #define RPAREN 254 #define COMMA 253 #define ERR (-1) /* precedence of each of the binary operators. * in case of a tie, compiler associates left-to-right. * N.B. each entry's index must correspond to its #define! */ static int precedence[] = {0,5,5,6,6,2,1,4,4,3,3,4,4}; #define UNI_PREC 7 /* unary ops have highest precedence */ /* execute-time operand stack */ #define MAX_STACK 32 static double stack[MAX_STACK], *sp; /* space for compiled opcodes - the "program". * opcodes go in lower 8 bits. * when an opcode has an operand (as CONST and VAR) it is really an array * index in the remaining upper bits. */ #define MAX_PROG 32 static int program[MAX_PROG], *pc; #define OP_SHIFT 8 #define OP_MASK 0xff /* auxiliary operand info. * the operands (all but lower 8 bits) of CONST and VAR are really indeces * into these arrays. thus, no point in making them any longer than you have * bits more than 8 in your machine's int to index into it, ie, make * MAX_OPX < 1 << ((sizeof(int)-1)*8) */ #define MAX_OPX 64 /* max number of operands */ #define MAXFLDLEN 64 /* longest allowed operand name */ typedef struct { int set; /* 1 when v has been set */ char name[MAXFLDLEN]; /* name of operand */ double v; /* last known value of this operand */ } Var; static Var vars[MAX_OPX]; /* operands */ static int nvars; /* number of vars[] in actual use */ static double consts[MAX_OPX]; /* constants */ static int nconsts; /* number of consts[] in actual use */ /* these are global just for easy/rapid access */ static int parens_nest; /* to check that parens end up nested */ static char *err_msg; /* caller provides storage; we point at it with this */ static char *cexpr, *lcexpr; /* pointers that move along caller's expression */ /* compile the given c-style expression. * return 0 if ok, else return -1 and a reason message in errbuf. */ int compileExpr (char *exp, char *errbuf) { /* init the globals. * also delete any flogs used in the previous program. */ cexpr = exp; err_msg = errbuf; pc = program; nvars = nconsts = 0; parens_nest = 0; pc = program; if (compile(0) == ERR) { (void) sprintf (err_msg + strlen(err_msg), " near `%.10s'", lcexpr); return (-1); } if (pc == program) { (void) sprintf (err_msg, "Null program"); return (-1); } *pc++ = HALT; return (0); } /* execute the expression previously compiled with compileExpr(). * return 0 with *vp set to the answer if ok, else return -1 with a reason * why not message in errbuf. */ int evalExpr (double *vp, char *errbuf) { err_msg = errbuf; sp = stack + MAX_STACK; /* grows towards lower addresses */ pc = program; return (execute(vp)); } /* set the value for an operand with the given name to the given value. * return 0 if found else -1. */ int setOperand (char *name, double valu) { int i; for (i = 0; i < nvars; i++) { if (strcmp (name, vars[i].name) == 0) { vars[i].v = valu; vars[i].set = 1; return(0); } } return (-1); } /* return 0 if all operands are set, else -1 */ int allOperandsSet () { int i; for (i = 0; i < nvars; i++) if (!vars[i].set) return (-1); return (0); } /* return a malloced array of each operand name. * N.B. caller must free array, and not modify names. */ int getAllOperands (char ***ops) { int i; *ops = (char **) malloc (nvars * sizeof(char *)); for (i = 0; i < nvars; i++) (*ops)[i] = vars[i].name; return (nvars); } /* return a malloced array of each initialized operand name. * N.B. caller must free array, and not modify the names. */ int getSetOperands (char ***ops) { int i, n; *ops = (char **) malloc (nvars * sizeof(char *)); for (n = i = 0; i < nvars; i++) if (vars[i].set) (*ops)[n++] = vars[i].name; return (n); } /* return a malloced array of each uninitialized operand name. * N.B. caller must free array, and not modify the names. */ int getUnsetOperands (char ***ops) { int i, n; *ops = (char **) malloc (nvars * sizeof(char *)); for (n = i = 0; i < nvars; i++) if (!vars[i].set) (*ops)[n++] = vars[i].name; return (n); } /* called when each different field is written. * this is just called by srch_log() to hide the fact from users of srch* * that srch is really using our vars array to store values. * since this gets called for all fields, it's not an error to not find name. * don't stop when see the first one because a term might appear more than once. */ void compiler_log (name, value) char *name; double value; { Var *vp; for (vp = vars; vp < &vars[nvars]; vp++) if (vp->name && strcmp (vp->name, name) == 0) vp->v = value; } /* get and return the opcode corresponding to the next token. * leave with lcexpr pointing at the new token, cexpr just after it. * also watch for mismatches parens and proper operator/operand alternation. */ static int next_token () { static char toomv[] = "More than %d variables"; static char toomc[] = "More than %d constants"; static char badop[] = "Illegal operator"; int tok = ERR; /* just something illegal */ char c; while (isspace(c = *cexpr)) cexpr++; lcexpr = cexpr++; /* mainly check for a binary operator */ switch (c) { case ',': tok = COMMA; break; case '\0': --cexpr; tok = HALT; break; /* keep returning HALT */ case '+': tok = ADD; break; /* compiler knows when it's really unary */ case '-': tok = SUB; break; /* compiler knows when it's really negate */ case '*': tok = MULT; break; case '/': tok = DIV; break; case '(': parens_nest++; tok = LPAREN; break; case ')': if (--parens_nest < 0) { (void) sprintf (err_msg, "Too many right parens"); return (ERR); } else tok = RPAREN; break; case '|': if (*cexpr == '|') { cexpr++; tok = OR; } else { (void) sprintf (err_msg, badop); return (ERR); } break; case '&': if (*cexpr == '&') { cexpr++; tok = AND; } else { (void) sprintf (err_msg, badop); return (ERR); } break; case '=': if (*cexpr == '=') { cexpr++; tok = EQ; } else { (void) sprintf (err_msg, badop); return (ERR); } break; case '!': if (*cexpr == '=') { cexpr++; tok = NE; } else { tok = NOT; } break; case '<': if (*cexpr == '=') { cexpr++; tok = LE; } else tok = LT; break; case '>': if (*cexpr == '=') { cexpr++; tok = GE; } else tok = GT; break; } if (tok != ERR) return (tok); /* not op so check for a constant, variable or function */ if (isdigit(c) || c == '.') { /* looks like a constant. * leading +- already handled */ if (nconsts > MAX_OPX) { (void) sprintf (err_msg, toomc, MAX_OPX); return (ERR); } consts[nconsts] = atof (lcexpr); tok = CONST | (nconsts++ << OP_SHIFT); skip_double(); } else if (isalpha(c)) { /* check list of functions */ tok = chk_funcs(); if (tok == ERR) { (void) sprintf (err_msg, "Bad function"); return (ERR); } } else if (c == '"') { /* a variable */ if (nvars > MAX_OPX) { (void) sprintf (err_msg, toomv, MAX_OPX); return (ERR); } if (parse_fieldname (vars[nvars].name, MAXFLDLEN) < 0) { (void) sprintf (err_msg, "Bad field"); return (ERR); } else tok = VAR | (nvars++ << OP_SHIFT); } if (tok != ERR) return (tok); /* what the heck is it? */ (void) sprintf (err_msg, "Syntax error"); return (ERR); } /* return funtion token, else ERR. * if find one, update cexpr too. */ static int chk_funcs() { static struct { char *st_name; int st_tok; } symtab[] = { /* be sure to put short names AFTER longer ones. * otherwise, order does not matter. */ {"abs", ABS}, {"floor", FLOOR}, {"acos", ACOS}, {"asin", ASIN}, {"atan2", ATAN2}, {"atan", ATAN}, {"cos", COS}, {"degrad", DEGRAD}, {"exp", EXP}, {"log10", LOG10}, {"log", LOG}, {"pi", PITOK}, {"pow", POW}, {"raddeg", RADDEG}, {"sin", SIN}, {"sqrt", SQRT}, {"tan", TAN}, }; int i; for (i = 0; i < sizeof(symtab)/sizeof(symtab[0]); i++) { int l = strlen (symtab[i].st_name); if (strncmp (lcexpr, symtab[i].st_name, l) == 0) { cexpr += l-1; return (symtab[i].st_tok); } } return (ERR); } /* move cexpr on past a double. * allow sci notation. * no need to worry about a leading '-' or '+' but allow them after an 'e'. * TODO: this handles all the desired cases, but also admits a bit too much * such as things like 1eee2...3. geeze; to skip a double right you almost * have to go ahead and crack it! */ static void skip_double() { int sawe = 0; /* so we can allow '-' or '+' right after an 'e' */ for (;;) { char c = *cexpr; if (isdigit(c) || c=='.' || (sawe && (c=='-' || c=='+'))) { sawe = 0; cexpr++; } else if (c == 'e') { sawe = 1; cexpr++; } else break; } } /* call this whenever you want to dig out the next (sub)expression. * keep compiling instructions as long as the operators are higher precedence * than prec (or until see HALT, COMMA or RPAREN) then return that * "look-ahead" token. * if error, fill in a message in err_msg[] and return ERR. */ static int compile (prec) int prec; { int expect_binop = 0; /* set after we have seen any operand. * used by SUB so it can tell if it really * should be taken to be a NEG instead. */ int tok = next_token (); int *oldpc; for (;;) { int p; if (tok == ERR) return (ERR); if (pc - program >= MAX_PROG) { (void) sprintf (err_msg, "Program is too long"); return (ERR); } /* check for special things like functions, constants and parens */ switch (tok & OP_MASK) { case COMMA: return (tok); case HALT: return (tok); case ADD: if (expect_binop) break; /* procede with binary addition */ /* just skip a unary positive(?) */ tok = next_token(); if (tok == HALT) { (void) sprintf (err_msg, "Term expected after unary +"); return (ERR); } continue; case SUB: if (expect_binop) break; /* procede with binary subtract */ oldpc = pc; tok = compile (UNI_PREC); if (oldpc == pc) { (void) sprintf (err_msg, "Term expected after unary -"); return (ERR); } *pc++ = NEG; expect_binop = 1; continue; case NOT: oldpc = pc; tok = compile (UNI_PREC); if (oldpc == pc) { (void) sprintf (err_msg, "Term expected after unary !"); return (ERR); } *pc++ = NOT; expect_binop = 1; continue; /* one-arg functions */ case ABS: case FLOOR: case SIN: case COS: case TAN: case ASIN: case ACOS: case ATAN: case DEGRAD: case RADDEG: case LOG: case LOG10: case EXP: case SQRT: /* eat up the function's parenthesized argument */ if (next_token() != LPAREN) { (void) sprintf (err_msg, "expecting '(' after function"); return (ERR); } oldpc = pc; if (compile (0) != RPAREN || oldpc == pc) { (void) sprintf (err_msg, "1-arg function arglist error"); return (ERR); } *pc++ = tok; tok = next_token(); expect_binop = 1; continue; /* two-arg functions */ case POW: case ATAN2: /* eat up the function's parenthesized arguments */ if (next_token() != LPAREN) { (void) sprintf (err_msg, "Saw a built-in function: expecting ("); return (ERR); } oldpc = pc; if (compile (0) != COMMA || oldpc == pc) { (void) sprintf (err_msg, "1st of 2-arg function arglist error"); return (ERR); } oldpc = pc; if (compile (0) != RPAREN || oldpc == pc) { (void) sprintf (err_msg, "2nd of 2-arg function arglist error"); return (ERR); } *pc++ = tok; tok = next_token(); expect_binop = 1; continue; /* constants and variables are just like 0-arg functions w/o ()'s */ case CONST: case PITOK: case VAR: *pc++ = tok; tok = next_token(); expect_binop = 1; continue; case LPAREN: oldpc = pc; if (compile (0) != RPAREN) { (void) sprintf (err_msg, "Unmatched left paren"); return (ERR); } if (oldpc == pc) { (void) sprintf (err_msg, "Null expression"); return (ERR); } tok = next_token(); expect_binop = 1; continue; case RPAREN: return (RPAREN); } /* everything else is a binary operator */ if (tok < ADD || tok > LE) { printf ("Bug! Bogus token: %d\n", tok); abort(); } p = precedence[tok]; if (p > prec) { int newtok; oldpc = pc; newtok = compile (p); if (newtok == ERR) return (ERR); if (oldpc == pc) { (void) strcpy (err_msg, "Term or factor expected"); return (ERR); } *pc++ = tok; expect_binop = 1; tok = newtok; } else return (tok); } } /* "run" the program[] compiled with compile(). * if ok, return 0 and the final result, * else return -1 with a reason why not message in err_msg. */ static int execute(result) double *result; { int instr; do { instr = *pc++; switch (instr & OP_MASK) { /* put these in numberic order so hopefully even the dumbest * compiler will choose to use a jump table, not a cascade of ifs. */ case HALT: break; /* outer loop will stop us */ case ADD: sp[1] = sp[1] + sp[0]; sp++; break; case SUB: sp[1] = sp[1] - sp[0]; sp++; break; case MULT: sp[1] = sp[1] * sp[0]; sp++; break; case DIV: sp[1] = sp[1] / sp[0]; sp++; break; case AND: sp[1] = sp[1] && sp[0] ? 1 : 0; sp++; break; case OR: sp[1] = sp[1] || sp[0] ? 1 : 0; sp++; break; case GT: sp[1] = sp[1] > sp[0] ? 1 : 0; sp++; break; case GE: sp[1] = sp[1] >= sp[0] ? 1 : 0; sp++; break; case EQ: sp[1] = sp[1] == sp[0] ? 1 : 0; sp++; break; case NE: sp[1] = sp[1] != sp[0] ? 1 : 0; sp++; break; case LT: sp[1] = sp[1] < sp[0] ? 1 : 0; sp++; break; case LE: sp[1] = sp[1] <= sp[0] ? 1 : 0; sp++; break; case NEG: *sp = -*sp; break; case NOT: *sp = (double)(*sp==0); break; case CONST: *--sp = consts[instr >> OP_SHIFT]; break; case VAR: *--sp = vars[instr>>OP_SHIFT].v; break; case PITOK: *--sp = 4.0*atan(1.0); break; case ABS: *sp = fabs (*sp); break; case FLOOR: *sp = floor (*sp); break; case SIN: *sp = sin (*sp); break; case COS: *sp = cos (*sp); break; case TAN: *sp = tan (*sp); break; case ASIN: *sp = asin (*sp); break; case ACOS: *sp = acos (*sp); break; case ATAN: *sp = atan (*sp); break; case DEGRAD:*sp *= atan(1.0)/45.0; break; case RADDEG:*sp *= 45.0/atan(1.0); break; case LOG: *sp = log (*sp); break; case LOG10: *sp = log10 (*sp); break; case EXP: *sp = exp (*sp); break; case SQRT: *sp = sqrt (*sp); break; case POW: sp[1] = pow (sp[1], sp[0]); sp++; break; case ATAN2: sp[1] = atan2 (sp[1], sp[0]); sp++; break; default: (void) sprintf (err_msg, "Bug! bad opcode: 0x%x", instr); return (-1); } if (sp < stack) { (void) sprintf (err_msg, "Runtime stack overflow"); return (-1); } else if (sp - stack > MAX_STACK) { (void) sprintf (err_msg, "Bug! runtime stack underflow"); return (-1); } } while (instr != HALT); /* result should now be on top of stack */ if (sp != &stack[MAX_STACK - 1]) { (void) sprintf (err_msg, "Bug! stack has %d items", MAX_STACK - (sp-stack)); return (-1); } *result = *sp; return (0); } /* starting with lcexpr pointing at a string expected to be a field name, * ie, at a '"', fill into up to the next '"' into name[], including trailing 0. * if there IS no '"' within len-1 chars, return -1, else 0. * the only sanity check is the string contains two dots. * when return, leave lcexpr alone but move cexpr to just after the second '"'. */ static int parse_fieldname (name, len) char name[]; int len; { char c = '\0'; int ndots = 0; cexpr = lcexpr + 1; while (--len > 0 && (c = *cexpr++) != '"' && c) { *name++ = c; ndots += c == '.'; } if (len == 0 || c != '"' || ndots != 2) return (-1); *name = '\0'; return (0); } /* For RCS Only -- Do Not Edit */ static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: compiler.c,v $ $Date: 2005/11/21 21:33:32 $ $Revision: 1.1 $ $Name: $"}; indi-0.5/src/tools/Makefile0000644000175000017500000000152010610526262013476 0ustar jrjr# relative path to dir with libraries LIBROOT = ../ # compiler and linker flags CC = gcc CLDFLAGS = -g GCCFLAGS = -ffast-math -Wall CFLAGS = $(CLDFLAGS) $(GCCFLAGS) -I$(LIBROOT) LDFLAGS = $(CLDFLAGS) -L$(LIBROOT) LIBS = -llilxml -lindicom -lm -lz # list each sample device TOOLS = getINDI setINDI evalINDI # supporting files comprising the INDI driver framework implementation IDAI = ../eventloop.o # build everything all: tools # build each tool tools: $(TOOLS) # build each INDI driver process getINDI: $(IDAI) getINDIproperty.o $(CC) $(LDFLAGS) -o $@ $(IDAI) getINDIproperty.o $(LIBS) setINDI: $(IDAI) setINDIproperty.o $(CC) $(LDFLAGS) -o $@ $(IDAI) setINDIproperty.o $(LIBS) evalINDI: $(IDAI) evalINDI.o compiler.o $(CC) $(LDFLAGS) -o $@ $(IDAI) evalINDI.o compiler.o $(LIBS) # clean up clean: touch x.o rm -f *.o $(TOOLS) x.err indi-0.5/src/tools/evalINDI.c0000644000175000017500000003511110605175651013606 0ustar jrjr/* evaluate an expression of INDI operands */ /* Overall design: * compile expression, building operand table, if trouble exit 2 * open INDI connection, if trouble exit 2 * send getProperties as required to get operands flowing * watch for messages until get initial values of each operand * evaluate expression, repeat if -w each time an op arrives until true * exit val==0 */ #include #include #include #include #include #include #include #include #include #include #include #include #include "indiapi.h" #include "lilxml.h" extern int compileExpr (char *expr, char *errmsg); extern int evalExpr (double *vp, char *errmsg); extern int allOperandsSet (void); extern int getAllOperands (char ***ops); extern int getSetOperands (char ***ops); extern int getUnsetOperands (char ***ops); extern int setOperand (char *name, double valu); static void usage (void); static void compile (char *expr); static FILE *openINDIServer (void); static void getProps(FILE *fp); static void initProps (FILE *fp); static int pstatestr (char *state); static time_t timestamp (char *ts); static int devcmp (char *op1, char *op2); static int runEval (FILE *fp); static int setOp (XMLEle *root); static XMLEle *nxtEle (FILE *fp); static int readServerChar (FILE *fp); static void onAlarm (int dummy); static char *me; static char host_def[] = "localhost"; /* default host name */ static char *host = host_def; /* working host name */ #define INDIPORT 7624 /* default port */ static int port = INDIPORT; /* working port number */ #define TIMEOUT 2 /* default timeout, secs */ static int timeout = TIMEOUT; /* working timeout, secs */ static LilXML *lillp; /* XML parser context */ static int directfd = -1; /* direct filedes to server, if >= 0 */ static int verbose; /* more tracing */ static int eflag; /* print each updated expression value*/ static int fflag; /* print final expression value */ static int iflag; /* read expresion from stdin */ static int oflag; /* print operands as they change */ static int wflag; /* wait for expression to be true */ int main (int ac, char *av[]) { FILE *fp; /* save our name for usage() */ me = av[0]; /* crack args */ while (--ac && **++av == '-') { char *s = *av; while (*++s) { switch (*s) { case 'd': if (ac < 2) { fprintf (stderr, "-d requires open fileno\n"); usage(); } directfd = atoi(*++av); ac--; break; case 'e': /* print each updated expression value */ eflag++; break; case 'f': /* print final expression value */ fflag++; break; case 'h': if (directfd >= 0) { fprintf (stderr, "Can not combine -d and -h\n"); usage(); } if (ac < 2) { fprintf (stderr, "-h requires host name\n"); usage(); } host = *++av; ac--; break; case 'i': /* read expression from stdin */ iflag++; break; case 'o': /* print operands as they change */ oflag++; break; case 'p': if (directfd >= 0) { fprintf (stderr, "Can not combine -d and -p\n"); usage(); } if (ac < 2) { fprintf (stderr, "-p requires tcp port number\n"); usage(); } port = atoi(*++av); ac--; break; case 't': if (ac < 2) { fprintf (stderr, "-t requires timeout\n"); usage(); } timeout = atoi(*++av); ac--; break; case 'v': /* verbose */ verbose++; break; case 'w': /* wait for expression to be true */ wflag++; break; default: fprintf (stderr, "Unknown flag: %c\n", *s); usage(); } } } /* now there are ac args starting with av[0] */ /* compile expression from av[0] or stdin */ if (ac == 0) compile (NULL); else if (ac == 1) compile (av[0]); else usage(); /* open connection */ if (directfd >= 0) { fp = fdopen (directfd, "r+"); if (!fp) { fprintf (stderr, "Direct fd %d: %s\n",directfd,strerror(errno)); exit(1); } if (verbose) fprintf (stderr, "Using direct fd %d\n", directfd); } else { fp = openINDIServer(); if (verbose) fprintf (stderr, "Connected to %s on port %d\n", host, port); } /* build a parser context for cracking XML responses */ lillp = newLilXML(); /* set up to catch an io timeout function */ signal (SIGALRM, onAlarm); /* send getProperties */ getProps(fp); /* initialize all properties */ initProps(fp); /* evaluate expression, return depending on flags */ return (runEval(fp)); } static void usage() { fprintf (stderr, "Usage: %s [options] [exp]\n", me); fprintf (stderr, "Purpose: evaluate an expression of INDI operands\n"); fprintf (stderr, "Version: $Revision: 1.3 $\n"); fprintf (stderr, "Options:\n"); fprintf (stderr, " -d f : use file descriptor f already open to server\n"); fprintf (stderr, " -e : print each updated expression value\n"); fprintf (stderr, " -f : print final expression value\n"); fprintf (stderr, " -h h : alternate host, default is %s\n", host_def); fprintf (stderr, " -i : read expression from stdin\n"); fprintf (stderr, " -o : print operands as they change\n"); fprintf (stderr, " -p p : alternate port, default is %d\n", INDIPORT); fprintf (stderr, " -t t : max secs to wait, 0 is forever, default is %d\n",TIMEOUT); fprintf (stderr, " -v : verbose (cummulative)\n"); fprintf (stderr, " -w : wait for expression to evaluate as true\n"); fprintf (stderr, "[exp] is an arith expression built from the following operators and functons:\n"); fprintf (stderr, " ! + - * / && || > >= == != < <=\n"); fprintf (stderr, " pi sin(rad) cos(rad) tan(rad) asin(x) acos(x) atan(x) atan2(y,x) abs(x)\n"); fprintf (stderr, " degrad(deg) raddeg(rad) floor(x) log(x) log10(x) exp(x) sqrt(x) pow(x,exp)\n"); fprintf (stderr, " operands are of the form \"device.name.element\" (including quotes), where\n"); fprintf (stderr, " element may be:\n"); fprintf (stderr, " _STATE evaluated to 0,1,2,3 from Idle,Ok,Busy,Alert.\n"); fprintf (stderr, " _TS evaluated to UNIX seconds from epoch.\n"); fprintf (stderr, " Switch vectors are evaluated to 0,1 from Off,On.\n"); fprintf (stderr, " Light vectors are evaluated to 0-3 as per _STATE.\n"); fprintf (stderr, "Examples:\n"); fprintf (stderr, " To print 0/1 whether Security.Doors.Front or .Rear are in Alert:\n"); fprintf (stderr, " evalINDI -f '\"Security.Doors.Front\"==3 || \"Security.Doors.Rear\"==3'\n"); fprintf (stderr, " To exit 0 if the Security property as a whole is in a state of Ok:\n"); fprintf (stderr, " evalINDI '\"Security.Security._STATE\"==1'\n"); fprintf (stderr, " To wait for RA and Dec to be near zero and watch their values as they change:\n"); fprintf (stderr, " evalINDI -t 0 -wo 'abs(\"Mount.EqJ2K.RA\")<.01 && abs(\"Mount.EqJ2K.Dec\")<.01'\n"); fprintf (stderr, "Exit 0 if expression evaluates to non-0, 1 if 0, else 2\n"); exit (1); } /* compile the given expression else read from stdin. * exit(2) if trouble. */ static void compile (char *expr) { char errmsg[1024]; char *exp = expr; if (!exp) { /* read expression from stdin */ int nr, nexp = 0; exp = malloc(1024); while ((nr = fread (exp+nexp, 1, 1024, stdin)) > 0) exp = realloc (exp, (nexp+=nr)+1024); exp[nexp] = '\0'; } if (verbose) fprintf (stderr, "Compiling: %s\n", exp); if (compileExpr (exp, errmsg) < 0) { fprintf (stderr, "Compile err: %s\n", errmsg); exit(2); } if (exp != expr) free (exp); } /* open a connection to the given host and port or die. * return FILE pointer to socket. */ static FILE * openINDIServer (void) { struct sockaddr_in serv_addr; struct hostent *hp; int sockfd; /* lookup host address */ hp = gethostbyname (host); if (!hp) { perror ("gethostbyname"); exit (2); } /* create a socket to the INDI server */ (void) memset ((char *)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr_list[0]))->s_addr; serv_addr.sin_port = htons(port); if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { perror ("socket"); exit(2); } /* connect */ if (connect (sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0){ perror ("connect"); exit(2); } /* prepare for line-oriented i/o with client */ return (fdopen (sockfd, "r+")); } /* invite each device referenced in the expression to report its properties. */ static void getProps(FILE *fp) { char **ops; int nops; int i, j; /* get each operand used in the expression */ nops = getAllOperands (&ops); /* send getProperties for each unique device referenced */ for (i = 0; i < nops; i++) { for (j = 0; j < i; j++) if (devcmp (ops[i], ops[j]) == 0) break; if (j < i) continue; if (verbose) fprintf (stderr, "sending getProperties for %.*s\n", strchr (ops[i],'.')-ops[i], ops[i]); fprintf (fp, "\n", INDIV, strchr (ops[i],'.')-ops[i], ops[i]); } } /* wait for defXXX or setXXX for each property in the expression. * return when find all operands are found or * exit(2) if time out waiting for all known operands. */ static void initProps (FILE *fp) { alarm (timeout); while (allOperandsSet() < 0) { if (setOp (nxtEle (fp)) == 0) alarm(timeout); } alarm (0); } /* pull apart the name and value from the given message, and set operand value. * ignore any other messages. * return 0 if found a recognized operand else -1 */ static int setOp (XMLEle *root) { char *t = tagXMLEle (root); char *d = findXMLAttValu (root, "device"); char *n = findXMLAttValu (root, "name"); int nset = 0; double v; char prop[1024]; XMLEle *ep; /* check values */ if (!strcmp (t,"defNumberVector") || !strcmp (t,"setNumberVector")) { for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) { char *et = tagXMLEle(ep); if (!strcmp (et,"defNumber") || !strcmp (et,"oneNumber")) { sprintf (prop, "%s.%s.%s", d, n, findXMLAttValu(ep,"name")); v = atof(pcdataXMLEle(ep)); if (setOperand (prop, v) == 0) { nset++; if (oflag) fprintf (stderr, "%s=%g\n", prop, v); } } } } else if(!strcmp(t,"defSwitchVector") || !strcmp(t,"setSwitchVector")){ for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) { char *et = tagXMLEle(ep); if (!strcmp (et,"defSwitch") || !strcmp (et,"oneSwitch")) { sprintf (prop, "%s.%s.%s", d, n, findXMLAttValu(ep,"name")); v = (double)!strcmp(pcdataXMLEle(ep),"On"); if (setOperand (prop, v) == 0) { nset++; if (oflag) fprintf (stderr, "%s=%g\n", prop, v); } } } } else if(!strcmp(t,"defLightVector") || !strcmp(t,"setLightVector")){ for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) { char *et = tagXMLEle(ep); if (!strcmp (et,"defLight") || !strcmp (et,"oneLight")) { sprintf (prop, "%s.%s.%s", d, n, findXMLAttValu(ep,"name")); v = (double)pstatestr(pcdataXMLEle(ep)); if (setOperand (prop, v) == 0) { nset++; if (oflag) fprintf (stderr, "%s=%g\n", prop, v); } } } } /* check special elements */ t = findXMLAttValu (root, "state"); if (t[0]) { sprintf (prop, "%s.%s._STATE", d, n); v = (double)pstatestr(t); if (setOperand (prop, v) == 0) { nset++; if (oflag) fprintf (stderr, "%s=%g\n", prop, v); } } t = findXMLAttValu (root, "timestamp"); if (t[0]) { sprintf (prop, "%s.%s._TS", d, n); v = (double)timestamp(t); if (setOperand (prop, v) == 0) { nset++; if (oflag) fprintf (stderr, "%s=%g\n", prop, v); } } /* return whether any were set */ return (nset > 0 ? 0 : -1); } /* evaluate the expression after seeing any operand change. * return whether expression evaluated to 0. * exit(2) is trouble or timeout waiting for operands we expect. */ static int runEval (FILE *fp) { char errmsg[1024]; double v; alarm(timeout); while (1) { if (evalExpr (&v, errmsg) < 0) { fprintf (stderr, "Eval: %s\n", errmsg); exit(2); } if (eflag) fprintf (stderr, "%g\n", v); if (!wflag || v != 0) break; while (setOp (nxtEle (fp)) < 0) continue; alarm(timeout); } alarm(0); if (!eflag && fflag) fprintf (stderr, "%g\n", v); return (v == 0); } /* return 0|1|2|3 depending on whether state is Idle|Ok|Busy|. */ static int pstatestr (char *state) { if (!strcmp (state, "Idle")) return (0); if (!strcmp (state, "Ok")) return (1); if (!strcmp (state, "Busy")) return (2); return (3); } /* return UNIX time for the given ISO 8601 time string */ static time_t timestamp (char *ts) { struct tm tm; if (6 == sscanf (ts, "%d-%d-%dT%d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec)) { tm.tm_mon -= 1; /* want 0..11 */ tm.tm_year -= 1900; /* want years since 1900 */ return (mktime (&tm)); } else return ((time_t)-1); } /* return 0 if the device portion of the two given property specs match, else 1 */ static int devcmp (char *op1, char *op2) { int n1 = strchr(op1,'.') - op1; int n2 = strchr(op2,'.') - op2; return (n1 != n2 || strncmp (op1,op2,n1)); } /* monitor server and return the next complete XML message. * exit(2) if time out. * N.B. caller must call delXMLEle() */ static XMLEle * nxtEle (FILE *fp) { char msg[1024]; /* read from server, exit if trouble or see malformed XML */ while(1) { XMLEle *root = readXMLEle (lillp, readServerChar(fp), msg); if (root) { /* found a complete XML element */ if (verbose > 1) prXMLEle (stderr, root, 0); return (root); } else if (msg[0]) { fprintf (stderr, "Bad XML from %s/%d: %s\n", host, port, msg); exit(2); } } } /* read next char from the INDI server connected by fp */ static int readServerChar (FILE *fp) { int c = fgetc (fp); if (c == EOF) { if (ferror(fp)) perror ("read"); else fprintf (stderr,"INDI server %s/%d disconnected\n", host, port); exit (2); } if (verbose > 2) fprintf (stderr, "Read %c\n", c); return (c); } /* called after timeout seconds waiting to hear from server. * print reason for trouble and exit(2). */ static void onAlarm (int dummy) { char **ops; int nops; /* report any unseen operands if any, else just say timed out */ if ((nops = getUnsetOperands (&ops)) > 0) { fprintf (stderr, "No values seen for"); while (nops-- > 0) fprintf (stderr, " %s", ops[nops]); fprintf (stderr, "\n"); } else fprintf (stderr, "Timed out waiting for new values\n"); exit (2); } indi-0.5/src/tools/getINDIproperty.c0000644000175000017500000003622610610472752015251 0ustar jrjr/* connect to an INDI server and show all desired device.property.element * with possible wild card * in any category. * All types but BLOBs are handled from their defXXX messages. Receipt of a * defBLOB sends enableBLOB then uses setBLOBVector for the value. BLOBs * are stored in a file dev.nam.elem.format. only .z compression is handled. * exit status: 0 at least some found, 1 some not found, 2 real trouble. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "indiapi.h" #include "lilxml.h" #include "base64.h" #include "zlib.h" /* table of INDI definition elements */ typedef struct { char *vec; /* vector name */ char *one; /* one element name */ } INDIDef; static INDIDef defs[] = { {"defTextVector", "defText"}, {"defNumberVector", "defNumber"}, {"defSwitchVector", "defSwitch"}, {"defLightVector", "defLight"}, {"defBLOBVector", "defBLOB"}, {"setBLOBVector", "oneBLOB"}, }; #define NDEFS (sizeof(defs)/sizeof(defs[0])) /* table of keyword to use in query vs name of INDI defXXX attribute */ typedef struct { char *keyword; char *indiattr; } INDIkwattr; static INDIkwattr kwattr[] = { {"_LABEL", "label"}, {"_GROUP", "group"}, {"_STATE", "state"}, {"_PERM", "perm"}, {"_TO", "timeout"}, {"_TS", "timestamp"}, }; #define NKWA (sizeof(kwattr)/sizeof(kwattr[0])) typedef struct { char *d; /* device to seek */ char *p; /* property to seek */ char *e; /* element to seek */ int wc : 1; /* whether pattern uses wild cards */ int ok : 1; /* something matched this query */ } SearchDef; static SearchDef *srchs; /* properties to look for */ static int nsrchs; static void usage (void); static void crackDPE (char *spec); static void addSearchDef (char *dev, char *prop, char *ele); static void openINDIServer(void); static void getprops(void); static void listenINDI(void); static int finished (void); static void onAlarm (int dummy); static int readServerChar(void); static void findDPE (XMLEle *root); static void findEle (XMLEle *root, char *dev, char *nam, char *defone, SearchDef *sp); static void enableBLOBs(char *dev, char *nam); static void oneBLOB (XMLEle *root, char *dev, char *nam, char *enam, char *p, int plen); static char *me; /* our name for usage() message */ static char host_def[] = "localhost"; /* default host name */ static char *host = host_def; /* working host name */ #define INDIPORT 7624 /* default port */ static int port = INDIPORT; /* working port number */ #define TIMEOUT 2 /* default timeout, secs */ static int timeout = TIMEOUT; /* working timeout, secs */ static int verbose; /* report extra info */ static LilXML *lillp; /* XML parser context */ #define WILDCARD '*' /* show all in this category */ static int onematch; /* only one possible match */ static int justvalue; /* if just one match show only value */ static int directfd = -1; /* direct filedes to server, if >= 0 */ static FILE *svrwfp; /* FILE * to talk to server */ static FILE *svrrfp; /* FILE * to read from server */ int main (int ac, char *av[]) { /* save our name */ me = av[0]; /* crack args */ while (--ac && **++av == '-') { char *s = *av; while (*++s) { switch (*s) { case '1': /* just value */ justvalue++; break; case 'd': if (ac < 2) { fprintf (stderr, "-d requires open fileno\n"); usage(); } directfd = atoi(*++av); ac--; break; case 'h': if (directfd >= 0) { fprintf (stderr, "Can not combine -d and -h\n"); usage(); } if (ac < 2) { fprintf (stderr, "-h requires host name\n"); usage(); } host = *++av; ac--; break; case 'p': if (directfd >= 0) { fprintf (stderr, "Can not combine -d and -p\n"); usage(); } if (ac < 2) { fprintf (stderr, "-p requires tcp port number\n"); usage(); } port = atoi(*++av); ac--; break; case 't': if (ac < 2) { fprintf (stderr, "-t requires timeout\n"); usage(); } timeout = atoi(*++av); ac--; break; case 'v': /* verbose */ verbose++; break; default: fprintf (stderr, "Unknown flag: %c\n", *s); usage(); } } } /* now ac args starting with av[0] */ if (ac == 0) av[ac++] = "*.*.*"; /* default is get everything */ /* crack each d.p.e */ while (ac--) crackDPE (*av++); onematch = nsrchs == 1 && !srchs[0].wc; /* open connection */ if (directfd >= 0) { svrwfp = fdopen (directfd, "w"); svrrfp = fdopen (directfd, "r"); if (!svrwfp || !svrrfp) { fprintf (stderr, "Direct fd %d: %s\n",directfd,strerror(errno)); exit(1); } if (verbose) fprintf (stderr, "Using direct fd %d\n", directfd); } else { openINDIServer(); if (verbose) fprintf (stderr, "Connected to %s on port %d\n", host, port); } /* build a parser context for cracking XML responses */ lillp = newLilXML(); /* issue getProperties */ getprops(); /* listen for responses, looking for d.p.e or timeout */ listenINDI(); return (0); } static void usage() { int i; fprintf(stderr, "Purpose: retrieve readable properties from an INDI server\n"); fprintf(stderr, "%s\n", "$Revision: 1.23 $"); fprintf(stderr, "Usage: %s [options] [device.property.element ...]\n",me); fprintf(stderr, " Any component may be \"*\" to match all (beware shell metacharacters).\n"); fprintf(stderr, " Reports all properties if none specified.\n"); fprintf(stderr, " BLOBs are saved in file named device.property.element.format\n"); fprintf(stderr, " In perl try: %s\n", "%props = split (/[=\\n]/, `getINDI`);"); fprintf(stderr, " Set element to one of following to return property attribute:\n"); for (i = 0; i < NKWA; i++) fprintf (stderr, " %10s to report %s\n", kwattr[i].keyword, kwattr[i].indiattr); fprintf(stderr, "Output format: output is fully qualified name=value one per line\n"); fprintf(stderr, " or just value if -1 and exactly one query without wildcards.\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " -1 : print just value if expecting exactly one response\n"); fprintf(stderr, " -d f : use file descriptor f already open to server\n"); fprintf(stderr, " -h h : alternate host, default is %s\n", host_def); fprintf(stderr, " -p p : alternate port, default is %d\n", INDIPORT); fprintf(stderr, " -t t : max time to wait, default is %d secs\n",TIMEOUT); fprintf(stderr, " -v : verbose (cumulative)\n"); fprintf(stderr, "Exit status:\n"); fprintf(stderr, " 0: found at least one match for each query\n"); fprintf(stderr, " 1: at least one query returned nothing\n"); fprintf(stderr, " 2: real trouble, try repeating with -v\n"); exit (2); } /* crack spec and add to srchs[], else exit */ static void crackDPE (char *spec) { char d[1024], p[1024], e[1024]; if (verbose) fprintf (stderr, "looking for %s\n", spec); if (sscanf (spec, "%[^.].%[^.].%[^.]", d, p, e) != 3) { fprintf (stderr, "Unknown format for property spec: %s\n", spec); usage(); } addSearchDef (d, p, e); } /* grow srchs[] with the new search */ static void addSearchDef (char *dev, char *prop, char *ele) { if (!srchs) srchs = (SearchDef *) malloc (1); /* realloc seed */ srchs = (SearchDef *) realloc (srchs, (nsrchs+1)*sizeof(SearchDef)); srchs[nsrchs].d = strcpy (malloc(strlen(dev)+1), dev); srchs[nsrchs].p = strcpy (malloc(strlen(prop)+1), prop); srchs[nsrchs].e = strcpy (malloc(strlen(ele)+1), ele); srchs[nsrchs].wc = *dev==WILDCARD || *prop==WILDCARD || *ele==WILDCARD; srchs[nsrchs].ok = 0; nsrchs++; } /* open a connection to the given host and port. * set svrwfp and svrrfp or die. */ static void openINDIServer (void) { struct sockaddr_in serv_addr; struct hostent *hp; int sockfd; /* lookup host address */ hp = gethostbyname (host); if (!hp) { herror ("gethostbyname"); exit (2); } /* create a socket to the INDI server */ (void) memset ((char *)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr_list[0]))->s_addr; serv_addr.sin_port = htons(port); if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { perror ("socket"); exit(2); } /* connect */ if (connect (sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0){ perror ("connect"); exit(2); } /* prepare for line-oriented i/o with client */ svrwfp = fdopen (sockfd, "w"); svrrfp = fdopen (sockfd, "r"); } /* issue getProperties to svrwfp, possibly constrained to one device */ static void getprops() { char *onedev = NULL; int i; /* find if only need one device */ for (i = 0; i < nsrchs; i++) { char *d = srchs[i].d; if (*d == WILDCARD || (onedev && strcmp(d,onedev))) { onedev = NULL; break; } else onedev = d; } if (onedev) fprintf(svrwfp, "\n", INDIV, onedev); else fprintf(svrwfp, "\n", INDIV); fflush (svrwfp); if (verbose) fprintf (stderr, "Queried properties from %s\n", onedev?onedev:"*"); } /* listen for INDI traffic on svrrfp. * print matching srchs[] and return when see all. * timeout and exit if any trouble. */ static void listenINDI () { char msg[1024]; /* arrange to call onAlarm() if not seeing any more defXXX */ signal (SIGALRM, onAlarm); alarm (timeout); /* read from server, exit if find all requested properties */ while (1) { XMLEle *root = readXMLEle (lillp, readServerChar(), msg); if (root) { /* found a complete XML element */ if (verbose > 1) prXMLEle (stderr, root, 0); findDPE (root); if (finished() == 0) exit (0); /* found all we want */ delXMLEle (root); /* not yet, delete and continue */ } else if (msg[0]) { fprintf (stderr, "Bad XML from %s/%d: %s\n", host, port, msg); exit(2); } } } /* return 0 if we are sure we have everything we are looking for, else -1 */ static int finished () { int i; for (i = 0; i < nsrchs; i++) if (srchs[i].wc || !srchs[i].ok) return (-1); return (0); } /* called after timeout seconds either because we are matching wild cards or * there is something still not found */ static void onAlarm (int dummy) { int trouble = 0; int i; for (i = 0; i < nsrchs; i++) { if (!srchs[i].ok) { trouble = 1; fprintf (stderr, "No %s.%s.%s from %s:%d\n", srchs[i].d, srchs[i].p, srchs[i].e, host, port); } } exit (trouble ? 1 : 0); } /* read one char from svrrfp */ static int readServerChar () { int c = fgetc (svrrfp); if (c == EOF) { if (ferror(svrrfp)) perror ("read"); else fprintf (stderr,"INDI server %s/%d disconnected\n", host, port); exit (2); } if (verbose > 2) fprintf (stderr, "Read %c\n", c); return (c); } /* print value if root is any srchs[] we are looking for*/ static void findDPE (XMLEle *root) { int i, j; for (i = 0; i < nsrchs; i++) { /* for each property we are looking for */ for (j = 0; j < NDEFS; j++) { /* for each possible type */ if (strcmp (tagXMLEle (root), defs[j].vec) == 0) { /* legal defXXXVector, check device */ char *dev = findXMLAttValu (root, "device"); char *idev = srchs[i].d; if (idev[0] == WILDCARD || !strcmp (dev,idev)) { /* found device, check name */ char *nam = findXMLAttValu (root, "name"); char *iprop = srchs[i].p; if (iprop[0] == WILDCARD || !strcmp (nam,iprop)) { /* found device and name, check perm */ char *perm = findXMLAttValu (root, "perm"); if (perm[0] && !strchr (perm, 'r')) { if (verbose) fprintf (stderr, "%s.%s is write-only\n", dev, nam); } else { /* check elements or attr keywords */ if (!strcmp (defs[j].vec, "defBLOBVector")) enableBLOBs (dev,nam); else findEle(root,dev,nam,defs[j].one,&srchs[i]); if (onematch) return; /* only one can match */ alarm (timeout); /* reset timeout */ } } } } } } } /* print elements in root speced in sp (known to be of type defone). * print just value if onematch and justvalue else fully qualified name. */ static void findEle (XMLEle *root, char *dev, char *nam, char *defone, SearchDef *sp) { char *iele = sp->e; XMLEle *ep; int i; /* check for attr keyword */ for (i = 0; i < NKWA; i++) { if (strcmp (iele, kwattr[i].keyword) == 0) { /* just print the property state, not the element values */ char *s = findXMLAttValu (root, kwattr[i].indiattr); sp->ok = 1; /* progress */ if (onematch && justvalue) printf ("%s\n", s); else printf ("%s.%s.%s=%s\n", dev, nam, kwattr[i].keyword, s); return; } } /* no special attr, look for specific element name */ for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) { if (!strcmp (tagXMLEle (ep), defone)) { /* legal defXXX, check deeper */ char *enam = findXMLAttValu (ep, "name"); if (iele[0]==WILDCARD || !strcmp(enam,iele)) { /* found it! */ char *p = pcdataXMLEle(ep); sp->ok = 1; /* progress */ if (!strcmp (defone, "oneBLOB")) oneBLOB (ep, dev, nam, enam, p, pcdatalenXMLEle(ep)); else if (onematch && justvalue) printf ("%s\n", p); else printf ("%s.%s.%s=%s\n", dev, nam, enam, p); if (onematch) return; /* only one can match*/ } } } } /* send server command to svrwfp that enables blobs for the given dev nam */ static void enableBLOBs(char *dev, char *nam) { if (verbose) fprintf (stderr, "sending enableBLOB %s.%s\n", dev, nam); fprintf (svrwfp,"Also\n", dev, nam); fflush (svrwfp); } /* given a oneBLOB, save */ static void oneBLOB (XMLEle *root, char *dev, char *nam, char *enam, char *p, int plen) { char *format; FILE *fp; int bloblen; char *blob; int ucs; int isz; char fn[128]; int i; /* get uncompressed size */ ucs = atoi(findXMLAttValu (root, "size")); if (verbose) fprintf (stderr, "%s.%s.%s reports uncompressed size as %d\n", dev, nam, enam, ucs); /* get format and length */ format = findXMLAttValu (root, "format"); isz = !strcmp (&format[strlen(format)-2], ".z"); /* decode blob from base64 in p */ blob = malloc (3*plen/4); bloblen = from64tobits (blob, p); if (bloblen < 0) { fprintf (stderr, "%s.%s.%s bad base64\n", dev, nam, enam); exit(2); } /* uncompress effectively in place if z */ if (isz) { uLong nuncomp = ucs; unsigned char *uncomp = malloc (ucs); int ok = uncompress (uncomp, &nuncomp, blob, bloblen); if (ok != Z_OK) { fprintf (stderr, "%s.%s.%s uncompress error %d\n", dev, nam, enam, ok); exit(2); } free (blob); blob = uncomp; bloblen = nuncomp; } /* rig up a file name from property name */ i = sprintf (fn, "%s.%s.%s%s", dev, nam, enam, format); if (isz) fn[i-2] = '\0'; /* chop off .z */ /* save */ fp = fopen (fn, "w"); if (fp) { if (verbose) fprintf (stderr, "Wrote %s\n", fn); fwrite (blob, bloblen, 1, fp); fclose (fp); } else { fprintf (stderr, "%s: %s\n", fn, strerror(errno)); } } indi-0.5/src/tools/setINDIproperty.c0000644000175000017500000002617210605175651015266 0ustar jrjr/* connect to an INDI server and set one or more device.property.element. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "indiapi.h" #include "lilxml.h" static void usage (void); static void crackSpec (char *spec); static void openINDIServer(FILE **rfpp, FILE **wfpp); static void listenINDI (FILE *rfp, FILE *wfp); static int finished (void); static void onAlarm (int dummy); static int readServerChar (FILE *fp); static void findSet (XMLEle *root, FILE *fp); /* table of INDI definition elements we can set */ typedef struct { char *defType; /* defXXXVector name */ char *defOne; /* defXXX name */ char *newType; /* newXXXVector name */ char *oneType; /* oneXXX name */ } INDIDef; static INDIDef defs[] = { {"defTextVector", "defText", "newTextVector", "oneText"}, {"defNumberVector", "defNumber", "newNumberVector", "oneNumber"}, {"defSwitchVector", "defSwitch", "newSwitchVector", "oneSwitch"}, }; #define NDEFS (sizeof(defs)/sizeof(defs[0])) #define INDIPORT 7624 /* default port */ static char host_def[] = "localhost"; /* default host name */ static char *me; /* our name for usage message */ static char *host = host_def; /* working host name */ static int port = INDIPORT; /* working port number */ static int verbose; /* report extra info */ static int directfd = -1; /* direct filedes to server, if >= 0 */ #define TIMEOUT 2 /* default timeout, secs */ static int timeout = TIMEOUT; /* working timeout, secs */ static LilXML *lillp; /* XML parser context */ typedef struct { char *e, *v; /* element name and value */ int ok; /* set when found */ } SetEV; typedef struct { char *d; /* device */ char *p; /* property */ SetEV *ev; /* elements */ int nev; /* n elements */ } SetSpec; static SetSpec *sets; /* set of properties to set */ static int nsets; static void scanEV (SetSpec *sp, char e[], char v[]); static void sendNew (FILE *fp, INDIDef *dp, SetSpec *sp); int main (int ac, char *av[]) { FILE *rfp, *wfp; /* save our name */ me = av[0]; /* crack args */ while (--ac && **++av == '-') { char *s = *av; while (*++s) { switch (*s) { case 'd': if (ac < 2) { fprintf (stderr, "-d requires open fileno\n"); usage(); } directfd = atoi(*++av); ac--; break; case 'h': if (directfd >= 0) { fprintf (stderr, "Can not combine -d and -h\n"); usage(); } if (ac < 2) { fprintf (stderr, "-h requires host name\n"); usage(); } host = *++av; ac--; break; case 'p': if (directfd >= 0) { fprintf (stderr, "Can not combine -d and -p\n"); usage(); } if (ac < 2) { fprintf (stderr, "-p requires tcp port number\n"); usage(); } port = atoi(*++av); ac--; break; case 't': if (ac < 2) { fprintf (stderr, "-t requires timeout\n"); usage(); } timeout = atoi(*++av); ac--; break; case 'v': /* verbose */ verbose++; break; default: fprintf (stderr, "Unknown flag: %c\n", *s); usage(); } } } /* now ac args starting at av[0] */ if (ac < 1) usage(); /* crack each property, add to sets[] */ while (ac--) crackSpec(*av++); /* open connection */ if (directfd >= 0) { rfp = fdopen (directfd, "r"); wfp = fdopen (directfd, "w"); if (!rfp || !wfp) { fprintf (stderr, "Direct fd %d: %s\n",directfd,strerror(errno)); exit(1); } if (verbose) fprintf (stderr, "Using direct fd %d\n", directfd); } else { openINDIServer(&rfp, &wfp); if (verbose) fprintf (stderr, "Connected to %s on port %d\n", host, port); } /* build a parser context for cracking XML responses */ lillp = newLilXML(); /* issue getProperties */ if (verbose) fprintf (stderr, "Querying for properties\n"); fprintf(wfp, "\n", INDIV); fflush (wfp); /* listen for properties, set when see any we recognize */ listenINDI(rfp, wfp); return (0); } static void usage() { fprintf(stderr, "Purpose: set one or more writable INDI properties\n"); fprintf(stderr, "%s\n", "$Revision: 1.2 $"); fprintf(stderr, "Usage: %s [options] device.property.e1[;e2...]=v1[;v2...] ...\n", me); fprintf(stderr, "Options:\n"); fprintf(stderr, " -d f : use file descriptor f already open to server\n"); fprintf(stderr, " -h h : alternate host, default is %s\n", host_def); fprintf(stderr, " -p p : alternate port, default is %d\n", INDIPORT); fprintf(stderr, " -t t : max time to wait, default is %d secs\n",TIMEOUT); fprintf(stderr, " -v : verbose (cumulative)\n"); fprintf(stderr, "Exit status:\n"); fprintf(stderr, " 0: all settings successful\n"); fprintf(stderr, " 1: at least one setting was invalid\n"); fprintf(stderr, " 2: real trouble, try repeating with -v\n"); exit (2); } /* crack property set spec, add to sets [] */ static void crackSpec (char *spec) { char d[1024], p[1024], e[2048], v[2048]; /* scan */ if (sscanf (spec, "%[^.].%[^.].%[^.=]=%s", d, p, e, v) != 4) { fprintf (stderr, "Bad format: %s\n", spec); usage(); } /* add to list */ if (!sets) sets = (SetSpec *) malloc (1); /* seed realloc */ sets = (SetSpec *) realloc (sets, (nsets+1)*sizeof(SetSpec)); sets[nsets].d = strcpy (malloc(strlen(d)+1), d); sets[nsets].p = strcpy (malloc(strlen(p)+1), p); sets[nsets].ev = (SetEV *) malloc (1); /* seed realloc */ sets[nsets].nev = 0; scanEV (&sets[nsets++], e, v); } /* open a read and write connection to host and port or die. * exit if trouble. */ static void openINDIServer (FILE **rfpp, FILE **wfpp) { struct sockaddr_in serv_addr; struct hostent *hp; int sockfd; /* lookup host address */ hp = gethostbyname (host); if (!hp) { perror ("gethostbyname"); exit (2); } /* create a socket to the INDI server */ (void) memset ((char *)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr_list[0]))->s_addr; serv_addr.sin_port = htons(port); if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { perror ("socket"); exit(2); } /* connect */ if (connect (sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0){ perror ("connect"); exit(2); } /* prepare for line-oriented i/o to client */ *rfpp = fdopen (sockfd, "r"); *wfpp = fdopen (sockfd, "w"); } /* listen for property reports, send new sets if match */ static void listenINDI (FILE *rfp, FILE *wfp) { char msg[1024]; /* arrange to call onAlarm() if not seeing any more defXXX */ signal (SIGALRM, onAlarm); alarm (timeout); /* read from server, exit if find all properties */ while (1) { XMLEle *root = readXMLEle (lillp, readServerChar(rfp), msg); if (root) { /* found a complete XML element */ if (verbose > 1) prXMLEle (stderr, root, 0); findSet (root, wfp); if (finished() == 0) { shutdown (fileno(wfp), SHUT_WR); /* insure flush */ exit (0); /* found all we want */ } delXMLEle (root); /* not yet, delete and continue */ } else if (msg[0]) { fprintf (stderr, "Bad XML from %s/%d: %s\n", host, port, msg); exit(2); } } } /* return 0 if we are sure we set everything we wanted to, else -1 */ static int finished () { int i, j; for (i = 0; i < nsets; i++) for (j = 0; j < sets[i].nev; j++) if (!sets[i].ev[j].ok) return (-1); return (0); } /* called after timeout seconds because we did not find something we trying * to set. */ static void onAlarm (int dummy) { int i, j; for (i = 0; i < nsets; i++) for (j = 0; j < sets[i].nev; j++) if (!sets[i].ev[j].ok) fprintf (stderr, "No %s.%s.%s from %s:%d\n", sets[i].d, sets[i].p, sets[i].ev[j].e, host, port); exit (1); } static int readServerChar (FILE *fp) { int c = fgetc (fp); if (c == EOF) { if (ferror(fp)) perror ("read"); else fprintf (stderr,"INDI server %s:%d disconnected\n", host, port); exit (2); } if (verbose > 2) fprintf (stderr, "Read %c\n", c); return (c); } /* issue a set command if it matches the given property */ static void findSet (XMLEle *root, FILE *fp) { char *rtype, *rdev, *rprop; XMLEle *ep; int t, s, i; /* check type */ rtype = tagXMLEle (root); for (t = 0; t < NDEFS; t++) if (strcmp (rtype, defs[t].defType) == 0) break; if (t == NDEFS) return; alarm (timeout); /* reset timeout */ /* check each set for matching device and property name, send if ok */ rdev = findXMLAttValu (root, "device"); rprop = findXMLAttValu (root, "name"); if (verbose > 1) fprintf (stderr, "Read definition for %s.%s\n", rdev, rprop); for (s = 0; s < nsets; s++) { if (!strcmp (rdev, sets[s].d) && !strcmp (rprop, sets[s].p)) { /* found device and name, check perm */ if (!strchr (findXMLAttValu (root, "perm"), 'w')) { if (verbose) fprintf (stderr, "%s.%s is read-only\n", rdev, rprop); exit (1); } /* check matching elements */ for (i = 0; i < sets[s].nev; i++) { for (ep = nextXMLEle(root,1); ep; ep = nextXMLEle(root,0)) { if (!strcmp(findXMLAttValu (ep,"name"),sets[s].ev[i].e) && !strcmp(tagXMLEle(ep), defs[t].defOne)) { sets[s].ev[i].ok = 1; break; } } if (!ep) return; /* not in this msg, maybe later */ } /* all element names found, send new values */ sendNew (fp, &defs[t], &sets[s]); } } } /* send the given set specification of the given INDI type to channel on fp */ static void sendNew (FILE *fp, INDIDef *dp, SetSpec *sp) { int i; fprintf (fp, "<%s device='%s' name='%s'>\n", dp->newType, sp->d, sp->p); for (i = 0; i < sp->nev; i++) { if (verbose) fprintf (stderr, " %s.%s.%s <- %s\n", sp->d, sp->p, sp->ev[i].e, sp->ev[i].v); fprintf (fp, " <%s name='%s'>%s\n", dp->oneType, sp->ev[i].e, sp->ev[i].v, dp->oneType); } fprintf (fp, "\n", dp->newType); fflush (fp); if (feof(fp) || ferror(fp)) { fprintf (stderr, "Send error\n"); exit(2); } } /* scan e1[;e2...] v1[;v2,...] from e[] and v[] and add to spec sp. * exit if trouble. */ static void scanEV (SetSpec *sp, char e[], char v[]) { static char sep[] = ";"; char *ep, *vp; if (verbose > 1) fprintf (stderr, "Scanning %s = %s\n", e, v); while (1) { char *e0 = strtok_r (e, sep, &ep); char *v0 = strtok_r (v, sep, &vp); if (!e0 && !v0) break; if (!e0) { fprintf (stderr, "More values than elements for %s.%s\n", sp->d, sp->p); exit(2); } if (!v0) { fprintf (stderr, "More elements than values for %s.%s\n", sp->d, sp->p); exit(2); } sp->ev = (SetEV *) realloc (sp->ev, (sp->nev+1)*sizeof(SetEV)); sp->ev[sp->nev].e = strcpy (malloc(strlen(e0)+1), e0); sp->ev[sp->nev].v = strcpy (malloc(strlen(v0)+1), v0); sp->nev++; e = NULL; v = NULL; } } /* For RCS Only -- Do Not Edit */ static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: setINDI.c,v $ $Date: 2006/09/12 19:55:51 $ $Revision: 1.2 $ $Name: $"}; indi-0.5/src/fli/0000755000175000017500000000000011017761434011456 5ustar jrjrindi-0.5/src/fli/libfli-filter-focuser.c0000644000175000017500000003354510605175655016032 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifdef WIN32 #include #else #include #include #endif #include #include #include #include #include #include "libfli-libfli.h" #include "libfli-mem.h" #include "libfli-debug.h" #include "libfli-filter-focuser.h" /* Array of filterwheel info Pos = # of filters Off = Offset of 0 filter from magnetic stop, X - y = number of steps from filter x to filter y */ static const wheeldata_t wheeldata[] = { /* POS OFF 0-1 1-2 2-3 3-4 4-5 5-6 6-7 7-8 8-9 9-A A-B B-C C-D D-E F-F F-0 */ { 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, { 1, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, { 2, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, { 3, 48, { 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, { 4, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, { 5, 0, { 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, { 6, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, { 7, 14, { 34, 34, 35, 34, 34, 35, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, { 8, 18, { 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0} }, { 9, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, {10, 0, { 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0} }, {11, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, {12, 6,{ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0} }, {13, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, {14, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, {15, 0, { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48} }, }; static long fli_stepmotor(flidev_t dev, long steps); static long fli_getsteppos(flidev_t dev, long *pos); static long fli_setfilterpos(flidev_t dev, long pos); long fli_filter_focuser_open(flidev_t dev) { #define FWSTRING "Filter Wheel (%ld position)" #define FOCSTRING "Focuser" #define MODEL_LEN (sizeof(FWSTRING) + 30) int err = 0; unsigned long ndev; long rlen, wlen; unsigned short buf[16]; flifilterdata_t *fdata = NULL; CHKDEVICE(dev); DEVICE->io_timeout = 1000; wlen = 2; rlen = 2; buf[0] = htons(0x8000); IO(dev, buf, &wlen, &rlen); if (ntohs(buf[0]) != 0x8000) { debug(FLIDEBUG_WARN, "Invalid echo, device not recognized, got %04x instead of %04x.", ntohs(buf[0]), 0x8000); err = -ENODEV; goto done; } wlen = 2; rlen = 2; buf[0] = htons(0x8001); IO(dev, buf, &wlen, &rlen); DEVICE->devinfo.fwrev = ntohs(buf[0]); if ((DEVICE->devinfo.fwrev & 0xff00) != 0x8000) { debug(FLIDEBUG_WARN, "Invalid echo, device not recognized."); err = -ENODEV; goto done; } if ((DEVICE->device_data = xmalloc(sizeof(flifilterdata_t))) == NULL) { err = -ENOMEM; goto done; } fdata = DEVICE->device_data; fdata->numslots = 0; fdata->stepspersec = 100; fdata->currentslot = -1; if (DEVICE->devinfo.fwrev == 0x8001) /* Old level of firmware */ { if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } debug(FLIDEBUG_INFO, "Device is old fashioned filter wheel."); fdata->numslots = 5; /* FIX: should model info be set first? */ return 0; } debug(FLIDEBUG_INFO, "New version of hardware found."); wlen = 2; rlen = 2; buf[0] = htons(0x8002); IO(dev, buf, &wlen, &rlen); ndev = ntohs(buf[0]); if ((ndev & 0xff00) != 0x8000) { err = -ENODEV; goto done; } if ((DEVICE->devinfo.model = (char *)xmalloc(MODEL_LEN)) == NULL) { debug(FLIDEBUG_FAIL, "Could not allocate memory for model information."); err = -ENOMEM; goto done; } ndev &= 0x00ff; /* switch based on the jumper settings on the filter/focuser dongle, determines how many slots in the filter wheel */ switch (ndev) { case 0x00: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->numslots = 5; snprintf(DEVICE->devinfo.model, MODEL_LEN, FWSTRING, fdata->numslots); break; case 0x01: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->numslots = 3; snprintf(DEVICE->devinfo.model, MODEL_LEN, FWSTRING, fdata->numslots); break; case 0x02: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->numslots = 7; snprintf(DEVICE->devinfo.model, MODEL_LEN, FWSTRING, fdata->numslots); break; case 0x03: fdata->numslots = 8; if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } snprintf(DEVICE->devinfo.model, MODEL_LEN, FWSTRING, fdata->numslots); break; case 0x04: fdata->numslots = 15; fdata->stepspersec= 16;/* // 1/.06 */ if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } snprintf(DEVICE->devinfo.model, MODEL_LEN, FWSTRING, fdata->numslots); break; case 0x05: if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } fdata->numslots = 12; fdata->stepspersec= 16; /*// 1/.06*/ snprintf(DEVICE->devinfo.model, MODEL_LEN, FWSTRING, fdata->numslots); break; case 0x06: fdata->numslots = 10; fdata->stepspersec= 16; /*// 1/.06*/ if (DEVICE->devinfo.type != FLIDEVICE_FILTERWHEEL) { err = -ENODEV; goto done; } snprintf(DEVICE->devinfo.model, MODEL_LEN, FWSTRING, fdata->numslots); break; case 0x07: if (DEVICE->devinfo.type != FLIDEVICE_FOCUSER) { err = -ENODEV; goto done; } snprintf(DEVICE->devinfo.model, MODEL_LEN, FOCSTRING); break; default: err = -ENODEV; goto done; } done: if (err) { if (DEVICE->devinfo.model != NULL) { xfree(DEVICE->devinfo.model); DEVICE->devinfo.model = NULL; } if (DEVICE->device_data != NULL) { xfree(DEVICE->device_data); DEVICE->device_data = NULL; } return err; } debug(FLIDEBUG_INFO, "Found a %ld slot filter wheel or a focuser.", fdata->numslots); #undef FWSTRING #undef FOCSTRING #undef MODEL_LEN return 0; } long fli_filter_focuser_close(flidev_t dev) { CHKDEVICE(dev); if (DEVICE->devinfo.model != NULL) { xfree(DEVICE->devinfo.model); DEVICE->devinfo.model = NULL; } if (DEVICE->device_data != NULL) { xfree(DEVICE->device_data); DEVICE->device_data = NULL; } return 0; } long fli_filter_command(flidev_t dev, int cmd, int argc, ...) { flifilterdata_t *fdata; long r; va_list ap; va_start(ap, argc); CHKDEVICE(dev); fdata = DEVICE->device_data; switch (cmd) { case FLI_SET_FILTER_POS: if (argc != 1) r = -EINVAL; else { long pos; pos = *va_arg(ap, long *); r = fli_setfilterpos(dev, pos); } break; case FLI_GET_FILTER_POS: if (argc != 1) r = -EINVAL; else { long *cslot; cslot = va_arg(ap, long *); *cslot = fdata->currentslot; r = 0; } break; case FLI_GET_FILTER_COUNT: if (argc != 1) r = -EINVAL; else { long *nslots; nslots = va_arg(ap, long *); *nslots = fdata->numslots; r = 0; } break; case FLI_STEP_MOTOR: if (argc != 1) r = -EINVAL; else { long *steps; steps = va_arg(ap, long *); r = fli_stepmotor(dev, *steps); } break; case FLI_GET_STEPPER_POS: if (argc != 1) r = -EINVAL; else { long *pos; pos = va_arg(ap, long *); r = fli_getsteppos(dev, pos); } break; default: r = -EINVAL; } va_end(ap); return r; } long fli_focuser_command(flidev_t dev, int cmd, int argc, ...) { long r; va_list ap; va_start(ap, argc); CHKDEVICE(dev); switch (cmd) { case FLI_STEP_MOTOR: if (argc != 1) r = -EINVAL; else { long *steps; steps = va_arg(ap, long *); r = fli_stepmotor(dev, *steps); } break; case FLI_GET_STEPPER_POS: if (argc != 1) r = -EINVAL; else { long *pos; pos = va_arg(ap, long *); r = fli_getsteppos(dev, pos); } break; case FLI_HOME_FOCUSER: if (argc != 0) r = -EINVAL; else r = fli_setfilterpos(dev, FLI_FILTERPOSITION_HOME); break; default: r = -EINVAL; } va_end(ap); return r; } static long fli_stepmotor(flidev_t dev, long steps) { flifilterdata_t *fdata; long dir, timeout, move, stepsleft; long rlen,wlen; unsigned short buf[16]; clock_t begin; if (steps == 0) return 0; fdata = DEVICE->device_data; dir = steps; steps = abs(steps); while (steps > 0) { if (steps > 2048) move = 2048; else move = steps; debug(FLIDEBUG_INFO, "Stepping %d steps.", move); steps -= move; timeout = (move / fdata->stepspersec) + 2; rlen = 2; wlen = 2; if (dir < 0) { buf[0] = htons((unsigned short) (0xa000 | (unsigned short) move)); IO(dev, buf, &wlen, &rlen); if ((ntohs(buf[0]) & 0xf000) != 0xa000) { debug(FLIDEBUG_WARN, "Invalid echo."); return -EIO; } } else { buf[0] = htons((unsigned short) (0x9000 | (unsigned short) move)); IO(dev, buf, &wlen, &rlen); if ((ntohs(buf[0]) & 0xf000) != 0x9000) { debug(FLIDEBUG_WARN, "Invalid echo."); return -EIO; } } begin = clock(); stepsleft = 0; while (stepsleft != 0x7000) { buf[0] = htons(0x7000); IO(dev, buf, &wlen, &rlen); stepsleft = ntohs(buf[0]); if (((clock() - begin) / CLOCKS_PER_SEC) > timeout) { debug(FLIDEBUG_WARN, "A device timeout has occurred."); return -EIO; } } } return 0; } static long fli_getsteppos(flidev_t dev, long *pos) { long poslow, poshigh; long rlen, wlen; unsigned short buf[16]; rlen = 2; wlen = 2; buf[0] = htons(0x6000); IO(dev, buf, &wlen, &rlen); poslow = ntohs(buf[0]); if ((poslow & 0xf000) != 0x6000) return -EIO; buf[0] = htons(0x6001); IO(dev, buf, &wlen, &rlen); poshigh = ntohs(buf[0]); if ((poshigh & 0xf000) != 0x6000) return -EIO; if ((poshigh & 0x0080) > 0) { *pos = ((~poslow) & 0xff) + 1; *pos += (256 * ((~poshigh) & 0xff)); *pos = -(*pos); } else { *pos = (poslow & 0xff) + 256 * (poshigh & 0xff); } return 0; } static long fli_setfilterpos(flidev_t dev, long pos) { flifilterdata_t *fdata; long rlen, wlen; unsigned short buf[16]; long move, i, steps; fdata = DEVICE->device_data; if (pos == FLI_FILTERPOSITION_HOME) fdata->currentslot = FLI_FILTERPOSITION_HOME; if (fdata->currentslot < 0) { debug(FLIDEBUG_INFO, "Home filter wheel/focuser."); /* //set the timeout*/ DEVICE->io_timeout = (DEVICE->devinfo.type == FLIDEVICE_FILTERWHEEL ? 5000 : 30000); /*//10,12,15 pos filterwheel needs a longer timeout t*/ if(fdata->numslots == 12||fdata->numslots == 10) { DEVICE->io_timeout = 120000; } if(fdata->numslots == 15) { DEVICE->io_timeout = 200000; } wlen = 2; rlen = 2; buf[0] = htons(0xf000); IO(dev, buf, &wlen, &rlen); if (ntohs(buf[0]) != 0xf000) return -EIO; DEVICE->io_timeout = 1000; debug(FLIDEBUG_INFO, "Moving %d steps to home position.", wheeldata[fdata->numslots].n_offset); COMMAND(fli_stepmotor(dev, - (wheeldata[fdata->numslots].n_offset))); fdata->currentslot = 0; } if (pos == FLI_FILTERPOSITION_HOME) return 0; if (pos >= fdata->numslots) { debug(FLIDEBUG_WARN, "Requested slot (%d) exceeds number of slots.", pos); return -EINVAL; } if (pos == fdata->currentslot) return 0; move = pos - fdata->currentslot; if (move < 0) move += fdata->numslots; steps = 0; for (i=0; i < move; i++) steps += wheeldata[fdata->numslots].n_steps[i % fdata->numslots]; debug(FLIDEBUG_INFO, "Move filter wheel %d steps.", steps); COMMAND(fli_stepmotor(dev, - (steps))); fdata->currentslot = pos; return 0; } indi-0.5/src/fli/libfli-usb-sys-linux.c0000644000175000017500000001352310605175655015635 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include #include #include "libfli-libfli.h" #include "libfli-sys.h" #include "libfli-usb.h" #define USB_DIR_OUT 0 /* to device */ #define USB_DIR_IN 0x80 /* to host */ #define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int) #define USBDEVFS_BULK _IOWR('U', 2, struct usbdevfs_bulktransfer) #define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int) #define IOCTL_USB_RESET _IO('U', 20) /* Device descriptor */ typedef struct { u_int8_t bLength; u_int8_t bDescriptorType; u_int16_t bcdUSB; u_int8_t bDeviceClass; u_int8_t bDeviceSubClass; u_int8_t bDeviceProtocol; u_int8_t bMaxPacketSize0; u_int16_t idVendor; u_int16_t idProduct; u_int16_t bcdDevice; u_int8_t iManufacturer; u_int8_t iProduct; u_int8_t iSerialNumber; u_int8_t bNumConfigurations; } usb_device_descriptor __attribute__ ((packed)); struct usbdevfs_bulktransfer { unsigned int ep; unsigned int len; unsigned int timeout; /* in milliseconds */ void *data; }; long linux_usb_reset(flidev_t dev); long unix_usbverifydescriptor(flidev_t dev, fli_unixio_t *io) { usb_device_descriptor usb_desc; int r; if ((r = read(io->fd, &usb_desc, sizeof(usb_device_descriptor))) != sizeof(usb_device_descriptor)) { debug(FLIDEBUG_FAIL, "linux_usbverifydescriptor(): Could not read descriptor."); return -EIO; } else { debug(FLIDEBUG_INFO, "USB device descriptor:"); if(usb_desc.idVendor != 0x0f18) { debug(FLIDEBUG_FAIL, "linux_usbverifydescriptor(): Not a FLI device!"); return -ENODEV; } switch(DEVICE->domain) { case FLIDOMAIN_USB: if( (usb_desc.idProduct != 0x0002) && (usb_desc.idProduct != 0x0006) && (usb_desc.idProduct != 0x0007) ) { return -ENODEV; } break; default: return -EINVAL; break; } DEVICE->devinfo.fwrev = usb_desc.bcdDevice; } return 0; } static long linux_bulktransfer(flidev_t dev, int ep, void *buf, long *len) { fli_unixio_t *io; unsigned int iface = 0; struct usbdevfs_bulktransfer bulk; unsigned int tbytes = 0; long bytes; /* This section of code has been modified since the Linux kernel has (had) a 4096 byte limit (kernel page size) on the IOCTL for data transfer. We ran into a problem when the CCD camera became large and the data transfer requirements grew. */ io = DEVICE->io_data; /* Claim the interface */ if (ioctl(io->fd, USBDEVFS_CLAIMINTERFACE, &iface)) return -errno; /* #define _DEBUG */ #ifdef _DEBUG if ((ep & 0xf0) == 0) { char buffer[1024]; int i; sprintf(buffer, "OUT %6ld: ", *len); for (i = 0; i < ((*len > 16)?16:*len); i++) { sprintf(buffer + strlen(buffer), "%02x ", ((unsigned char *) buf)[i]); } debug(FLIDEBUG_INFO, buffer); } #endif /* _DEBUG */ while (tbytes < (unsigned) *len) { bulk.ep = ep; bulk.len = ((*len - tbytes) > 4096)?4096:(*len - tbytes); bulk.timeout = DEVICE->io_timeout; bulk.data = buf + tbytes; /* This ioctl return the number of bytes transfered */ if((bytes = ioctl(io->fd, USBDEVFS_BULK, &bulk)) != (long) bulk.len) break; tbytes += bytes; } #ifdef _DEBUG if ((ep & 0xf0) != 0) { char buffer[1024]; int i; sprintf(buffer, " IN %6ld: ", *len); for (i = 0; i < ((*len > 16)?16:*len); i++) { sprintf(buffer + strlen(buffer), "%02x ", ((unsigned char *) buf)[i]); } debug(FLIDEBUG_INFO, buffer); } #endif /* _DEBUG */ /* Release the interface */ /* if (ioctl(io->fd, USBDEVFS_RELEASEINTERFACE, &iface)) return -errno; */ if ((unsigned) *len != tbytes) return -errno; else return 0; } long linux_bulkwrite(flidev_t dev, void *buf, long *wlen) { return linux_bulktransfer(dev, FLI_CMD_ENDPOINT | USB_DIR_OUT, buf, wlen); } long linux_bulkread(flidev_t dev, void *buf, long *rlen) { return linux_bulktransfer(dev, FLI_CMD_ENDPOINT | USB_DIR_IN, buf, rlen); } long linux_usb_reset(flidev_t dev) { fli_unixio_t *io; io = DEVICE->io_data; return (ioctl(io->fd, IOCTL_USB_RESET, NULL)); } indi-0.5/src/fli/libfli-camera-parport.c0000644000175000017500000004405110605175655016010 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifdef WIN32 #include #else #include #include #endif #include #include #include #include "libfli-libfli.h" #include "libfli-mem.h" #include "libfli-debug.h" #include "libfli-camera.h" #include "libfli-camera-parport.h" long fli_camera_parport_open(flidev_t dev) { flicamdata_t *cam; long rlen, wlen; unsigned short buf; int id; cam = DEVICE->device_data; /* Set timeout values */ cam->readto = 1000; cam->writeto = 1000; cam->dirto = 1000; rlen = 2; wlen = 2; buf = htons(C_ADDRESS(1, EPARAM_ECHO)); IO(dev, &buf, &wlen, &rlen); if (buf != htons(C_ADDRESS(1, EPARAM_ECHO))) { debug(FLIDEBUG_FAIL, "Echo back from camera failed."); return -EIO; } rlen = 2; wlen = 2; buf = htons(C_ADDRESS(1, EPARAM_DEVICE)); IO(dev, &buf, &wlen, &rlen); DEVICE->devinfo.hwrev = ntohs(buf) & 0x00ff; rlen = 2; wlen = 2; buf = htons(C_ADDRESS(1, EPARAM_CCDID)); IO(dev, &buf, &wlen, &rlen); DEVICE->devinfo.devid = ntohs(buf) & 0x00ff; for (id = 0; knowndev[id].index != 0; id++) if (knowndev[id].index == DEVICE->devinfo.devid) break; if (knowndev[id].index == 0) return -ENODEV; cam->ccd.array_area.ul.x = knowndev[id].array_area.ul.x; cam->ccd.array_area.ul.y = knowndev[id].array_area.ul.y; cam->ccd.array_area.lr.x = knowndev[id].array_area.lr.x; cam->ccd.array_area.lr.y = knowndev[id].array_area.lr.y; cam->ccd.visible_area.ul.x = knowndev[id].visible_area.ul.x; cam->ccd.visible_area.ul.y = knowndev[id].visible_area.ul.y; cam->ccd.visible_area.lr.x = knowndev[id].visible_area.lr.x; cam->ccd.visible_area.lr.y = knowndev[id].visible_area.lr.y; cam->ccd.pixelwidth = knowndev[id].pixelwidth; cam->ccd.pixelheight = knowndev[id].pixelheight; if ((DEVICE->devinfo.model = (char *)xmalloc(strlen(knowndev[id].model) + 1)) == NULL) return -ENOMEM; strcpy(DEVICE->devinfo.model, knowndev[id].model); debug(FLIDEBUG_INFO, " Name: %s", DEVICE->devinfo.devnam); debug(FLIDEBUG_INFO, " Array: (%4d,%4d),(%4d,%4d)", cam->ccd.array_area.ul.x, cam->ccd.array_area.ul.y, cam->ccd.array_area.lr.x, cam->ccd.array_area.lr.y); debug(FLIDEBUG_INFO, " Visible: (%4d,%4d),(%4d,%4d)", cam->ccd.visible_area.ul.x, cam->ccd.visible_area.ul.y, cam->ccd.visible_area.lr.x, cam->ccd.visible_area.lr.y); rlen = 2; wlen = 2; buf = htons(C_ADDRESS(1, EPARAM_SNHIGH)); IO(dev, &buf, &wlen, &rlen); DEVICE->devinfo.serno = (ntohs(buf) & 0x00ff) << 8; rlen = 2; wlen = 2; buf = htons(C_ADDRESS(1, EPARAM_SNLOW)); IO(dev, &buf, &wlen, &rlen); DEVICE->devinfo.serno |= (ntohs(buf) & 0x00ff); rlen = 2; wlen = 2; buf = htons(C_ADDRESS(1, EPARAM_FIRM)); IO(dev, &buf, &wlen, &rlen); DEVICE->devinfo.fwrev = (ntohs(buf) & 0x00ff); /* Initialize all varaibles to something */ switch(DEVICE->devinfo.hwrev) { case 0x01: cam->tempslope = (100.0 / 201.1); cam->tempintercept = (-61.613); break; case 0x02: cam->tempslope = (70.0 / 215.75); cam->tempintercept = (-52.5681); break; default: debug(FLIDEBUG_WARN, "Could not set temperature parameters."); break; } cam->vflushbin = 4; cam->hflushbin = 4; cam->vbin = 1; cam->hbin = 1; cam->image_area.ul.x = cam->ccd.visible_area.ul.x; cam->image_area.ul.y = cam->ccd.visible_area.ul.y; cam->image_area.lr.x = cam->ccd.visible_area.lr.x; cam->image_area.lr.y = cam->ccd.visible_area.lr.y; cam->exposure = 100; cam->frametype = FLI_FRAME_TYPE_NORMAL; cam->flushes = 0; cam->bitdepth = FLI_MODE_16BIT; cam->exttrigger = 0; cam->grabrowwidth = (cam->image_area.lr.x - cam->image_area.ul.x) / cam->hbin; cam->grabrowcount = 1; cam->grabrowcounttot = cam->grabrowcount; cam->grabrowindex = 0; cam->grabrowbatchsize = 1; cam->grabrowbufferindex = cam->grabrowcount; cam->flushcountbeforefirstrow = 0; cam->flushcountafterlastrow = 0; return 0; } long fli_camera_parport_get_array_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y) { flicamdata_t *cam; cam = DEVICE->device_data; *ul_x = cam->ccd.array_area.ul.x; *ul_y = cam->ccd.array_area.ul.y; *lr_x = cam->ccd.array_area.lr.x; *lr_y = cam->ccd.array_area.lr.y; return 0; } long fli_camera_parport_get_visible_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y) { flicamdata_t *cam; cam = DEVICE->device_data; *ul_x = cam->ccd.visible_area.ul.x; *ul_y = cam->ccd.visible_area.ul.y; *lr_x = cam->ccd.visible_area.lr.x; *lr_y = cam->ccd.visible_area.lr.y; return 0; } long fli_camera_parport_set_exposure_time(flidev_t dev, long exptime) { flicamdata_t *cam; cam = DEVICE->device_data; if (exptime < 0) return -EINVAL; cam->exposure = exptime; if (exptime <= 15000) /* Less than thirty seconds..., 8.192e-3 sec */ { cam->expdur = 1; cam->expmul = (long) (((double) exptime) / 8.192); } else if (exptime <= 2000000) /* Less than one hour */ { cam->expdur = (long) (1.0 / 8.192e-3); cam->expmul = (long) (exptime / 1000); } else { cam->expdur = (long) (10.0 / 8.192e-3); cam->expmul = (long) (exptime / 10000); } return 0; } long fli_camera_parport_set_image_area(flidev_t dev, long ul_x, long ul_y, long lr_x, long lr_y) { flicamdata_t *cam; cam = DEVICE->device_data; if ((ul_x < cam->ccd.visible_area.ul.x) || (ul_y < cam->ccd.visible_area.ul.y) || (lr_x > cam->ccd.visible_area.lr.x) || (lr_y > cam->ccd.visible_area.lr.y)) return -EINVAL; cam->image_area.ul.x = ul_x; cam->image_area.ul.y = ul_y; cam->image_area.lr.x = lr_x; cam->image_area.lr.y = lr_y; return 0; } long fli_camera_parport_set_hbin(flidev_t dev, long hbin) { flicamdata_t *cam; cam = DEVICE->device_data; if ((hbin < 1) || (hbin > 16)) return -EINVAL; cam->hbin = hbin; return 0; } long fli_camera_parport_set_vbin(flidev_t dev, long vbin) { flicamdata_t *cam; cam = DEVICE->device_data; if ((vbin < 1) || (vbin > 16)) return -EINVAL; cam->vbin = vbin; return 0; } long fli_camera_parport_get_exposure_status(flidev_t dev, long *timeleft) { flicamdata_t *cam; long rlen, wlen; unsigned short buf; cam = DEVICE->device_data; rlen = 2; wlen = 2; buf = htons(C_SHUTTER(1,0)); IO(dev, &buf, &wlen, &rlen); if ((ntohs(buf) & 0xf000) != C_SHUTTER(0,0)) { debug(FLIDEBUG_FAIL, "(exposurestatus) echo back from camera failed."); return -EIO; } *timeleft = (long)((double)(ntohs(buf) & 0x07ff) * ((double)cam->expdur * 8.192)); return 0; } long fli_camera_parport_set_temperature(flidev_t dev, double temperature) { flicamdata_t *cam; long rlen, wlen; unsigned short buf; cam = DEVICE->device_data; rlen = 2; wlen = 2; buf = (unsigned short)((temperature - cam->tempintercept) / cam->tempslope); buf = htons((unsigned short) C_TEMP(buf)); IO(dev, &buf, &wlen, &rlen); if ((ntohs(buf) & 0xf000) != C_TEMP(0)) { debug(FLIDEBUG_FAIL, "(settemperature) echo back from camera failed."); return -EIO; } return 0; } long fli_camera_parport_get_temperature(flidev_t dev, double *temperature) { flicamdata_t *cam; long rlen, wlen; unsigned short buf; cam = DEVICE->device_data; rlen = 2; wlen = 2; buf = htons(C_TEMP(0x0800)); IO(dev, &buf, &wlen, &rlen); if ((ntohs(buf) & 0xf000) != C_TEMP(0)) { debug(FLIDEBUG_FAIL, "(settemperature) echo back from camera failed."); return -EIO; } *temperature = cam->tempslope * (double)(ntohs(buf) & 0x00ff) + cam->tempintercept; return 0; } long fli_camera_parport_grab_row(flidev_t dev, void *buff, size_t width) { flicamdata_t *cam; long r; double dTm; long rlen, wlen; unsigned short buf; cam = DEVICE->device_data; if (cam->flushcountbeforefirstrow > 0) { if ((r = fli_camera_parport_flush_rows(dev, cam->flushcountbeforefirstrow, 1))) return r; cam->flushcountbeforefirstrow = 0; } dTm = (25.0e-6) * cam->ccd.array_area.lr.x + 1e-3; dTm = dTm / 1e-6; cam->readto = (long)dTm; cam->writeto = (long)dTm; rlen = 0; wlen = 2; buf = htons((unsigned short) C_SEND(cam->grabrowwidth)); IO(dev, &buf, &wlen, &rlen); if (cam->bitdepth == FLI_MODE_8BIT) { unsigned char *cbuf; int x; if ((cbuf = xmalloc(cam->grabrowwidth)) == NULL) { debug(FLIDEBUG_FAIL, "Failed memory allocation during row grab."); return -ENOMEM; } rlen = cam->grabrowwidth; wlen = 0; r = DEVICE->fli_io(dev, cbuf, &wlen, &rlen); if (r != 0) { debug(FLIDEBUG_WARN, "Couldn't grab entire row, got %d of %d bytes.", rlen, cam->grabrowwidth); } for (x = 0; x < (int)width; x++) { ((char *)buff)[x] = (((cbuf[x]) + 128) & 0x00ff); } xfree(cbuf); } else { unsigned short *sbuf; int x; if ((sbuf = xmalloc(cam->grabrowwidth * sizeof(unsigned short))) == NULL) { debug(FLIDEBUG_FAIL, "Failed memory allocation during row grab."); return -ENOMEM; } rlen = cam->grabrowwidth * sizeof(unsigned short); wlen = 0; r = DEVICE->fli_io(dev, sbuf, &wlen, &rlen); if (r != 0) { debug(FLIDEBUG_WARN, "Couldn't grab entire row, got %d of %d bytes.", rlen, cam->grabrowwidth); } for (x = 0; x < (int)width; x++) { if (DEVICE->devinfo.hwrev == 0x01) /* IMG camera */ { ((unsigned short *)buff)[x] = ntohs(sbuf[x]) + 32768; } else { ((unsigned short *)buff)[x] = ntohs(sbuf[x]); } } xfree(sbuf); } rlen = 2; wlen = 0; IO(dev, &buf, &wlen, &rlen); if (ntohs(buf) != C_SEND(width)) { debug(FLIDEBUG_WARN, "Width: %d, requested %d.", width, cam->grabrowwidth * sizeof(unsigned short)); debug(FLIDEBUG_WARN, "Got 0x%04x instead of 0x%04x.", ntohs(buf), C_SEND(width)); debug(FLIDEBUG_WARN, "Didn't get command echo at end of row."); } if (cam->grabrowcount > 0) { cam->grabrowcount--; if (cam->grabrowcount == 0) { if ((r = fli_camera_parport_flush_rows(dev, cam->flushcountafterlastrow, 1))) return r; cam->flushcountafterlastrow = 0; cam->grabrowbatchsize = 1; } } cam->readto = 1000; cam->writeto = 1000; return 0; } long fli_camera_parport_expose_frame(flidev_t dev) { flicamdata_t *cam; long rlen, wlen; unsigned short buf; cam = DEVICE->device_data; debug(FLIDEBUG_INFO, "Setting X Row Offset."); rlen = 2; wlen = 2; buf = htons((unsigned short) D_XROWOFF(cam->image_area.ul.x)); IO(dev, &buf, &wlen, &rlen); debug(FLIDEBUG_INFO, "Setting X Row Width to %d.", cam->ccd.array_area.lr.x - cam->ccd.array_area.ul.x); buf = htons((unsigned short) D_XROWWID(cam->ccd.array_area.lr.x - cam->ccd.array_area.ul.x)); IO(dev, &buf, &wlen, &rlen); debug(FLIDEBUG_INFO, "Setting X Flush Bin."); buf = htons((unsigned short) D_XFLBIN(cam->hflushbin)); IO(dev, &buf, &wlen, &rlen); debug(FLIDEBUG_INFO, "Setting Y Flush Bin."); buf = htons((unsigned short) D_YFLBIN(cam->vflushbin)); IO(dev, &buf, &wlen, &rlen); debug(FLIDEBUG_INFO, "Setting X Bin."); buf = htons((unsigned short) D_XBIN(cam->hbin)); IO(dev, &buf, &wlen, &rlen); debug(FLIDEBUG_INFO, "Setting Y Bin."); buf = htons((unsigned short) D_YBIN(cam->vbin)); IO(dev, &buf, &wlen, &rlen); debug(FLIDEBUG_INFO, "Setting Exposure Duration."); buf = htons((unsigned short) D_EXPDUR(cam->expdur)); IO(dev, &buf, &wlen, &rlen); if (cam->bitdepth == FLI_MODE_8BIT) { debug(FLIDEBUG_INFO, "Eight Bit."); buf = htons((unsigned short)((cam->exttrigger > 0) ? C_RESTCFG(0,0,1,7) : C_RESTCFG(0,0,0,7))); } else { debug(FLIDEBUG_INFO, "Sixteen Bit."); buf = htons((unsigned short)((cam->exttrigger > 0) ? C_RESTCFG(0,0,1,15) : C_RESTCFG(0,0,0,15))); } IO(dev, &buf, &wlen, &rlen); if (cam->flushes > 0) { int r; debug(FLIDEBUG_INFO, "Flushing array."); if ((r = fli_camera_parport_flush_rows(dev, cam->ccd.array_area.lr.y - cam->ccd.array_area.ul.y, cam->flushes))) return r; } debug(FLIDEBUG_INFO, "Exposing."); buf = htons((unsigned short) C_SHUTTER((cam->frametype == FLI_FRAME_TYPE_DARK)?0:1, cam->expmul)); IO(dev, &buf, &wlen, &rlen); cam->grabrowwidth = cam->image_area.lr.x - cam->image_area.ul.x; cam->flushcountbeforefirstrow = cam->image_area.ul.y; cam->flushcountafterlastrow = (cam->ccd.array_area.lr.y - cam->ccd.array_area.ul.y) - ((cam->image_area.lr.y - cam->image_area.ul.y) * cam->vbin) - cam->image_area.ul.y; if (cam->flushcountafterlastrow < 0) cam->flushcountafterlastrow = 0; cam->grabrowcount = cam->image_area.lr.y - cam->image_area.ul.y; return 0; } long fli_camera_parport_flush_rows(flidev_t dev, long rows, long repeat) { flicamdata_t *cam; double dTm; long rlen, wlen; unsigned short buf; if (rows < 0) return -EINVAL; if (rows == 0) return 0; cam = DEVICE->device_data; dTm = ((25e-6) / (cam->hflushbin / 2)) * cam->ccd.array_area.lr.x + 1e-3; dTm = dTm * rows; dTm = dTm / 1e-6; cam->readto = (long)dTm; cam->writeto = (long)dTm; while (repeat>0) { long retval; rlen = 2; wlen = 2; buf = htons((unsigned short) C_FLUSH(rows)); retval = DEVICE->fli_io(dev, &buf, &wlen, &rlen); if (retval != 0) { cam->readto = 1000; cam->writeto = 1000; return retval; } repeat--; } return 0; } long fli_camera_parport_set_bit_depth(flidev_t dev, flibitdepth_t bitdepth) { flicamdata_t *cam; cam = DEVICE->device_data; if (DEVICE->devinfo.type != 0x01) /* IMG cameras only support this */ return -EINVAL; if ((bitdepth != FLI_MODE_8BIT) && (bitdepth != FLI_MODE_16BIT)) { debug(FLIDEBUG_FAIL, "Invalid bit depth setting."); return -EINVAL; } cam->bitdepth = bitdepth; return 0; } static void correctioportdatawrite(flidev_t dev, unsigned short *Data) { unsigned short data; data = 0; switch(DEVICE->devinfo.hwrev) { case 0x01: data |= (*Data & FLICCD_IO_P0)?0x01:0; data |= (*Data & FLICCD_IO_P1)?0x02:0; data |= (*Data & FLICCD_IO_P2)?0x04:0; data |= (*Data & FLICCD_IO_P3)?0x80:0; break; case 0x02: data |= (*Data & FLICCD_IO_P0)?0x08:0; data |= (*Data & FLICCD_IO_P1)?0x10:0; data |= (*Data & FLICCD_IO_P2)?0x20:0; data |= (*Data & FLICCD_IO_P3)?0x40:0; break; default: break; } *Data = data; return; } static void correctioportdataread(flidev_t dev, unsigned short *Data) { unsigned short data; data = 0; switch (DEVICE->devinfo.hwrev) { case 0x01: data |= (*Data & 0x01)?FLICCD_IO_P0:0; data |= (*Data & 0x02)?FLICCD_IO_P1:0; data |= (*Data & 0x04)?FLICCD_IO_P2:0; data |= (*Data & 0x80)?FLICCD_IO_P3:0; break; case 0x02: data |= (*Data & 0x08)?FLICCD_IO_P0:0; data |= (*Data & 0x10)?FLICCD_IO_P1:0; data |= (*Data & 0x20)?FLICCD_IO_P2:0; data |= (*Data & 0x40)?FLICCD_IO_P3:0; break; default: break; } *Data = data; return; } long fli_camera_parport_read_ioport(flidev_t dev, long *ioportset) { long rlen, wlen; unsigned short buf; rlen = 2; wlen = 2; buf = htons(0x7900); IO(dev, &buf, &wlen, &rlen); *ioportset = ntohs(buf) & 0x00ff; correctioportdataread(dev, (unsigned short *) ioportset); return 0; } long fli_camera_parport_write_ioport(flidev_t dev, long ioportset) { long rlen, wlen; unsigned short buf = (unsigned short) ioportset; correctioportdatawrite(dev, &buf); buf = htons((unsigned short) (0x7100 | (buf & 0x00ff))); rlen = 2; wlen = 2; IO(dev, &buf, &wlen, &rlen); return 0; } long fli_camera_parport_configure_ioport(flidev_t dev, long ioportset) { long rlen, wlen; unsigned short buf = (unsigned short) ioportset; correctioportdatawrite(dev, &buf); buf = htons((unsigned short) (0x7000 | (buf & 0x00ff))); rlen = 2; wlen = 2; IO(dev, &buf, &wlen, &rlen); return 0; } long fli_camera_parport_control_shutter(flidev_t dev, long shutter) { long rlen, wlen; unsigned short buf; rlen = 2; wlen = 2; buf = htons(D_EXPDUR(0)); IO(dev, &buf, &wlen, &rlen); switch (shutter) { case FLI_SHUTTER_CLOSE: debug(FLIDEBUG_INFO, "Closing shutter."); buf = htons(C_SHUTTER(0, 0)); IO(dev, &buf, &wlen, &rlen); break; case FLI_SHUTTER_OPEN: buf = htons(C_SHUTTER(1, 1)); IO(dev, &buf, &wlen, &rlen); break; default: return -EINVAL; } return 0; } indi-0.5/src/fli/libfli-camera.c0000644000175000017500000004014510605175655014323 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include "libfli-libfli.h" #include "libfli-debug.h" #include "libfli-mem.h" #include "libfli-camera.h" #include "libfli-camera-parport.h" #include "libfli-camera-usb.h" const fliccdinfo_t knowndev[] = { /* id model array_area visible_area */ {1, "KAF-0260C0-2", {{0, 0}, {534, 520}}, {{12, 4}, {524, 516}}, 1.0, 20.0, 20.0}, {2, "KAF-0400C0-2", {{0, 0}, {796, 520}}, {{14, 4}, {782, 516}}, 1.0, 20.0, 20.0}, {3, "KAF-1000C0-2", {{0, 0}, {1042, 1032}}, {{8, 4}, {1032, 1028}}, 1.0, 24.0, 24.0}, {4, "KAF-1300C0-2", {{0, 0}, {1304, 1028}}, {{4, 2}, {1284, 1026}}, 1.0, 20.0, 20.0}, {5, "KAF-1400C0-2", {{0, 0}, {1348, 1037}}, {{14,14}, {782, 526}}, 1.0, 20.0, 20.0}, {6, "KAF-1600C0-2", {{0, 0}, {1564, 1032}}, {{14, 4}, {1550, 1028}}, 1.0, 20.0, 20.0}, {7, "KAF-4200C0-2", {{0, 0}, {2060, 2048}}, {{25, 2}, {2057, 2046}}, 1.0, 20.0, 20.0}, {8, "SITe-502S", {{0, 0}, {527, 512}}, {{15, 0}, {527, 512}}, 1.0, 20.0, 20.0}, {9, "TK-1024", {{0, 0}, {1124, 1024}}, {{50, 0}, {1074, 1024}}, 1.0, 24.0, 24.0}, {10, "TK-512", {{0, 0}, {563, 512}}, {{51, 0}, {563, 512}}, 1.0, 24.0, 24.0}, {11, "SI-003A", {{0, 0}, {1056, 1024}}, {{16, 0}, {1040, 1024}}, 1.0, 24.0, 24.0}, {12, "KAF-6300", {{0, 0}, {3100, 2056}}, {{16, 4}, {3088, 2052}}, 1.0, 9.0, 9.0}, {13, "KAF-3200", {{0, 0}, {2267, 1510}}, {{46,34}, {2230, 1506}}, 1.0, 6.8, 6.8}, {14, "SI424A", {{0, 0}, {2088, 2049}}, {{20, 0}, {2068, 2049}}, 1.0, 6.8, 6.8}, {15, "CCD47-10", {{0, 0}, {1072, 1027}}, {{8, 0}, {1064, 1027}}, 0.0, 0.0, 0.0}, {16, "CCD77", {{0, 0}, {527, 512}}, {{15, 0}, {527, 512}}, 0.0, 0.0, 0.0}, {17, "CCD42-40", {{0, 0}, {2148, 2048}}, {{50, 0}, {2098, 2048}}, 1.0, 13.5, 13.5}, {18, "KAF-4300", {{0, 0}, {2102, 2092}}, {{8, 4}, {2092, 2088}}, 1.0, 24.0, 24.0}, {19, "KAF-16801", {{0, 0}, {4145, 4128}}, {{44,29}, {4124, 4109}}, 1.0, 9.0, 9.0}, {0, "Unknown Model", {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, 0.0, 0.0, 0.0} }; /* Common camera routines */ static long fli_camera_get_pixel_size(flidev_t dev, double *pixel_x, double *pixel_y); #define fli_camera_parport_get_pixel_size fli_camera_get_pixel_size #define fli_camera_usb_get_pixel_size fli_camera_get_pixel_size static long fli_camera_set_frame_type(flidev_t dev, fliframe_t frametype); #define fli_camera_parport_set_frame_type fli_camera_set_frame_type #define fli_camera_usb_set_frame_type fli_camera_set_frame_type static long fli_camera_set_flushes(flidev_t dev, long nflushes); #define fli_camera_parport_set_flushes fli_camera_set_flushes #define fli_camera_usb_set_flushes fli_camera_set_flushes long fli_camera_open(flidev_t dev) { int r; CHKDEVICE(dev); if ((DEVICE->device_data = xcalloc(1, sizeof(flicamdata_t))) == NULL) return -ENOMEM; switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_open(dev); break; case FLIDOMAIN_USB: r = fli_camera_usb_open(dev); break; default: r = -EINVAL; } if (r) { xfree(DEVICE->device_data); DEVICE->device_data = NULL; } return r; } long fli_camera_close(flidev_t dev) { flicamdata_t *cam; CHKDEVICE(dev); cam = DEVICE->device_data; if (cam->gbuf != NULL) { xfree(cam->gbuf); cam->gbuf = NULL; } if (DEVICE->devinfo.model != NULL) { xfree(DEVICE->devinfo.model); DEVICE->devinfo.model = NULL; } if (DEVICE->devinfo.devnam != NULL) { xfree(DEVICE->devinfo.devnam); DEVICE->devinfo.devnam = NULL; } if (DEVICE->device_data != NULL) { xfree(DEVICE->device_data); DEVICE->device_data = NULL; } return 0; } long fli_camera_command(flidev_t dev, int cmd, int argc, ...) { long r; va_list ap; va_start(ap, argc); CHKDEVICE(dev); switch (cmd) { case FLI_GET_PIXEL_SIZE: if (argc != 2) r = -EINVAL; else { double *pixel_x, *pixel_y; pixel_x = va_arg(ap, double *); pixel_y = va_arg(ap, double *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_get_pixel_size(dev, pixel_x, pixel_y); break; case FLIDOMAIN_USB: r = fli_camera_usb_get_pixel_size(dev, pixel_x, pixel_y); break; default: r = -EINVAL; } } break; case FLI_GET_ARRAY_AREA: if (argc != 4) r = -EINVAL; else { long *ul_x, *ul_y, *lr_x, *lr_y; ul_x = va_arg(ap, long *); ul_y = va_arg(ap, long *); lr_x = va_arg(ap, long *); lr_y = va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_get_array_area(dev, ul_x, ul_y, lr_x, lr_y); break; case FLIDOMAIN_USB: r = fli_camera_usb_get_array_area(dev, ul_x, ul_y, lr_x, lr_y); break; default: r = -EINVAL; } } break; case FLI_GET_VISIBLE_AREA: if (argc != 4) r = -EINVAL; else { long *ul_x, *ul_y, *lr_x, *lr_y; ul_x = va_arg(ap, long *); ul_y = va_arg(ap, long *); lr_x = va_arg(ap, long *); lr_y = va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_get_visible_area(dev, ul_x, ul_y, lr_x, lr_y); break; case FLIDOMAIN_USB: r = fli_camera_usb_get_visible_area(dev, ul_x, ul_y, lr_x, lr_y); break; default: r = -EINVAL; } } break; case FLI_SET_EXPOSURE_TIME: if (argc != 1) r = -EINVAL; else { long exptime; exptime = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_exposure_time(dev, exptime); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_exposure_time(dev, exptime); break; default: r = -EINVAL; } } break; case FLI_SET_IMAGE_AREA: if (argc != 4) r = -EINVAL; else { long ul_x, ul_y, lr_x, lr_y; ul_x = *va_arg(ap, long *); ul_y = *va_arg(ap, long *); lr_x = *va_arg(ap, long *); lr_y = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_image_area(dev, ul_x, ul_y, lr_x, lr_y); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_image_area(dev, ul_x, ul_y, lr_x, lr_y); break; default: r = -EINVAL; } } break; case FLI_SET_HBIN: if (argc != 1) r = -EINVAL; else { long hbin; hbin = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_hbin(dev, hbin); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_hbin(dev, hbin); break; default: r = -EINVAL; } } break; case FLI_SET_VBIN: if (argc != 1) r = -EINVAL; else { long vbin; vbin = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_vbin(dev, vbin); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_vbin(dev, vbin); break; default: r = -EINVAL; } } break; case FLI_SET_FRAME_TYPE: if (argc != 1) r = -EINVAL; else { long frametype; frametype = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_frame_type(dev, frametype); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_frame_type(dev, frametype); break; default: r = -EINVAL; } } break; case FLI_CANCEL_EXPOSURE: if (argc != 0) r = -EINVAL; else { flicamdata_t *cam; cam = DEVICE->device_data; cam->grabrowcount = 1; cam->grabrowcounttot = cam->grabrowcount; cam->grabrowindex = 0; cam->grabrowbatchsize = 1; cam->grabrowbufferindex = cam->grabrowcount; cam->flushcountbeforefirstrow = 0; cam->flushcountafterlastrow = 0; r = DEVICE->fli_command(dev, FLI_CONTROL_SHUTTER, (long) FLI_SHUTTER_CLOSE); } break; case FLI_GET_EXPOSURE_STATUS: if (argc != 1) r = -EINVAL; else { long *timeleft; timeleft = va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_get_exposure_status(dev, timeleft); break; case FLIDOMAIN_USB: r = fli_camera_usb_get_exposure_status(dev, timeleft); break; default: r = -EINVAL; } } break; case FLI_SET_TEMPERATURE: if (argc != 1) r = -EINVAL; else { double temperature; temperature = *va_arg(ap, double *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_temperature(dev, temperature); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_temperature(dev, temperature); break; default: r = -EINVAL; } } break; case FLI_GET_TEMPERATURE: if (argc != 1) r = -EINVAL; else { double *temperature; temperature = va_arg(ap, double *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_get_temperature(dev, temperature); break; case FLIDOMAIN_USB: r = fli_camera_usb_get_temperature(dev, temperature); break; default: r = -EINVAL; } } break; case FLI_GRAB_ROW: if (argc != 2) r = -EINVAL; else { void *buf; size_t width; buf = va_arg(ap, void *); width = *va_arg(ap, size_t *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_grab_row(dev, buf, width); break; case FLIDOMAIN_USB: r = fli_camera_usb_grab_row(dev, buf, width); break; default: r = -EINVAL; } } break; case FLI_EXPOSE_FRAME: if (argc != 0) r = -EINVAL; else { switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_expose_frame(dev); break; case FLIDOMAIN_USB: r = fli_camera_usb_expose_frame(dev); break; default: r = -EINVAL; } } break; case FLI_FLUSH_ROWS: if (argc != 2) r = -EINVAL; else { long rows, repeat; rows = *va_arg(ap, long *); repeat = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_flush_rows(dev, rows, repeat); break; case FLIDOMAIN_USB: r = fli_camera_usb_flush_rows(dev, rows, repeat); break; default: r = -EINVAL; } } break; case FLI_SET_FLUSHES: if (argc != 1) r = -EINVAL; else { long nflushes; nflushes = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_flushes(dev, nflushes); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_flushes(dev, nflushes); break; default: r = -EINVAL; } } break; case FLI_SET_BIT_DEPTH: if (argc != 1) r = -EINVAL; else { flibitdepth_t bitdepth; bitdepth = *va_arg(ap, flibitdepth_t *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_set_bit_depth(dev, bitdepth); break; case FLIDOMAIN_USB: r = fli_camera_usb_set_bit_depth(dev, bitdepth); break; default: r = -EINVAL; } } break; case FLI_READ_IOPORT: if (argc != 1) r = -EINVAL; else { long *ioportset; ioportset = va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_read_ioport(dev, ioportset); break; case FLIDOMAIN_USB: r = fli_camera_usb_read_ioport(dev, ioportset); break; default: r = -EINVAL; } } break; case FLI_WRITE_IOPORT: if (argc != 1) r = -EINVAL; else { long ioportset; ioportset = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_write_ioport(dev, ioportset); break; case FLIDOMAIN_USB: r = fli_camera_usb_write_ioport(dev, ioportset); break; default: r = -EINVAL; } } break; case FLI_CONFIGURE_IOPORT: if (argc != 1) r = -EINVAL; else { long ioportset; ioportset = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_configure_ioport(dev, ioportset); break; case FLIDOMAIN_USB: r = fli_camera_usb_configure_ioport(dev, ioportset); break; default: r = -EINVAL; } } break; case FLI_CONTROL_SHUTTER: if (argc != 1) r = -EINVAL; else { long shutter; flicamdata_t *cam; cam = DEVICE->device_data; shutter = *va_arg(ap, long *); if( (shutter == FLI_SHUTTER_EXTERNAL_TRIGGER_LOW) || (shutter == FLI_SHUTTER_EXTERNAL_TRIGGER_HIGH) ) { debug(FLIDEBUG_INFO, "External trigger.\n"); cam->exttrigger = 1; cam->exttriggerpol = (shutter == FLI_SHUTTER_EXTERNAL_TRIGGER_LOW)?0:1; r = 0; } else { cam->exttrigger = 0; switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = fli_camera_parport_control_shutter(dev, shutter); break; case FLIDOMAIN_USB: r = fli_camera_usb_control_shutter(dev, shutter); break; default: r = -EINVAL; } } } break; case FLI_CONTROL_BGFLUSH: if (argc != 1) r = -EINVAL; else { long bgflush; flicamdata_t *cam; cam = DEVICE->device_data; bgflush = *va_arg(ap, long *); switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: r = -EFAULT; break; case FLIDOMAIN_USB: r = fli_camera_usb_control_bgflush(dev, bgflush); break; default: r = -EINVAL; } } break; default: r = -EINVAL; } va_end(ap); return r; } static long fli_camera_get_pixel_size(flidev_t dev, double *pixel_x, double *pixel_y) { flicamdata_t *cam; cam = DEVICE->device_data; *pixel_x = (double)cam->ccd.pixelwidth; *pixel_y = (double)cam->ccd.pixelheight; return 0; } static long fli_camera_set_frame_type(flidev_t dev, fliframe_t frametype) { flicamdata_t *cam; cam = DEVICE->device_data; if ((frametype < FLI_FRAME_TYPE_NORMAL) || (frametype > FLI_FRAME_TYPE_DARK)) return -EINVAL; cam->frametype = frametype; return 0; } static long fli_camera_set_flushes(flidev_t dev, long nflushes) { flicamdata_t *cam; cam = DEVICE->device_data; if((nflushes < 0) || (nflushes > 5)) return -EINVAL; cam->flushes = nflushes; return 0; } indi-0.5/src/fli/libfli-usb-sys-bsd.c0000644000175000017500000000671510605175655015253 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include #include #include "libfli-libfli.h" #include "libfli-sys.h" #include "libfli-usb.h" long unix_usbverifydescriptor(flidev_t dev, fli_unixio_t *io) { usb_device_descriptor_t usb_desc; int r; if ((r = read(io->fd, &usb_desc, sizeof(usb_device_descriptor_t))) != sizeof(usb_device_descriptor_t)) { debug(FLIDEBUG_FAIL, "linux_usbverifydescriptor(): Could not read descriptor."); return -EIO; } else { debug(FLIDEBUG_INFO, "USB device descriptor:"); if(usb_desc.idVendor != 0x0f18) { debug(FLIDEBUG_FAIL, "linux_usbverifydescriptor(): Not a FLI device!"); return -ENODEV; } switch(DEVICE->domain) { case FLIDOMAIN_USB: if(usb_desc.idProduct != 0x0002) { return -ENODEV; } break; default: return -EINVAL; break; } DEVICE->devinfo.fwrev = usb_desc.bcdDevice; } return 0; } long bsd_bulkwrite(flidev_t dev, void *buf, long *wlen) { fli_unixio_t *io; long org_wlen = *wlen; int to; io = DEVICE->io_data; to = DEVICE->io_timeout; if (ioctl(io->fd, USB_SET_TIMEOUT, &to) == -1) return -errno; *wlen = write(io->fd, buf, *wlen); if (*wlen != org_wlen) return -errno; else return 0; } long bsd_bulkread(flidev_t dev, void *buf, long *rlen) { fli_unixio_t *io; long org_rlen = *rlen; int to; io = DEVICE->io_data; to = DEVICE->io_timeout; if (ioctl(io->fd, USB_SET_TIMEOUT, &to) == -1) return -errno; *rlen = read(io->fd, buf, *rlen); if (*rlen != org_rlen) return -errno; else return 0; } indi-0.5/src/fli/libfli-serial.h0000644000175000017500000000373110605175655014357 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_SERIAL_H_ #define _LIBFLI_SERIAL_H_ #define BAUDRATE B1200 long unix_serialio(flidev_t dev, void *buf, long *wlen, long *rlen); #endif /* _LIBFLI_SERIAL_H_ */ indi-0.5/src/fli/libfli-parport.c0000644000175000017500000000660310605175655014563 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include #include "libfli-libfli.h" #include "libfli-debug.h" #include "libfli-camera.h" #include "fli_ioctl.h" long unix_parportio_linux(flidev_t dev, void *buf, long *wlen, long *rlen) { fli_unixio_t *io; flicamdata_t *cam; int err = 0, locked = 0; long org_wlen = *wlen, org_rlen = *rlen; int wto, rto, dto; long ticks; io = DEVICE->io_data; cam = DEVICE->device_data; if ((err = unix_fli_lock(dev))) { debug(FLIDEBUG_WARN, "Lock failed"); goto done; } locked = 1; /* Convert timeout to jiffies */ #ifdef HZ ticks = HZ; #else ticks = sysconf(_SC_CLK_TCK); #endif wto = cam->writeto / 1000 * ticks; rto = cam->readto / 1000 * ticks; dto = cam->dirto / 1000 * ticks; if (ioctl(io->fd, FLI_SET_WTO, &wto)) { err = -errno; goto done; } if (ioctl(io->fd, FLI_SET_DTO, &dto)) { err = -errno; goto done; } if (ioctl(io->fd, FLI_SET_RTO, &rto)) { err = -errno; goto done; } if ((*wlen = write(io->fd, buf, *wlen)) != org_wlen) { debug(FLIDEBUG_WARN, "write failed, only %d of %d bytes written", *wlen, org_wlen); err = -errno; goto done; } if (*rlen > 0) { if ((*rlen = read(io->fd, buf, *rlen)) != org_rlen) { debug(FLIDEBUG_WARN, "read failed, only %d of %d bytes read", *rlen, org_rlen); err = -errno; goto done; } } done: if (locked) { int r; if ((r = unix_fli_unlock(dev))) debug(FLIDEBUG_WARN, "Unlock failed"); if (err == 0) err = r; } return err; } indi-0.5/src/fli/libfli-mem.h0000644000175000017500000000405310605175655013654 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_MEM_H_ #define _LIBFLI_MEM_H_ void *xmalloc(size_t size); void *xcalloc(size_t nmemb, size_t size); void xfree(void *ptr); void *xrealloc(void *ptr, size_t size); int xfree_all(void); char *xstrdup(const char *s); #endif /* _LIBFLI_MEM_H_ */ indi-0.5/src/fli/libfli-debug.h0000644000175000017500000000403310605175655014162 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_DEBUG_H_ #define _LIBFLI_DEBUG_H_ /* Debug functions */ int debugclose(void); int debugopen(char *host); void debug(int level, const char *format, ...); void setdebuglevel(char *host, int level); #endif /* _LIBFLI_DEBUG_H_ */ indi-0.5/src/fli/libfli-camera-usb.c0000644000175000017500000004773010605175655015121 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifdef WIN32 #include #else #include #include #endif #include #include #include #include #include "libfli-libfli.h" #include "libfli-debug.h" #include "libfli-mem.h" #include "libfli-camera.h" #include "libfli-camera-usb.h" double dconvert(void *buf) { unsigned char *fnum = (unsigned char *) buf; double sign, exponent, mantissa, result; sign = (double) ((fnum[3] & 0x80)?(-1):(1)); exponent = (double) ((fnum[3] & 0x7f) << 1 | ((fnum[2] & 0x80)?1:0)); mantissa = 1.0 + ((double) ((fnum[2] & 0x7f) << 16 | fnum[1] << 8 | fnum[0]) / pow(2, 23)); result = sign * (double) pow(2, (exponent - 127.0)) * mantissa; return result; } long fli_camera_usb_open(flidev_t dev) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[32]; cam = DEVICE->device_data; if ((cam->gbuf = xmalloc(USB_READ_SIZ_MAX)) == NULL) return -ENOMEM; buf[0] = htons(FLI_USBCAM_HARDWAREREV); rlen = 2; wlen = 2; IO(dev, buf, &wlen, &rlen); DEVICE->devinfo.hwrev = ntohs(buf[0]); buf[0] = htons(FLI_USBCAM_DEVICEID); rlen = 2; wlen = 2; IO(dev, buf, &wlen, &rlen); DEVICE->devinfo.devid = ntohs(buf[0]); buf[0] = htons(FLI_USBCAM_SERIALNUM); rlen = 2; wlen = 2; IO(dev, buf, &wlen, &rlen); DEVICE->devinfo.serno = ntohs(buf[0]); debug(FLIDEBUG_INFO, "DeviceID %d", DEVICE->devinfo.devid); debug(FLIDEBUG_INFO, "SerialNum %d", DEVICE->devinfo.serno); debug(FLIDEBUG_INFO, "HWRev %d", DEVICE->devinfo.hwrev); debug(FLIDEBUG_INFO, "FWRev %d", DEVICE->devinfo.fwrev); if (DEVICE->devinfo.fwrev < 0x0201) { int id; for (id = 0; knowndev[id].index != 0; id++) if (knowndev[id].index == DEVICE->devinfo.devid) break; if (knowndev[id].index == 0) return -ENODEV; cam->ccd.pixelwidth = knowndev[id].pixelwidth; cam->ccd.pixelheight = knowndev[id].pixelheight; wlen = sizeof(unsigned short) * 7; rlen = 0; buf[0] = htons(FLI_USBCAM_DEVINIT); buf[1] = htons((unsigned short)knowndev[id].array_area.lr.x); buf[2] = htons((unsigned short)knowndev[id].array_area.lr.y); buf[3] = htons((unsigned short)(knowndev[id].visible_area.lr.x - knowndev[id].visible_area.ul.x)); buf[4] = htons((unsigned short)(knowndev[id].visible_area.lr.y - knowndev[id].visible_area.ul.y)); buf[5] = htons((unsigned short)knowndev[id].visible_area.ul.x); buf[6] = htons((unsigned short)knowndev[id].visible_area.ul.y); IO(dev, buf, &wlen, &rlen); if ((DEVICE->devinfo.model = (char *)xmalloc(strlen(knowndev[id].model) + 1)) == NULL) return -ENOMEM; strcpy(DEVICE->devinfo.model, knowndev[id].model); switch(DEVICE->devinfo.fwrev & 0xff00) { case 0x0100: cam->tempslope = (70.0 / 215.75); cam->tempintercept = (-52.5681); break; case 0x0200: cam->tempslope = (100.0 / 201.1); cam->tempintercept = (-61.613); break; default: cam->tempslope = 1e-12; cam->tempintercept = 0; } } else if (DEVICE->devinfo.fwrev >= 0x0201) /* Here, all the parameters are stored on the camera */ { rlen = 64; wlen = 2; buf[0] = htons(FLI_USBCAM_READPARAMBLOCK); IO(dev, buf, &wlen, &rlen); cam->ccd.pixelwidth = dconvert((char *) ((void *)buf) + 31); cam->ccd.pixelheight = dconvert((char*) ((void *)buf) + 35); cam->tempslope = dconvert((char *) ((void *)buf) + 23); cam->tempintercept = dconvert((char *) ((void *)buf) + 27); } rlen = 32; wlen = 2; buf[0] = htons(FLI_USBCAM_DEVICENAME); IO(dev, buf, &wlen, &rlen); if ((DEVICE->devinfo.devnam = (char *)xmalloc(rlen + 1)) == NULL) return -ENOMEM; memcpy(DEVICE->devinfo.devnam, buf, rlen); DEVICE->devinfo.devnam[rlen] = '\0'; if(DEVICE->devinfo.model == NULL) { DEVICE->devinfo.model = xstrdup(DEVICE->devinfo.devnam); } rlen = 4; wlen = 2; buf[0] = htons(FLI_USBCAM_ARRAYSIZE); IO(dev, buf, &wlen, &rlen); cam->ccd.array_area.ul.x = 0; cam->ccd.array_area.ul.y = 0; cam->ccd.array_area.lr.x = ntohs(buf[0]); cam->ccd.array_area.lr.y = ntohs(buf[1]); rlen = 4; wlen = 2; buf[0] = htons(FLI_USBCAM_IMAGEOFFSET); IO(dev, buf, &wlen, &rlen); cam->ccd.visible_area.ul.x = ntohs(buf[0]); cam->ccd.visible_area.ul.y = ntohs(buf[1]); rlen = 4; wlen = 2; buf[0] = htons(FLI_USBCAM_IMAGESIZE); IO(dev, buf, &wlen, &rlen); cam->ccd.visible_area.lr.x = cam->ccd.visible_area.ul.x + ntohs(buf[0]); cam->ccd.visible_area.lr.y = cam->ccd.visible_area.ul.y + ntohs(buf[1]); debug(FLIDEBUG_INFO, " Name: %s", DEVICE->devinfo.devnam); debug(FLIDEBUG_INFO, " Array: (%4d,%4d),(%4d,%4d)", cam->ccd.array_area.ul.x, cam->ccd.array_area.ul.y, cam->ccd.array_area.lr.x, cam->ccd.array_area.lr.y); debug(FLIDEBUG_INFO, " Visible: (%4d,%4d),(%4d,%4d)", cam->ccd.visible_area.ul.x, cam->ccd.visible_area.ul.y, cam->ccd.visible_area.lr.x, cam->ccd.visible_area.lr.y); debug(FLIDEBUG_INFO, " Pix Size: (%g, %g)", cam->ccd.pixelwidth, cam->ccd.pixelheight); debug(FLIDEBUG_INFO, " Temp.: T = AD x %g + %g", cam->tempslope, cam->tempintercept); /* Initialize all varaibles to something */ cam->vflushbin = 4; cam->hflushbin = 4; cam->vbin = 1; cam->hbin = 1; cam->image_area.ul.x = cam->ccd.visible_area.ul.x; cam->image_area.ul.y = cam->ccd.visible_area.ul.y; cam->image_area.lr.x = cam->ccd.visible_area.lr.x; cam->image_area.lr.y = cam->ccd.visible_area.lr.y; cam->exposure = 100; cam->frametype = FLI_FRAME_TYPE_NORMAL; cam->flushes = 0; cam->bitdepth = FLI_MODE_16BIT; cam->exttrigger = 0; cam->exttriggerpol = 0; cam->grabrowwidth = (cam->image_area.lr.x - cam->image_area.ul.x) / cam->hbin; cam->grabrowcount = 1; cam->grabrowcounttot = cam->grabrowcount; cam->grabrowindex = 0; cam->grabrowbatchsize = 1; cam->grabrowbufferindex = cam->grabrowcount; cam->flushcountbeforefirstrow = 0; cam->flushcountafterlastrow = 0; return 0; } long fli_camera_usb_get_array_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[8]; cam = DEVICE->device_data; rlen = 4; wlen = 2; buf[0] = htons(FLI_USBCAM_ARRAYSIZE); IO(dev, buf, &wlen, &rlen); cam->ccd.array_area.ul.x = 0; cam->ccd.array_area.ul.y = 0; cam->ccd.array_area.lr.x = ntohs(buf[0]); cam->ccd.array_area.lr.y = ntohs(buf[1]); *ul_x = cam->ccd.array_area.ul.x; *ul_y = cam->ccd.array_area.ul.y; *lr_x = cam->ccd.array_area.lr.x; *lr_y = cam->ccd.array_area.lr.y; return 0; } long fli_camera_usb_get_visible_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[8]; cam = DEVICE->device_data; rlen = 4; wlen = 2; buf[0] = htons(FLI_USBCAM_IMAGEOFFSET); IO(dev, buf, &wlen, &rlen); cam->ccd.visible_area.ul.x = ntohs(buf[0]); cam->ccd.visible_area.ul.y = ntohs(buf[1]); rlen = 4; wlen = 2; buf[0] = htons(FLI_USBCAM_IMAGESIZE); IO(dev, buf, &wlen, &rlen); cam->ccd.visible_area.lr.x = cam->ccd.visible_area.ul.x + ntohs(buf[0]); cam->ccd.visible_area.lr.y = cam->ccd.visible_area.ul.y + ntohs(buf[1]); *ul_x = cam->ccd.visible_area.ul.x; *ul_y = cam->ccd.visible_area.ul.y; *lr_x = cam->ccd.visible_area.lr.x; *lr_y = cam->ccd.visible_area.lr.y; return 0; } long fli_camera_usb_set_exposure_time(flidev_t dev, long exptime) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[8]; if (exptime < 0) return -EINVAL; cam = DEVICE->device_data; rlen = 0; wlen = 8; buf[0] = htons(FLI_USBCAM_SETEXPOSURE); ((unsigned long *)((void *) buf))[1] = htonl(exptime); IO(dev, buf, &wlen, &rlen); cam->exposure = exptime; return 0; } long fli_camera_usb_set_image_area(flidev_t dev, long ul_x, long ul_y, long lr_x, long lr_y) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[8]; cam = DEVICE->device_data; if( (DEVICE->devinfo.fwrev < 0x0300) && ((DEVICE->devinfo.hwrev & 0xff00) == 0x0100) ) { if( (lr_x > (cam->ccd.visible_area.lr.x * cam->hbin)) || (lr_y > (cam->ccd.visible_area.lr.y * cam->vbin)) ) { debug(FLIDEBUG_WARN, "FLISetVisibleArea(), area out of bounds: (%4d,%4d),(%4d,%4d)", ul_x, ul_y, lr_x, lr_y); } } if( (ul_x < cam->ccd.visible_area.ul.x) || (ul_y < cam->ccd.visible_area.ul.y) ) { debug(FLIDEBUG_FAIL, "FLISetVisibleArea(), area out of bounds: (%4d,%4d),(%4d,%4d)", ul_x, ul_y, lr_x, lr_y); return -EINVAL; } rlen = 0; wlen = 6; buf[0] = htons(FLI_USBCAM_SETFRAMEOFFSET); buf[1] = htons((unsigned short) cam->image_area.ul.x); buf[2] = htons((unsigned short) cam->image_area.ul.y); IO(dev, buf, &wlen, &rlen); cam->image_area.ul.x = ul_x; cam->image_area.ul.y = ul_y; cam->image_area.lr.x = lr_x; cam->image_area.lr.y = lr_y; cam->grabrowwidth = (cam->image_area.lr.x - cam->image_area.ul.x) / cam->hbin; return 0; } long fli_camera_usb_set_hbin(flidev_t dev, long hbin) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[8]; cam = DEVICE->device_data; if ((hbin < 1) || (hbin > 16)) return -EINVAL; rlen = 0; wlen = 6; buf[0] = htons(FLI_USBCAM_SETBINFACTORS); buf[1] = htons((unsigned short) hbin); buf[2] = htons((unsigned short) cam->vbin); IO(dev, buf, &wlen, &rlen); cam->hbin = hbin; cam->grabrowwidth = (cam->image_area.lr.x - cam->image_area.ul.x) / cam->hbin; return 0; } long fli_camera_usb_set_vbin(flidev_t dev, long vbin) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[8]; cam = DEVICE->device_data; if ((vbin < 1) || (vbin > 16)) return -EINVAL; rlen = 0; wlen = 6; buf[0] = htons(FLI_USBCAM_SETBINFACTORS); buf[1] = htons((unsigned short) cam->hbin); buf[2] = htons((unsigned short) vbin); IO(dev, buf, &wlen, &rlen); cam->vbin = vbin; return 0; } long fli_camera_usb_get_exposure_status(flidev_t dev, long *timeleft) { long rlen, wlen; unsigned short buf[8]; rlen = 4; wlen = 2; buf[0] = htons(FLI_USBCAM_EXPOSURESTATUS); IO(dev, buf, &wlen, &rlen); *timeleft = ntohl(((unsigned long *)((void *) buf))[0]); return 0; } long fli_camera_usb_set_temperature(flidev_t dev, double temperature) { flicamdata_t *cam; unsigned short ad; long rlen, wlen; unsigned short buf[8]; cam = DEVICE->device_data; if(DEVICE->devinfo.fwrev < 0x0200) { return 0; } if(cam->tempslope == 0.0) { ad = 255; } else { ad = (unsigned short) ((temperature - cam->tempintercept) / cam->tempslope); } debug(FLIDEBUG_INFO, "Temperature slope, intercept, AD val, %f %f %f %d", temperature, cam->tempslope, cam->tempintercept, ad); rlen = 0; wlen = 4; buf[0] = htons(FLI_USBCAM_TEMPERATURE); buf[1] = htons(ad); IO(dev, buf, &wlen, &rlen); return 0; } long fli_camera_usb_get_temperature(flidev_t dev, double *temperature) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[16]; cam = DEVICE->device_data; rlen = 2; wlen = 2; buf[0] = htons(FLI_USBCAM_TEMPERATURE); IO(dev, buf, &wlen, &rlen); *temperature = cam->tempslope * (double)((ntohs(buf[0]) & 0x00ff)) + cam->tempintercept; return 0; } long fli_camera_usb_grab_row(flidev_t dev, void *buff, size_t width) { flicamdata_t *cam; long x; long r; cam = DEVICE->device_data; if(width > (size_t) (cam->image_area.lr.x - cam->image_area.ul.x)) { debug(FLIDEBUG_FAIL, "FLIGrabRow(), requested row too wide."); debug(FLIDEBUG_FAIL, " Requested width: %d", width); debug(FLIDEBUG_FAIL, " FLISetImageArea() width: %d", cam->image_area.lr.x - cam->image_area.ul.x); return -EINVAL; } if (cam->flushcountbeforefirstrow > 0) { if ((r = fli_camera_usb_flush_rows(dev, cam->flushcountbeforefirstrow, 1))) return r; cam->flushcountbeforefirstrow = 0; } if (cam->grabrowbufferindex >= cam->grabrowbatchsize) { /* We don't have the row in memory */ long rlen, wlen; /* Do we have less than GrabRowBatchSize rows to grab? */ if (cam->grabrowbatchsize > (cam->grabrowcounttot - cam->grabrowindex)) { cam->grabrowbatchsize = cam->grabrowcounttot - cam->grabrowindex; } rlen = cam->grabrowwidth * 2 * cam->grabrowbatchsize; wlen = 6; cam->gbuf[0] = htons(FLI_USBCAM_SENDROW); cam->gbuf[1] = htons((unsigned short) cam->grabrowwidth); cam->gbuf[2] = htons((unsigned short) cam->grabrowbatchsize); IO(dev, cam->gbuf, &wlen, &rlen); for (x = 0; x < (cam->grabrowwidth * cam->grabrowbatchsize); x++) { if ((DEVICE->devinfo.hwrev & 0xff00) == 0x0100) { cam->gbuf[x] = ntohs(cam->gbuf[x]) + 32768; } else { cam->gbuf[x] = ntohs(cam->gbuf[x]); } } cam->grabrowbufferindex = 0; } for (x = 0; x < (long)width; x++) { ((unsigned short *)buff)[x] = cam->gbuf[x + (cam->grabrowbufferindex * cam->grabrowwidth)]; } cam->grabrowbufferindex++; cam->grabrowindex++; if (cam->grabrowcount > 0) { cam->grabrowcount--; if (cam->grabrowcount == 0) { if ((r = fli_camera_usb_flush_rows(dev, cam->flushcountafterlastrow, 1))) return r; cam->flushcountafterlastrow = 0; cam->grabrowbatchsize = 1; } } return 0; } long fli_camera_usb_expose_frame(flidev_t dev) { flicamdata_t *cam; short flags = 0; long rlen, wlen; unsigned short buf[16]; cam = DEVICE->device_data; rlen = 0; wlen = 6; buf[0] = htons(FLI_USBCAM_SETFRAMEOFFSET); buf[1] = htons((unsigned short) cam->image_area.ul.x); buf[2] = htons((unsigned short) cam->image_area.ul.y); IO(dev, buf, &wlen, &rlen); rlen = 0; wlen = 6; buf[0] = htons(FLI_USBCAM_SETBINFACTORS); buf[1] = htons((unsigned short) cam->hbin); buf[2] = htons((unsigned short) cam->vbin); IO(dev, buf, &wlen, &rlen); rlen = 0; wlen = 6; buf[0] = htons(FLI_USBCAM_SETFLUSHBINFACTORS); buf[1] = htons((unsigned short) cam->hflushbin); buf[2] = htons((unsigned short) cam->vflushbin); IO(dev, buf, &wlen, &rlen); rlen = 0; wlen = 8; buf[0] = htons(FLI_USBCAM_SETEXPOSURE); ((unsigned long *)((void *) buf))[1] = htonl(cam->exposure); IO(dev, buf, &wlen, &rlen); /* What flags do we need to send... */ /* Dark Frame */ flags |= (cam->frametype == FLI_FRAME_TYPE_DARK) ? 0x01 : 0x00; /* External trigger */ flags |= (cam->exttrigger != 0) ? 0x04 : 0x00; flags |= (cam->exttriggerpol != 0) ? 0x08 : 0x00; debug(FLIDEBUG_INFO, "Exposure flags: %04x", flags); debug(FLIDEBUG_INFO, "Flushing %d times.\n", cam->flushes); if (cam->flushes > 0) { long r; if ((r = fli_camera_usb_flush_rows(dev, cam->ccd.array_area.lr.y - cam->ccd.array_area.ul.y, cam->flushes))) return r; } rlen = 0; wlen = 4; buf[0] = htons(FLI_USBCAM_STARTEXPOSURE); buf[1] = htons((unsigned short) flags); IO(dev, buf, &wlen, &rlen); cam->grabrowcount = cam->image_area.lr.y - cam->image_area.ul.y; cam->grabrowcounttot = cam->grabrowcount; cam->grabrowwidth = cam->image_area.lr.x - cam->image_area.ul.x; cam->grabrowindex = 0; cam->grabrowbatchsize = USB_READ_SIZ_MAX / (cam->grabrowwidth * 2); /* Lets put some bounds on this... */ if (cam->grabrowbatchsize > cam->grabrowcounttot) cam->grabrowbatchsize = cam->grabrowcounttot; if (cam->grabrowbatchsize > 64) cam->grabrowbatchsize = 64; /* We need to get a whole new buffer by default */ cam->grabrowbufferindex = cam->grabrowbatchsize; cam->flushcountbeforefirstrow = cam->image_area.ul.y; cam->flushcountafterlastrow = (cam->ccd.array_area.lr.y - cam->ccd.array_area.ul.y) - ((cam->image_area.lr.y - cam->image_area.ul.y) * cam->vbin) - cam->image_area.ul.y; if (cam->flushcountbeforefirstrow < 0) cam->flushcountbeforefirstrow = 0; if (cam->flushcountafterlastrow < 0) cam->flushcountafterlastrow = 0; return 0; } long fli_camera_usb_flush_rows(flidev_t dev, long rows, long repeat) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[16]; cam = DEVICE->device_data; if (rows < 0) return -EINVAL; if (rows == 0) return 0; rlen = 0; wlen = 6; buf[0] = htons(FLI_USBCAM_SETFLUSHBINFACTORS); buf[1] = htons((unsigned short) cam->hflushbin); buf[2] = htons((unsigned short) cam->vflushbin); IO(dev, buf, &wlen, &rlen); while (repeat > 0) { rlen = 0; wlen = 4; buf[0] = htons(FLI_USBCAM_FLUSHROWS); buf[1] = htons((unsigned short) rows); IO(dev, buf, &wlen, &rlen); repeat--; } return 0; } long fli_camera_usb_set_bit_depth(flidev_t dev, flibitdepth_t bitdepth) { dev=dev; bitdepth=bitdepth; return -EINVAL; } long fli_camera_usb_read_ioport(flidev_t dev, long *ioportset) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[8]; cam = DEVICE->device_data; rlen = 1; wlen = 2; buf[0] = htons(FLI_USBCAM_READIO); IO(dev, buf, &wlen, &rlen); *ioportset = ((unsigned char *)(void *)buf)[0]; return 0; } long fli_camera_usb_write_ioport(flidev_t dev, long ioportset) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[8]; cam = DEVICE->device_data; rlen = 0; wlen = 3; buf[0] = htons(FLI_USBCAM_WRITEIO); ((unsigned char *)(void *)buf)[2] = (char)ioportset; IO(dev, buf, &wlen, &rlen); return 0; } long fli_camera_usb_configure_ioport(flidev_t dev, long ioportset) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[8]; cam = DEVICE->device_data; rlen = 0; wlen = 3; buf[0] = htons(FLI_USBCAM_WRITEDIR); ((unsigned char *)(void *)buf)[2] = (char)ioportset; IO(dev, buf, &wlen, &rlen); return 0; } long fli_camera_usb_control_shutter(flidev_t dev, long shutter) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[8]; cam = DEVICE->device_data; rlen = 0; wlen = 3; buf[0] = htons(FLI_USBCAM_SHUTTER); ((unsigned char *)(void *)buf)[2] = (char)shutter; IO(dev, buf, &wlen, &rlen); return 0; } long fli_camera_usb_control_bgflush(flidev_t dev, long bgflush) { flicamdata_t *cam; long rlen, wlen; unsigned short buf[8]; cam = DEVICE->device_data; if(DEVICE->devinfo.fwrev < 0x0300) { debug(FLIDEBUG_WARN, "Background flush commanded on early firmware."); return -EFAULT; } if( (bgflush != FLI_BGFLUSH_STOP) && (bgflush != FLI_BGFLUSH_START) ) return -EINVAL; rlen = 0; wlen = 4; buf[0] = htons(FLI_USBCAM_BGFLUSH); buf[1] = htons((unsigned short) bgflush); IO(dev, buf, &wlen, &rlen); return 0; } indi-0.5/src/fli/Makefile.am0000644000175000017500000000127710605175655013527 0ustar jrjrINCLUDES = $(all_includes) METASOURCES = AUTO if LINUX libfli_linux = libfli_linux.la endif if BSD libfli_bsd = libfli_bsd.la endif if NULL libfli_null = libfli_null.la endif noinst_LTLIBRARIES = libfli.la $(libfli_linux) $(libfli_bsd) $(libfli_null) libfli_linux_la_SOURCES = libfli-parport.c libfli-usb-sys-linux.c libfli_bsd_la_SOURCES = libfli-usb-sys-bsd.c libfli_null_la_SOURCES = libfli-usb-sys-null.c libfli_la_SOURCES = libfli.c libfli-camera.c libfli-camera-parport.c libfli-camera-usb.c libfli-filter-focuser.c libfli-mem.c libfli-serial.c libfli-sys.c libfli-usb.c libfli-debug.c AM_LDFLAGS = $(all_libraries) libfli_la_LIBADD = $(libfli_linux) $(libfli_bsd) $(libfli_null) indi-0.5/src/fli/libfli-camera-parport.h0000644000175000017500000001070310605175655016012 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_CAMERA_PARPORT_H_ #define _LIBFLI_CAMERA_PARPORT_H_ /* Define command and data word formats */ #define C_ADDRESS(addr,ext) (0x8000|(((addr)<<8)&0x0f00)|((ext)&0x00ff)) #define C_RESTCFG(gain,chnl,exttrig,res) (0x9000|(((gain)<<8)&0x0f00)|(((chnl)<<5)&0x00e0)|(((exttrig)<<4)&0x0010)|(((res)&0x000f))) #define C_SHUTTER(open,dmult) (0xa000|((dmult)&0x07ff)|(((open)<<11)&0x0800)) #define C_SEND(x) (0xb000|((x)&0x0fff)) #define C_FLUSH(x) (0xc000|((x)&0x0fff)) #define C_VSKIP(x) (0xd000|((x)&0x0fff)) #define C_HSKIP(x) (0xe000|((x)&0x0fff)) #define C_TEMP(x) (0xf000|((x)&0x0fff)) #define D_XROWOFF(x) (0x0000|((x)&0x0fff)) #define D_XROWWID(x) (0x1000|((x)&0x0fff)) #define D_XFLBIN(x) (0x2000|((x)&0x0fff)) #define D_YFLBIN(x) (0x3000|((x)&0x0fff)) #define D_XBIN(x) (0x4000|((x)&0x0fff)) #define D_YBIN(x) (0x5000|((x)&0x0fff)) #define D_EXPDUR(x) (0x6000|((x)&0x0fff)) #define D_RESERVE(x) (0x7000|((x)&0x0fff)) /* Define extended parameter fields for querying camera */ #define EPARAM_ECHO (0x00) #define EPARAM_CCDID (0x01) #define EPARAM_FIRM (0x02) #define EPARAM_SNHIGH (0x03) #define EPARAM_SNLOW (0x04) #define EPARAM_SIGGAIN (0x05) #define EPARAM_DEVICE (0x06) /* I/O Bit definitions */ #define FLICCD_IO_P0 (0x01) #define FLICCD_IO_P1 (0x02) #define FLICCD_IO_P2 (0x04) #define FLICCD_IO_P3 (0x08) long fli_camera_parport_open(flidev_t dev); long fli_camera_parport_get_array_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y); long fli_camera_parport_get_visible_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y); long fli_camera_parport_set_exposure_time(flidev_t dev, long exptime); long fli_camera_parport_set_image_area(flidev_t dev, long ul_x, long ul_y, long lr_x, long lr_y); long fli_camera_parport_set_hbin(flidev_t dev, long hbin); long fli_camera_parport_set_vbin(flidev_t dev, long vbin); long fli_camera_parport_get_exposure_status(flidev_t dev, long *timeleft); long fli_camera_parport_set_temperature(flidev_t dev, double temperature); long fli_camera_parport_get_temperature(flidev_t dev, double *temperature); long fli_camera_parport_grab_row(flidev_t dev, void *buf, size_t width); long fli_camera_parport_expose_frame(flidev_t dev); long fli_camera_parport_flush_rows(flidev_t dev, long rows, long repeat); long fli_camera_parport_set_bit_depth(flidev_t dev, flibitdepth_t bitdepth); long fli_camera_parport_read_ioport(flidev_t dev, long *ioportset); long fli_camera_parport_write_ioport(flidev_t dev, long ioportset); long fli_camera_parport_configure_ioport(flidev_t dev, long ioportset); long fli_camera_parport_control_shutter(flidev_t dev, long shutter); #endif /* _LIBFLI_CAMERA_PARPORT_H_ */ indi-0.5/src/fli/libfli-camera-usb.h0000644000175000017500000001014110605175655015110 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_CAMERA_USB_H_ #define _LIBFLI_CAMERA_USB_H_ #define FLI_USBCAM_DEVICENAME 0x01 #define FLI_USBCAM_DEVICEMFG 0x02 #define FLI_USBCAM_VERSION 0x03 #define FLI_USBCAM_DEVICEID 0x04 #define FLI_USBCAM_SERIALNUM 0x05 #define FLI_USBCAM_HARDWAREREV 0x06 #define FLI_USBCAM_DEVINIT 0x07 #define FLI_USBCAM_READPARAMBLOCK 0x08 #define FLI_USBCAM_ARRAYSIZE 0x100 #define FLI_USBCAM_IMAGEOFFSET 0x102 #define FLI_USBCAM_IMAGESIZE 0x103 #define FLI_USBCAM_TEMPERATURE 0x104 #define FLI_USBCAM_SETFRAMEOFFSET 0x105 #define FLI_USBCAM_SETBINFACTORS 0x106 #define FLI_USBCAM_SETFLUSHBINFACTORS 0x107 #define FLI_USBCAM_SETEXPOSURE 0x108 #define FLI_USBCAM_STARTEXPOSURE 0x109 #define FLI_USBCAM_ABORTEXPOSURE 0x10a #define FLI_USBCAM_EXPOSURESTATUS 0x10b #define FLI_USBCAM_FLUSHROWS 0x10c #define FLI_USBCAM_SENDROW 0x10d #define FLI_USBCAM_SHUTTER 0x10f #define FLI_USBCAM_WRITEIO 0x110 #define FLI_USBCAM_READIO 0x111 #define FLI_USBCAM_WRITEDIR 0x112 #define FLI_USBCAM_BGFLUSH 0x114 long fli_camera_usb_open(flidev_t dev); long fli_camera_usb_get_array_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y); long fli_camera_usb_get_visible_area(flidev_t dev, long *ul_x, long *ul_y, long *lr_x, long *lr_y); long fli_camera_usb_set_exposure_time(flidev_t dev, long exptime); long fli_camera_usb_set_image_area(flidev_t dev, long ul_x, long ul_y, long lr_x, long lr_y); long fli_camera_usb_set_hbin(flidev_t dev, long hbin); long fli_camera_usb_set_vbin(flidev_t dev, long vbin); long fli_camera_usb_get_exposure_status(flidev_t dev, long *timeleft); long fli_camera_usb_set_temperature(flidev_t dev, double temperature); long fli_camera_usb_get_temperature(flidev_t dev, double *temperature); long fli_camera_usb_grab_row(flidev_t dev, void *buff, size_t width); long fli_camera_usb_expose_frame(flidev_t dev); long fli_camera_usb_flush_rows(flidev_t dev, long rows, long repeat); long fli_camera_usb_set_bit_depth(flidev_t dev, flibitdepth_t bitdepth); long fli_camera_usb_read_ioport(flidev_t dev, long *ioportset); long fli_camera_usb_write_ioport(flidev_t dev, long ioportset); long fli_camera_usb_configure_ioport(flidev_t dev, long ioportset); long fli_camera_usb_control_shutter(flidev_t dev, long shutter); long fli_camera_usb_control_bgflush(flidev_t dev, long bgflush); #endif /* _LIBFLI_CAMERA_USB_H_ */ indi-0.5/src/fli/Makefile.in0000644000175000017500000004074710610536734013540 0ustar jrjr# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/fli DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) @LINUX_TRUE@am__DEPENDENCIES_1 = libfli_linux.la @BSD_TRUE@am__DEPENDENCIES_2 = libfli_bsd.la @NULL_TRUE@am__DEPENDENCIES_3 = libfli_null.la libfli_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_3) am_libfli_la_OBJECTS = libfli.lo libfli-camera.lo \ libfli-camera-parport.lo libfli-camera-usb.lo \ libfli-filter-focuser.lo libfli-mem.lo libfli-serial.lo \ libfli-sys.lo libfli-usb.lo libfli-debug.lo libfli_la_OBJECTS = $(am_libfli_la_OBJECTS) libfli_bsd_la_LIBADD = am_libfli_bsd_la_OBJECTS = libfli-usb-sys-bsd.lo libfli_bsd_la_OBJECTS = $(am_libfli_bsd_la_OBJECTS) @BSD_TRUE@am_libfli_bsd_la_rpath = libfli_linux_la_LIBADD = am_libfli_linux_la_OBJECTS = libfli-parport.lo libfli-usb-sys-linux.lo libfli_linux_la_OBJECTS = $(am_libfli_linux_la_OBJECTS) @LINUX_TRUE@am_libfli_linux_la_rpath = libfli_null_la_LIBADD = am_libfli_null_la_OBJECTS = libfli-usb-sys-null.lo libfli_null_la_OBJECTS = $(am_libfli_null_la_OBJECTS) @NULL_TRUE@am_libfli_null_la_rpath = DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libfli_la_SOURCES) $(libfli_bsd_la_SOURCES) \ $(libfli_linux_la_SOURCES) $(libfli_null_la_SOURCES) DIST_SOURCES = $(libfli_la_SOURCES) $(libfli_bsd_la_SOURCES) \ $(libfli_linux_la_SOURCES) $(libfli_null_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BSD_FALSE = @BSD_FALSE@ BSD_TRUE = @BSD_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_SUBDIR = @EXTRA_SUBDIR@ F77 = @F77@ FFLAGS = @FFLAGS@ GREP = @GREP@ HAVE_LIBSBIGUDRV_FALSE = @HAVE_LIBSBIGUDRV_FALSE@ HAVE_LIBSBIGUDRV_TRUE = @HAVE_LIBSBIGUDRV_TRUE@ HAVE_LIBUSB_FALSE = @HAVE_LIBUSB_FALSE@ HAVE_LIBUSB_TRUE = @HAVE_LIBUSB_TRUE@ HAVE_V4L2_FALSE = @HAVE_V4L2_FALSE@ HAVE_V4L2_TRUE = @HAVE_V4L2_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBCFITSIO = @LIBCFITSIO@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSBIGUDRV = @LIBSBIGUDRV@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LINUX_FALSE = @LINUX_FALSE@ LINUX_TRUE = @LINUX_TRUE@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ NULL_FALSE = @NULL_FALSE@ NULL_TRUE = @NULL_TRUE@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_F77 = @ac_ct_F77@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ INCLUDES = $(all_includes) METASOURCES = AUTO @LINUX_TRUE@libfli_linux = libfli_linux.la @BSD_TRUE@libfli_bsd = libfli_bsd.la @NULL_TRUE@libfli_null = libfli_null.la noinst_LTLIBRARIES = libfli.la $(libfli_linux) $(libfli_bsd) $(libfli_null) libfli_linux_la_SOURCES = libfli-parport.c libfli-usb-sys-linux.c libfli_bsd_la_SOURCES = libfli-usb-sys-bsd.c libfli_null_la_SOURCES = libfli-usb-sys-null.c libfli_la_SOURCES = libfli.c libfli-camera.c libfli-camera-parport.c libfli-camera-usb.c libfli-filter-focuser.c libfli-mem.c libfli-serial.c libfli-sys.c libfli-usb.c libfli-debug.c AM_LDFLAGS = $(all_libraries) libfli_la_LIBADD = $(libfli_linux) $(libfli_bsd) $(libfli_null) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/fli/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/fli/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libfli.la: $(libfli_la_OBJECTS) $(libfli_la_DEPENDENCIES) $(LINK) $(libfli_la_LDFLAGS) $(libfli_la_OBJECTS) $(libfli_la_LIBADD) $(LIBS) libfli_bsd.la: $(libfli_bsd_la_OBJECTS) $(libfli_bsd_la_DEPENDENCIES) $(LINK) $(am_libfli_bsd_la_rpath) $(libfli_bsd_la_LDFLAGS) $(libfli_bsd_la_OBJECTS) $(libfli_bsd_la_LIBADD) $(LIBS) libfli_linux.la: $(libfli_linux_la_OBJECTS) $(libfli_linux_la_DEPENDENCIES) $(LINK) $(am_libfli_linux_la_rpath) $(libfli_linux_la_LDFLAGS) $(libfli_linux_la_OBJECTS) $(libfli_linux_la_LIBADD) $(LIBS) libfli_null.la: $(libfli_null_la_OBJECTS) $(libfli_null_la_DEPENDENCIES) $(LINK) $(am_libfli_null_la_rpath) $(libfli_null_la_LDFLAGS) $(libfli_null_la_OBJECTS) $(libfli_null_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli-camera-parport.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli-camera-usb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli-camera.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli-debug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli-filter-focuser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli-mem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli-parport.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli-serial.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli-sys.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli-usb-sys-bsd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli-usb-sys-linux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli-usb-sys-null.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli-usb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfli.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-info-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: indi-0.5/src/fli/libfli-serial.c0000644000175000017500000001160010605175655014344 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include #include #include #include "libfli-libfli.h" #include "libfli-debug.h" #include "libfli-sys.h" #include "libfli-serial.h" long unix_serialio(flidev_t dev, void *buf, long *wlen, long *rlen) { int err = 0, locked = 0, gotattr = 0; long org_wlen = *wlen, org_rlen = *rlen; struct termios old_termios, new_termios; fli_unixio_t *io; io = DEVICE->io_data; if ((err = unix_fli_lock(dev))) { debug(FLIDEBUG_WARN, "Lock failed"); goto done; } locked = 1; if (tcgetattr(io->fd, &old_termios)) { err = -errno; debug(FLIDEBUG_WARN, "tcgetattr() failed: %s", strerror(errno)); goto done; } gotattr = 1; bzero(&new_termios, sizeof(struct termios)); new_termios.c_cflag = CS8 | CREAD | CLOCAL; new_termios.c_cc[VMIN] = 1; new_termios.c_cc[VTIME] = 0; /* Set the input baud rate */ if (cfsetispeed(&new_termios, BAUDRATE)) { err = -errno; debug(FLIDEBUG_WARN, "cfsetispeed() failed: %s", strerror(errno)); goto done; } /* Set the output baud rate */ if (cfsetospeed(&new_termios, BAUDRATE)) { err = -errno; debug(FLIDEBUG_WARN, "cfsetospeed() failed: %s", strerror(errno)); goto done; } if (tcsetattr(io->fd, TCSANOW, &new_termios)) { err = -errno; /* FIX: Should this be FLIDEBUG_FAIL*/ debug(FLIDEBUG_WARN, "tcsetattr() failed: %s", strerror(errno)); goto done; } if ((*wlen = write(io->fd, buf, org_wlen)) != org_wlen) { err = -errno; debug(FLIDEBUG_WARN, "write() failed, only %d of %d bytes written", *wlen, org_wlen); goto done; } if (tcdrain(io->fd)) { err = -errno; debug(FLIDEBUG_WARN, "tcdrain() failed: %s", strerror(errno)); goto done; } for (*rlen = 0; *rlen < org_rlen; ) { ssize_t r; fd_set readfds; struct timeval timeout; timeout.tv_sec = DEVICE->io_timeout / 1000; timeout.tv_usec = (DEVICE->io_timeout % 1000) * 1000; FD_ZERO(&readfds); FD_SET(io->fd, &readfds); switch (select(io->fd + 1, &readfds, NULL, NULL, &timeout)) { case -1: /* An error occurred */ err = -errno; debug(FLIDEBUG_WARN, "select() failed: %s", strerror(errno)); break; case 0: /* A timeout occurred */ err = -ETIMEDOUT; debug(FLIDEBUG_WARN, "A serial communication timeout occurred"); break; default: /* There's some data to read */ if ((r = read(io->fd, buf + *rlen, org_rlen - *rlen)) <= 0) { err = -errno; debug(FLIDEBUG_WARN, "read() failed, only %d of %d bytes read", r, org_rlen - *rlen); } else *rlen += r; break; } if (err) break; } done: if (gotattr) { if (tcsetattr(io->fd, TCSANOW, &old_termios)) { if (err == 0) err = -errno; debug(FLIDEBUG_WARN, "tcsetattr() failed, could not restore terminal settings: %s", strerror(errno)); } } if (locked) { int r; if ((r = unix_fli_unlock(dev))) debug(FLIDEBUG_WARN, "Unlock failed"); if (err == 0) err = r; } return err; } indi-0.5/src/fli/libfli-sys.c0000644000175000017500000002342210605175655013710 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include #include #include #include #include #include #include #include #include "libfli-libfli.h" #include "libfli-debug.h" #include "libfli-mem.h" #include "libfli-camera.h" #include "libfli-filter-focuser.h" #include "libfli-sys.h" #include "libfli-parport.h" #include "libfli-usb.h" #include "libfli-serial.h" #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif static long unix_fli_list_parport(flidomain_t domain, char ***names); static long unix_fli_list_usb(flidomain_t domain, char ***names); static long unix_fli_list_serial(flidomain_t domain, char ***names); #ifdef __linux__ long linux_usb_reset(flidev_t dev); #endif long unix_fli_connect(flidev_t dev, char *name, long domain) { fli_unixio_t *io; CHKDEVICE(dev); if (name == NULL) return -EINVAL; /* Lock functions should be set before any other functions used */ DEVICE->fli_lock = unix_fli_lock; DEVICE->fli_unlock = unix_fli_unlock; DEVICE->domain = domain & 0x00ff; DEVICE->devinfo.type = domain & 0xff00; debug(FLIDEBUG_INFO, "Domain: 0x%04x", DEVICE->domain); debug(FLIDEBUG_INFO, " Type: 0x%04x", DEVICE->devinfo.type); if ((io = xcalloc(1, sizeof(fli_unixio_t))) == NULL) return -ENOMEM; if ((io->fd = open(name, O_RDWR)) == -1) { xfree(io); return -errno; } switch (DEVICE->domain) { case FLIDOMAIN_PARALLEL_PORT: DEVICE->fli_io = unix_parportio; break; case FLIDOMAIN_USB: { int r; if( (r = unix_usbverifydescriptor(dev, io)) != 0) { close(io->fd); xfree(io); return r; } DEVICE->fli_io = unix_usbio; } break; case FLIDOMAIN_SERIAL: DEVICE->fli_io = unix_serialio; break; default: close(io->fd); xfree(io); return -EINVAL; } switch (DEVICE->devinfo.type) { case FLIDEVICE_CAMERA: DEVICE->fli_open = fli_camera_open; DEVICE->fli_close = fli_camera_close; DEVICE->fli_command = fli_camera_command; break; case FLIDEVICE_FOCUSER: DEVICE->fli_open = fli_focuser_open; DEVICE->fli_close = fli_focuser_close; DEVICE->fli_command = fli_focuser_command; break; case FLIDEVICE_FILTERWHEEL: DEVICE->fli_open = fli_filter_open; DEVICE->fli_close = fli_filter_close; DEVICE->fli_command = fli_filter_command; break; default: close(io->fd); xfree(io); return -EINVAL; } DEVICE->io_data = io; DEVICE->name = xstrdup(name); DEVICE->io_timeout = 60 * 1000; /* 1 min. */ return 0; } long unix_fli_disconnect(flidev_t dev) { int err = 0; fli_unixio_t *io; CHKDEVICE(dev); #ifdef __linux__ if ((DEVICE->domain & 0x00ff) == FLIDOMAIN_USB) { debug(FLIDEBUG_INFO, "Resetting device"); linux_usb_reset(dev); } #endif if ((io = DEVICE->io_data) == NULL) return -EINVAL; if (close(io->fd)) err = -errno; xfree(DEVICE->io_data); DEVICE->io_data = NULL; DEVICE->fli_lock = NULL; DEVICE->fli_unlock = NULL; DEVICE->fli_io = NULL; DEVICE->fli_open = NULL; DEVICE->fli_close = NULL; DEVICE->fli_command = NULL; return err; } #if defined(_USE_FLOCK_) long unix_fli_lock(flidev_t dev) { fli_unixio_t *io = DEVICE->io_data; if (io == NULL) return -ENODEV; if (flock(io->fd, LOCK_EX) == -1) return -errno; else return 0; } long unix_fli_unlock(flidev_t dev) { fli_unixio_t *io = DEVICE->io_data; if (io == NULL) return -ENODEV; if (flock(io->fd, LOCK_UN) == -1) return -errno; else return 0; } #else /* !defined(_USE_FLOCK_) */ #define PUBLIC_DIR "/var/spool/uucppublic" long unix_fli_lock(flidev_t dev) { int fd, err = 0, locked = 0, i; char tmpf[] = PUBLIC_DIR "/temp.XXXXXX", lockf[PATH_MAX], name[PATH_MAX]; FILE *f; unsigned int backoff = 10000; pid_t pid; if ((fd = mkstemp(tmpf)) == -1) return -errno; if ((f = fdopen(fd, "w")) == NULL) { err = -errno; goto done; } fprintf(f, "%d\n", getpid()); fclose(f); if (chmod(tmpf, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) == -1) { err = -errno; goto done; } for (i = 0; DEVICE->name[i] != '\0' && i < PATH_MAX; i++) name[i] = (DEVICE->name[i] == '/') ? '-' : DEVICE->name[i]; name[MIN(i, PATH_MAX - 1)] = '\0'; if (snprintf(lockf, PATH_MAX, PUBLIC_DIR "/libfli%s.lock", name) >= PATH_MAX) { err = -EOVERFLOW; goto done; } do { if (link(tmpf, lockf) == -1) { int r; if (errno != EEXIST) { err = -errno; goto done; } if ((f = fopen(lockf, "r")) == NULL) continue; r = fscanf(f, "%d\n", &pid); fclose(f); if (r != 1) continue; if (kill(pid, 0)) { if (errno == ESRCH) { debug(FLIDEBUG_WARN, "Removing stale lock file"); unlink(lockf); } continue; } else { usleep(backoff); if ((backoff <<= 2) == 0) { err = -ETIMEDOUT; goto done; } } } else locked = 1; } while (!locked); done: unlink(tmpf); return err; } long unix_fli_unlock(flidev_t dev) { char lockf[PATH_MAX], name[PATH_MAX]; FILE *f; pid_t pid = -1; int i; for (i = 0; DEVICE->name[i] != '\0' && i < PATH_MAX; i++) name[i] = (DEVICE->name[i] == '/') ? '-' : DEVICE->name[i]; name[MIN(i, PATH_MAX - 1)] = '\0'; if (snprintf(lockf, PATH_MAX, PUBLIC_DIR "/libfli%s.lock", name) >= PATH_MAX) return -EOVERFLOW; if ((f = fopen(lockf, "r")) == NULL) { debug(FLIDEBUG_WARN, "Trying to unlock `%s' when not locked", DEVICE->name); return -errno; } if (fscanf(f, "%d\n", &pid) != 1) debug(FLIDEBUG_WARN, "Invalid lock file for `%s'", DEVICE->name); fclose(f); if (pid != -1 && pid != getpid()) debug(FLIDEBUG_WARN, "Forcing unlock of `%s' from process %d", DEVICE->name, pid); unlink(lockf); return 0; } #undef PUBLIC_DIR #endif /* defined(_USE_FLOCK_) */ long unix_fli_list(flidomain_t domain, char ***names) { *names = NULL; switch (domain & 0x00ff) { case FLIDOMAIN_PARALLEL_PORT: return unix_fli_list_parport(domain, names); break; case FLIDOMAIN_USB: return unix_fli_list_usb(domain, names); break; case FLIDOMAIN_SERIAL: return unix_fli_list_serial(domain, names); break; default: return -EINVAL; } /* Not reached */ return -EINVAL; } static long unix_fli_list_glob(char *pattern, flidomain_t domain, char ***names) { int retval, i, found = 0; char **list; glob_t g; if ((retval = glob(pattern, 0, NULL, &g))) { #ifdef GLOB_NOMATCH if (retval != GLOB_NOMATCH) { globfree(&g); return -errno; } /* retval == GLOB_NOMATCH */ g.gl_pathc = 0; #else globfree(&g); return -errno; #endif } if ((list = xmalloc((g.gl_pathc + 1) * sizeof(char *))) == NULL) { globfree(&g); return -ENOMEM; } for (i = 0; i < (int) g.gl_pathc; i++) { flidev_t dev; if (FLIOpen(&dev, g.gl_pathv[i], domain)) continue; if ((list[found] = xmalloc(strlen(g.gl_pathv[i]) + strlen(DEVICE->devinfo.model) + 2)) == NULL) { int j; FLIClose(dev); for (j = 0; j < found; j++) xfree(list[j]); xfree(list); globfree(&g); return -ENOMEM; } sprintf(list[found], "%s;%s", g.gl_pathv[i], DEVICE->devinfo.model); FLIClose(dev); found++; } globfree(&g); /* Terminate the list */ list[found++] = NULL; list = xrealloc(list, found * sizeof(char *)); *names = list; return 0; } #ifdef __linux__ static long unix_fli_list_parport(flidomain_t domain, char ***names) { return unix_fli_list_glob(PARPORT_GLOB, domain, names); } #else static long unix_fli_list_parport(flidomain_t domain, char ***names) { return -EINVAL; } #endif static long unix_fli_list_usb(flidomain_t domain, char ***names) { return unix_fli_list_glob(USB_GLOB, domain, names); } static long unix_fli_list_serial(flidomain_t domain, char ***names) { return unix_fli_list_glob(SERIAL_GLOB, domain, names); } indi-0.5/src/fli/libfli-debug.c0000644000175000017500000000542410605175655014162 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include "libfli-libfli.h" int sysloglevel(int level) { switch (level) { case FLIDEBUG_INFO: return LOG_INFO; break; case FLIDEBUG_WARN: return LOG_WARNING; break; case FLIDEBUG_FAIL: return LOG_ERR; break; case FLIDEBUG_ALL: return LOG_EMERG | LOG_ALERT | LOG_CRIT | LOG_ERR | LOG_WARNING | LOG_NOTICE | LOG_INFO | LOG_DEBUG; break; } return 0; } int debugopen(char *host) { openlog("libfli", LOG_PID , LOG_USER); return 0; } int debugclose(void) { closelog(); return 0; } void debug(int level, const char *format, ...) { va_list ap; va_start(ap, format); vsyslog(sysloglevel(level), format, ap); va_end(ap); return; } void setdebuglevel(char *host, int level) { static int open = 0; if (level == 0) { debugclose(); open = 0; return; } if (open == 0) { debugopen(host); open = 1; } setlogmask(LOG_UPTO(sysloglevel(level))); return; } indi-0.5/src/fli/libfli.c0000644000175000017500000010714610605175655013102 0ustar jrjr/* Copyright (c) 2000, 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include "libfli-libfli.h" #include "libfli-mem.h" #include "libfli-debug.h" static long devalloc(flidev_t *dev); static long devfree(flidev_t dev); static long fli_open(flidev_t *dev, char *name, long domain); static long fli_close(flidev_t dev); static long fli_freelist(char **names); flidevdesc_t *devices[MAX_OPEN_DEVICES] = {NULL,}; const char* version = "FLI Software Development Library for " __SYSNAME__ " " __LIBFLIVER__; static long devalloc(flidev_t *dev) { int i; if (dev == NULL) return -EINVAL; for (i = 0; i < MAX_OPEN_DEVICES; i++) if (devices[i] == NULL) break; if (i == MAX_OPEN_DEVICES) return -ENODEV; if ((devices[i] = (flidevdesc_t *)xcalloc(1, sizeof(flidevdesc_t))) == NULL) return -ENOMEM; *dev = i; return 0; } static long devfree(flidev_t dev) { CHKDEVICE(dev); if (DEVICE->io_data != NULL) { debug(FLIDEBUG_WARN, "close didn't free io_data (not NULL)"); xfree(DEVICE->io_data); DEVICE->io_data = NULL; } if (DEVICE->device_data != NULL) { debug(FLIDEBUG_WARN, "close didn't free device_data (not NULL)"); xfree(DEVICE->device_data); DEVICE->device_data = NULL; } if (DEVICE->sys_data != NULL) { debug(FLIDEBUG_WARN, "close didn't free sys_data (not NULL)"); xfree(DEVICE->sys_data); DEVICE->sys_data = NULL; } if (DEVICE->name != NULL) { xfree(DEVICE->name); DEVICE->name = NULL; } xfree(DEVICE); DEVICE = NULL; return 0; } static long fli_open(flidev_t *dev, char *name, long domain) { int retval; debug(FLIDEBUG_INFO, "Entering FLIOpen()"); debug(FLIDEBUG_INFO, "Trying to open file <%s> in domain %d.", name, domain); if ((retval = devalloc(dev)) != 0) { debug(FLIDEBUG_WARN, "error devalloc() %d [%s]", retval, strerror(-retval)); return retval; } debug(FLIDEBUG_INFO, "Got device index %d", *dev); if ((retval = fli_connect(*dev, name, domain)) != 0) { debug(FLIDEBUG_WARN, "fli_connect() error %d [%s]", retval, strerror(-retval)); devfree(*dev); return retval; } if ((retval = devices[*dev]->fli_open(*dev)) != 0) { debug(FLIDEBUG_WARN, "fli_open() error %d [%s]", retval, strerror(-retval)); fli_disconnect(*dev); devfree(*dev); return retval; } return retval; } static long fli_close(flidev_t dev) { CHKDEVICE(dev); CHKFUNCTION(DEVICE->fli_close); DEVICE->fli_close(dev); fli_disconnect(dev); devfree(dev); return 0; } static long fli_freelist(char **names) { int i; if (names == NULL) return 0; for (i = 0; names[i] != NULL; i++) xfree(names[i]); xfree(names); return 0; } LIBFLIAPI FLIGrabFrame(flidev_t dev, void* buff, size_t buffsize, size_t* bytesgrabbed) { dev=dev; buff=buff; buffsize=buffsize;bytesgrabbed=bytesgrabbed; return -EFAULT; } /** Get a handle to an FLI device. This function requires the filename and domain of the requested device. Valid device filenames can be obtained using the \texttt{FLIList()} function. An application may use any number of handles associated with the same physical device. When doing so, it is important to lock the appropriate device to ensure that multiple accesses to the same device do not occur during critical operations. @param dev Pointer to where a device handle will be placed. @param name Pointer to a string where the device filename to be opened is stored. For parallel port devices that are not probed by \texttt{FLIList()} (Windows 95/98/Me), place the address of the parallel port in a string in ascii form ie: "0x378". @param domain Domain to apply to \texttt{name} for device opening. This is a bitwise ORed combination of interface method and device type. Valid interfaces include \texttt{FLIDOMAIN_PARALLEL_PORT}, \texttt{FLIDOMAIN_USB}, \texttt{FLIDOMAIN_SERIAL}, and \texttt{FLIDOMAIN_INET}. Valid device types include \texttt{FLIDEVICE_CAMERA}, \texttt{FLIDOMAIN_FILTERWHEEL}, and \texttt{FLIDOMAIN_FOCUSER}. @return Zero on success. @return Non-zero on failure. @see FLIList @see FLIClose @see flidomain_t */ LIBFLIAPI FLIOpen(flidev_t *dev, char *name, flidomain_t domain) { return fli_open(dev, name, domain); } /** Enable debugging of API operations and communications. Use this function in combination with FLIDebug to assist in diagnosing problems that may be encountered during programming. @param host Name of the file to send debugging information to. This parameter is ignored under Linux where \texttt{syslog(3)} is used to send debug messages (see \texttt{syslog.conf(5)} for how to configure syslogd). @param level Debug level. A value of \texttt{FLIDEBUG_NONE} disables debugging. Values of \texttt{FLIDEBUG_FAIL}, \texttt{FLIDEBUG_WARN}, and \texttt{FLIDEBUG_INFO} enable progressively more verbose debug messages. @return Zero on success. @return Non-zero on failure. */ LIBFLIAPI FLISetDebugLevel(char *host, flidebug_t level) { setdebuglevel(host, level); return 0; } /** Close a handle to a FLI device. @param dev The device handle to be closed. @return Zero on success. @return Non-zero on failure. @see FLIOpen */ LIBFLIAPI FLIClose(flidev_t dev) { return fli_close(dev); } /** Get the current library version. This function copies up to \texttt{len - 1} characters of the current library version string followed by a terminating \texttt{NULL} character into the buffer pointed to by \texttt{ver}. @param ver Pointer to a character buffer where the library version string is to be placed. @param len The size in bytes of the buffer pointed to by \texttt{ver}. @return Zero on success. @return Non-zero on failure. */ LIBFLIAPI FLIGetLibVersion(char* ver, size_t len) { if (len > 0 && ver == NULL) return -EINVAL; if ((size_t) snprintf(ver, len, "%s", version) >= len) return -EOVERFLOW; else return 0; } /** Get the model of a given device. This function copies up to \texttt{len - 1} characters of the model string for device \texttt{dev}, followed by a terminating \texttt{NULL} character into the buffer pointed to by \texttt{model}. @param dev Device to find model of. @param model Pointer to a character buffer where the model string is to be placed. @param len The size in bytes of buffer pointed to by \texttt{model}. @return Zero on success. @return Non-zero on failure. @see FLIGetHWRevision @see FLIGetFWRevision @see FLIGetSerialNum */ LIBFLIAPI FLIGetModel(flidev_t dev, char* model, size_t len) { if (model == NULL) return -EINVAL; CHKDEVICE(dev); if (DEVICE->devinfo.model == NULL) { model[0] = '\0'; return 0; } if ((size_t) snprintf(model, len, "%s", DEVICE->devinfo.model) >= len) return -EOVERFLOW; else return 0; } /** Find the dimensions of a pixel in the array of the given device. @param dev Device to find the pixel size of. @param pixel_x Pointer to a double which will receive the size (in microns) of a pixel in the x direction. @param pixel_y Pointer to a double which will receive the size (in microns) of a pixel in the y direction. @return Zero on success. @return Non-zero on failure. @see FLIGetArrayArea @see FLIGetVisibleArea */ LIBFLIAPI FLIGetPixelSize(flidev_t dev, double *pixel_x, double *pixel_y) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_PIXEL_SIZE, 2, pixel_x, pixel_y); } /** Get the hardware revision of a given device. @param dev Device to find the hardware revision of. @param hwrev Pointer to a long which will receive the hardware revision. @return Zero on success. @return Non-zero on failure. @see FLIGetModel @see FLIGetFWRevision @see FLIGetSerialNum */ LIBFLIAPI FLIGetHWRevision(flidev_t dev, long *hwrev) { CHKDEVICE(dev); *hwrev = DEVICE->devinfo.hwrev; return 0; } /** Get firmware revision of a given device. @param dev Device to find the firmware revision of. @param fwrev Pointer to a long which will receive the firmware revision. @return Zero on success. @return Non-zero on failure. @see FLIGetModel @see FLIGetHWRevision @see FLIGetSerialNum */ LIBFLIAPI FLIGetFWRevision(flidev_t dev, long *fwrev) { CHKDEVICE(dev); *fwrev = DEVICE->devinfo.fwrev; return 0; } /** Get the array area of the given camera. This function finds the \emph{total} area of the CCD array for camera \texttt{dev}. This area is specified in terms of a upper-left point and a lower-right point. The upper-left x-coordinate is placed in \texttt{ul_x}, the upper-left y-coordinate is placed in \texttt{ul_y}, the lower-right x-coordinate is placed in \texttt{lr_x}, and the lower-right y-coordinate is placed in \texttt{lr_y}. @param dev Camera to get the array area of. @param ul_x Pointer to where the upper-left x-coordinate is to be placed. @param ul_y Pointer to where the upper-left y-coordinate is to be placed. @param lr_x Pointer to where the lower-right x-coordinate is to be placed. @param lr_y Pointer to where the lower-right y-coordinate is to be placed. @return Zero on success. @return Non-zero on failure. @see FLIGetVisibleArea @see FLISetImageArea */ LIBFLIAPI FLIGetArrayArea(flidev_t dev, long* ul_x, long* ul_y, long* lr_x, long* lr_y) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_ARRAY_AREA, 4, ul_x, ul_y, lr_x, lr_y); } /** Get the visible area of the given camera. This function finds the \emph{visible} area of the CCD array for the camera \texttt{dev}. This area is specified in terms of a upper-left point and a lower-right point. The upper-left x-coordinate is placed in \texttt{ul_x}, the upper-left y-coordinate is placed in \texttt{ul_y}, the lower-right x-coordinate is placed in \texttt{lr_x}, the lower-right y-coordinate is placed in \texttt{lr_y}. @param dev Camera to get the visible area of. @param ul_x Pointer to where the upper-left x-coordinate is to be placed. @param ul_y Pointer to where the upper-left y-coordinate is to be placed. @param lr_x Pointer to where the lower-right x-coordinate is to be placed. @param lr_y Pointer to where the lower-right y-coordinate is to be placed. @return Zero on success. @return Non-zero on failure. @see FLIGetArrayArea @see FLISetImageArea */ LIBFLIAPI FLIGetVisibleArea(flidev_t dev, long* ul_x, long* ul_y, long* lr_x, long* lr_y) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_VISIBLE_AREA, 4, ul_x, ul_y, lr_x, lr_y); } /** Set the exposure time for a camera. This function sets the exposure time for the camera \texttt{dev} to \texttt{exptime} msec. @param dev Camera to set the exposure time of. @param exptime Exposure time in msec. @return Zero on success. @return Non-zero on failure. @see FLIExposeFrame @see FLICancelExposure @see FLIGetExposureStatus */ LIBFLIAPI FLISetExposureTime(flidev_t dev, long exptime) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_EXPOSURE_TIME, 1, &exptime); } /** Set the image area for a given camera. This function sets the image area for camera \texttt{dev} to an area specified in terms of a upper-left point and a lower-right point. The upper-left x-coordinate is \texttt{ul_x}, the upper-left y-coordinate is \texttt{ul_y}, the lower-right x-coordinate is \texttt{lr_x}, and the lower-right y-coordinate is \texttt{lr_y}. Note that the given lower-right coordinate must take into account the horizontal and vertical bin factor settings, but the upper-left coordinate is absolute. In other words, the lower-right coordinate used to set the image area is a virtual point $(lr_x', lr_y')$ determined by: \[ lr_x' = ul_x + (lr_x - ul_x) / hbin \] \[ lr_y' = ul_y + (lr_y - ul_y) / vbin \] Where $(lr_x', lr_y')$ is the coordinate to pass to the \texttt{FLISetImageArea} function, $(ul_x, ul_y)$ and $(lr_x, lr_y)$ are the absolute coordinates of the desired image area, $hbin$ is the horizontal bin factor, and $vbin$ is the vertical bin factor. @param dev Camera to set image area of. @param ul_x Upper-left x-coordinate of image area. @param ul_y Upper-left y-coordinate of image area. @param lr_x Lower-right x-coordinate of image area ($lr_x'$ from above). @param lr_y Lower-right y-coordinate of image area ($lr_y'$ from above). @return Zero on success. @return Non-zero on failure. @see FLIGetVisibleArea @see FLIGetArrayArea */ LIBFLIAPI FLISetImageArea(flidev_t dev, long ul_x, long ul_y, long lr_x, long lr_y) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_IMAGE_AREA, 4, &ul_x, &ul_y, &lr_x, &lr_y); } /** Set the horizontal bin factor for a given camera. This function sets the horizontal bin factor for the camera \texttt{dev} to \texttt{hbin}. The valid range of the \texttt{hbin} parameter is from 1 to 16. @param dev Camera to set horizontal bin factor of. @param hbin Horizontal bin factor. @return Zero on success. @return Non-zero on failure. @see FLISetVBin @see FLISetImageArea */ LIBFLIAPI FLISetHBin(flidev_t dev, long hbin) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_HBIN, 1, &hbin); } /** Set the vertical bin factor for a given camera. This function sets the vertical bin factor for the camera \texttt{dev} to \texttt{vbin}. The valid range of the \texttt{vbin} parameter is from 1 to 16. @param dev Camera to set vertical bin factor of. @param vbin Vertical bin factor. @return Zero on success. @return Non-zero on failure. @see FLISetHBin @see FLISetImageArea */ LIBFLIAPI FLISetVBin(flidev_t dev, long vbin) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_VBIN, 1, &vbin); } /** Set the frame type for a given camera. This function sets the frame type for camera \texttt{dev} to \texttt{frametype}. The \texttt{frametype} parameter is either \texttt{FLI_FRAME_TYPE_NORMAL} for a normal frame where the shutter opens or \texttt{FLI_FRAME_TYPE_DARK} for a dark frame where the shutter remains closed. @param cam Camera to set the frame type of. @param frametype Frame type: \texttt{FLI_FRAME_TYPE_NORMAL} or \texttt{FLI_FRAME_TYPE_DARK}. @return Zero on success. @return Non-zero on failure. @see fliframe_t @see FLIExposeFrame */ LIBFLIAPI FLISetFrameType(flidev_t dev, fliframe_t frametype) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_FRAME_TYPE, 1, &frametype); } /** Cancel an exposure for a given camera. This function cancels an exposure in progress by closing the shutter. @param dev Camera to cancel the exposure of. @return Zero on success. @return Non-zero on failure. @see FLIExposeFrame @see FLIGetExposureStatus @see FLISetExposureTime */ LIBFLIAPI FLICancelExposure(flidev_t dev) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_CANCEL_EXPOSURE, 0); } /** Find the remaining exposure time of a given camera. This functions places the remaining exposure time (in milliseconds) in the location pointed to by \texttt{timeleft}. @param dev Camera to find the remaining exposure time of. @param timeleft Pointer to where the remaining exposure time (in milliseonds) will be placed. @return Zero on success. @return Non-zero on failure. @see FLIExposeFrame @see FLICancelExposure @see FLISetExposureTime */ LIBFLIAPI FLIGetExposureStatus(flidev_t dev, long *timeleft) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_EXPOSURE_STATUS, 1, timeleft); } /** Set the temperature of a given camera. This function sets the temperature of the CCD camera \texttt{dev} to \texttt{temperature} degrees Celsius. The valid range of the \texttt{temperature} parameter is from -55 C to 45 C. @param dev Camera device to set the temperature of. @param temperature Temperature in Celsius to set CCD camera cold finger to. @return Zero on success. @return Non-zero on failure. @see FLIGetTemperature */ LIBFLIAPI FLISetTemperature(flidev_t dev, double temperature) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_TEMPERATURE, 1, &temperature); } /** Get the temperature of a given camera. This function places the temperature of the CCD camera cold finger of device \texttt{dev} in the location pointed to by \texttt{temperature}. @param dev Camera device to get the temperature of. @param temperature Pointer to where the temperature will be placed. @return Zero on success. @return Non-zero on failure. @see FLISetTemperature */ LIBFLIAPI FLIGetTemperature(flidev_t dev, double *temperature) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_TEMPERATURE, 1, temperature); } /** Grab a row of an image. This function grabs the next available row of the image from camera device \texttt{dev}. The row of width \texttt{width} is placed in the buffer pointed to by \texttt{buff}. The size of the buffer pointed to by \texttt{buff} must take into account the bit depth of the image, meaning the buffer size must be at least \texttt{width} bytes for an 8-bit image, and at least 2*\texttt{width} for a 16-bit image. @param dev Camera whose image to grab the next available row from. @param buff Pointer to where the next available row will be placed. @param width Row width in pixels. @return Zero on success. @return Non-zero on failure. @see FLIGrabFrame */ LIBFLIAPI FLIGrabRow(flidev_t dev, void *buff, size_t width) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GRAB_ROW, 2, buff, &width); } /** Expose a frame for a given camera. This function exposes a frame according to the settings (image area, exposure time, bit depth, etc.) of camera \texttt{dev}. The settings of \texttt{dev} must be valid for the camera device. They are set by calling the appropriate set library functions. This function returns after the exposure has started. @param dev Camera to expose the frame of. @return Zero on success. @return Non-zero on failure. @see FLISetExposureTime @see FLISetFrameType @see FLISetImageArea @see FLISetHBin @see FLISetVBin @see FLISetNFlushes @see FLISetBitDepth @see FLIGrabFrame @see FLICancelExposure @see FLIGetExposureStatus */ LIBFLIAPI FLIExposeFrame(flidev_t dev) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_EXPOSE_FRAME, 0); } /** Flush rows of a given camera. This function flushes \texttt{rows} rows of camera \texttt{dev} \texttt{repeat} times. @param dev Camera to flush rows of. @param rows Number of rows to flush. @param repeat Number of times to flush each row. @return Zero on success. @return Non-zero on failure. @see FLISetNFlushes */ LIBFLIAPI FLIFlushRow(flidev_t dev, long rows, long repeat) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_FLUSH_ROWS, 2, &rows, &repeat); } /** Set the number of flushes for a given camera. This function sets the number of times the CCD array of camera \texttt{dev} is flushed \emph{before} exposing a frame to \texttt{nflushes}. The valid range of the \texttt{nflushes} parameter is from 1 to 16. @param dev Camera to set the number of flushes of. @param nflushes Number of times to flush CCD array before an exposure. @return Zero on success. @return Non-zero on failure. @see FLIFlushRow @see FLIExposeFrame */ LIBFLIAPI FLISetNFlushes(flidev_t dev, long nflushes) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_FLUSHES, 1, &nflushes); } /** Set the gray-scale bit depth for a given camera. This function sets the gray-scale bit depth of camera \texttt{dev} to \texttt{bitdepth}. The \texttt{bitdepth} parameter is either \texttt{FLI_MODE_8BIT} for 8-bit mode or \texttt{FLI_MODE_16BIT} for 16-bit mode. @param dev Camera to set the bit depth of. @param bitdepth Gray-scale bit depth: \texttt{FLI_MODE_8BIT} or \texttt{FLI_MODE_16BIT}. @return Zero on success. @return Non-zero on failure. @see flibitdepth_t @see FLIExposeFrame */ LIBFLIAPI FLISetBitDepth(flidev_t dev, flibitdepth_t bitdepth) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_BIT_DEPTH, 1, &bitdepth); } /** Read the I/O port of a given camera. This function reads the I/O port on camera \texttt{dev} and places the value in the location pointed to by \texttt{ioportset}. @param dev Camera to read the I/O port of. @param ioportset Pointer to where the I/O port data will be stored. @return Zero on success. @return Non-zero on failure. @see FLIWriteIOPort @see FLIConfigureIOPort */ LIBFLIAPI FLIReadIOPort(flidev_t dev, long *ioportset) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_READ_IOPORT, 1, ioportset); } /** Write to the I/O port of a given camera. This function writes the value \texttt{ioportset} to the I/O port on camera \texttt{dev}. @param dev Camera to write I/O port of. @param ioportset Data to be written to the I/O port. @return Zero on success. @return Non-zero on failure. @see FLIReadIOPort @see FLIConfigureIOPort */ LIBFLIAPI FLIWriteIOPort(flidev_t dev, long ioportset) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_WRITE_IOPORT, 1, &ioportset); } /** Configure the I/O port of a given camera. This function configures the I/O port on camera \texttt{dev} with the value \texttt{ioportset}. The I/O configuration of each pin on a given camera is determined by the value of \texttt{ioportset}. Setting a respective I/O bit enables the port bit for output while clearing an I/O bit enables to port bit for input. By default, all I/O ports are configured as inputs. @param dev Camera to configure the I/O port of. @param ioportset Data to configure the I/O port with. @return Zero on success. @return Non-zero on failure. @see FLIReadIOPort @see FLIWriteIOPort */ LIBFLIAPI FLIConfigureIOPort(flidev_t dev, long ioportset) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_CONFIGURE_IOPORT, 1, &ioportset); } /** Lock a specified device. This function establishes an exclusive lock (mutex) on the given device to prevent access to the device by any other function or process. @param dev Device to lock. @return Zero on success. @return Non-zero on failure. @see FLIUnlockDevice */ LIBFLIAPI FLILockDevice(flidev_t dev) { CHKDEVICE(dev); return DEVICE->fli_lock(dev); } /** Unlock a specified device. This function releases a previously established exclusive lock (mutex) on the given device to allow access to the device by any other function or process. @param dev Device to unlock. @return Zero on success. @return Non-zero on failure. @see FLILockDevice */ LIBFLIAPI FLIUnlockDevice(flidev_t dev) { CHKDEVICE(dev); return DEVICE->fli_unlock(dev); } /** Control the shutter on a given camera. This function controls the shutter function on camera \texttt{dev} according to the \texttt{shutter} parameter. @param dev Device to control the shutter of. @param shutter How to control the shutter. A value of \texttt{FLI_SHUTTER_CLOSE} closes the shutter and \texttt{FLI_SHUTTER_OPEN} opens the shutter. \texttt{FLI_SHUTTER_EXTERNAL_TRIGGER_LOW} causes the exposure to begin only when a logic LOW is detected on I/O port bit 0. \texttt{FLI_SHUTTER_EXTERNAL_TRIGGER_HIGH} causes the exposure to begin only when a logic HIGH is detected on I/O port bit 0. This setting may not be available on all cameras. @return Zero on success. @return Non-zero on failure. @see flishutter_t */ LIBFLIAPI FLIControlShutter(flidev_t dev, flishutter_t shutter) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_CONTROL_SHUTTER, 1, &shutter); } /** Enables background flushing of CCD array. This function enables the background flushing of the CCD array camera \texttt{dev} according to the \texttt{bgflush} parameter. Note that this function may not succeed on all FLI products as this feature may not be available. @param dev Device to control the background flushing of. @param bgflush Enables or disables background flushing. A value of \texttt{FLI_BGFLUSH_START} begins background flushing. It is important to note that background flushing is stopped whenever \texttt{FLIExposeFrame()} or \texttt{FLIControlShutter()} are called. \texttt{FLI_BGFLUSH_STOP} stops all background flush activity. @return Zero on success. @return Non-zero on failure. @see flibgflush_t */ LIBFLIAPI FLIControlBackgroundFlush(flidev_t dev, flibgflush_t bgflush) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_CONTROL_BGFLUSH, 1, &bgflush); } /** List available devices. This function returns a pointer to a NULL terminated list of device names. The pointer should be freed later with \texttt{FLIFreeList()}. Each device name in the returned list includes the filename needed by \texttt{FLIOpen()}, a separating semicolon, followed by the model name or user assigned device name. @param domain Domain to list the devices of. This is a bitwise ORed combination of interface method and device type. Valid interfaces include \texttt{FLIDOMAIN_PARALLEL_PORT}, \texttt{FLIDOMAIN_USB}, \texttt{FLIDOMAIN_SERIAL}, and \texttt{FLIDOMAIN_INET}. Valid device types include \texttt{FLIDEVICE_CAMERA}, \texttt{FLIDOMAIN_FILTERWHEEL}, and \texttt{FLIDOMAIN_FOCUSER}. @param names Pointer to where the device name list will be placed. @return Zero on success. @return Non-zero on failure. @see flidomain_t @see FLIFreeList @see FLIOpen */ LIBFLIAPI FLIList(flidomain_t domain, char ***names) { debug(FLIDEBUG_INFO, "FLIList() domain %04x", domain); return fli_list(domain, names); } /** Free a previously generated device list. Use this function after \texttt{FLIList()} to free the list of device names. @param names Pointer to the list. @return Zero on success. @return Non-zero on failure. @see FLIList */ LIBFLIAPI FLIFreeList(char **names) { return fli_freelist(names); } /** Set the filter wheel position of a given device. Use this function to set the filter wheel position of \texttt{dev} to \texttt{filter}. @param dev Filter wheel device handle. @param filter Desired filter wheel position. @return Zero on success. @return Non-zero on failure. @see FLIGetFilterPos */ LIBFLIAPI FLISetFilterPos(flidev_t dev, long filter) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_SET_FILTER_POS, 1, &filter); } /** Get the filter wheel position of a given device. Use this function to get the filter wheel position of \texttt{dev}. @param dev Filter wheel device handle. @param filter Pointer to where the filter wheel position will be placed. @return Zero on success. @return Non-zero on failure. @see FLISetFilterPos */ LIBFLIAPI FLIGetFilterPos(flidev_t dev, long *filter) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_FILTER_POS, 1, filter); } /** Get the filter wheel filter count of a given device. Use this function to get the filter count of filter wheel \texttt{dev}. @param dev Filter wheel device handle. @param filter Pointer to where the filter wheel filter count will be placed. @return Zero on success. @return Non-zero on failure. */ LIBFLIAPI FLIGetFilterCount(flidev_t dev, long *filter) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_FILTER_COUNT, 1, filter); } /** Step the filter wheel or focuser motor of a given device. Use this function to move the focuser or filter wheel \texttt{dev} by an amount \texttt{steps}. @param dev Filter wheel or focuser device handle. @param steps Number of steps to move the focuser or filter wheel. @return Zero on success. @return Non-zero on failure. @see FLIGetStepperPosition */ LIBFLIAPI FLIStepMotor(flidev_t dev, long steps) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_STEP_MOTOR, 1, &steps); } /** Get the stepper motor position of a given device. Use this function to read the stepper motor position of filter wheel or focuser \texttt{dev}. @param dev Filter wheel or focuser device handle. @param position Pointer to where the postion of the stepper motor will be placed. @return Zero on success. @return Non-zero on failure. @see FLIStepMotor */ LIBFLIAPI FLIGetStepperPosition(flidev_t dev, long *position) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_GET_STEPPER_POS, 1, position); } /** Home a given focuser. Use this function to home focuser \texttt{dev}. @param dev Focuser device handle. @return Zero on success. @return Non-zero on failure. */ LIBFLIAPI FLIHomeFocuser(flidev_t dev) { CHKDEVICE(dev); return DEVICE->fli_command(dev, FLI_HOME_FOCUSER, 0); } /* This stuff is used by the next four functions */ typedef struct list { char *filename; char *name; long domain; struct list *next; } list_t; static list_t *firstdevice = NULL; static list_t *currentdevice = NULL; /** Creates a list of all devices within a specified \texttt{domain}. Use \texttt{FLIDeleteList()} to delete the list created with this function. This function is the first called begin the iteration through the list of current FLI devices attached. @param domain Domain to search for devices, set to zero to search all domains. This parameter must contain the device type. @return Zero on success. @return Non-zero on failure. @see FLIDeleteList @see FLIListFirst @see FLIListNext */ LIBFLIAPI FLICreateList(flidomain_t domain) { char **list; flidomain_t domord[5]; int i, j, k; for (i = 0; i < 5; i++) { domord[i] = 0; } if (firstdevice != NULL) { FLIDeleteList(); } currentdevice = NULL; if ((domain & 0x00ff) != 0) { domord[0] = domain; } else { domord[0] = domain | FLIDOMAIN_PARALLEL_PORT; domord[1] = domain | FLIDOMAIN_USB; domord[2] = domain | FLIDOMAIN_SERIAL; } i = 0; while (domord[i] != 0) { debug(FLIDEBUG_INFO, "Searching for domain 0x%04x.", domord[i]); FLIList(domord[i], &list); if (list != NULL) { j = 0; while (list[j] != NULL) { if (firstdevice == NULL) { firstdevice = (list_t *)xmalloc(sizeof(list_t)); if (firstdevice == NULL) return -ENOMEM; currentdevice = firstdevice; } else { currentdevice->next = (list_t *) xmalloc(sizeof(list_t)); if (currentdevice->next == NULL) return -ENOMEM; currentdevice = currentdevice->next; } currentdevice->next = NULL; currentdevice->domain = domord[i]; currentdevice->filename = NULL; currentdevice->name = NULL; k = 0; while (k < (int) strlen(list[j])) { if (list[j][k] == ';') { currentdevice->filename = (char *) xmalloc(k+1); if (currentdevice->filename != NULL) { strncpy(currentdevice->filename, list[j], k); currentdevice->filename[k] = '\0'; } currentdevice->name = (char *) xmalloc(strlen(&list[j][k+1]) + 1); if (currentdevice->name != NULL) { strcpy(currentdevice->name, &list[j][k+1]); } break; } k++; } j++; } FLIFreeList(list); } i++; } return 0; } /** Deletes a list of devices created by \texttt{FLICreateList()}. @return Zero on success. @return Non-zero on failure. @see FLICreateList @see FLIListFirst @see FLIListNext */ LIBFLIAPI FLIDeleteList(void) { list_t *dev = firstdevice; list_t *last; while (dev != NULL) { if (dev->filename != NULL) xfree(dev->filename); if (dev->name != NULL) xfree(dev->name); last = dev; dev = dev->next; xfree(last); } firstdevice = NULL; currentdevice = NULL; return 0; } /** Obtains the first device in the list. Use this function to get the first \texttt{domain}, \texttt{filename} and \texttt{name} from the list of attached FLI devices created using the function \texttt{FLICreateList()}. Use \texttt{FLIListNext()} to obtain more found devices. @param domain Pointer to where to domain of the device will be placed. @param filename Pointer to where the filename of the device will be placed. @param fnlen Length of the supplied buffer to hold the filename. @param name Pointer to where the name of the device will be placed. @param namelen Length of the supplied buffer to hold the name. @return Zero on success. @return Non-zero on failure. @see FLICreateList @see FLIDeleteList @see FLIListNext */ LIBFLIAPI FLIListFirst(flidomain_t *domain, char *filename, size_t fnlen, char *name, size_t namelen) { currentdevice = firstdevice; return FLIListNext(domain, filename, fnlen, name, namelen); } /** Obtains the next device in the list. Use this function to get the next \texttt{domain}, \texttt{filename} and \texttt{name} from the list of attached FLI devices created using the function \texttt{FLICreateList()}. @param domain Pointer to where to domain of the device will be placed. @param filename Pointer to where the filename of the device will be placed. @param fnlen Length of the supplied buffer to hold the filename. @param name Pointer to where the name of the device will be placed. @param namelen Length of the supplied buffer to hold the name. @return Zero on success. @return Non-zero on failure. @see FLICreateList @see FLIDeleteList @see FLIListFirst */ LIBFLIAPI FLIListNext(flidomain_t *domain, char *filename, size_t fnlen, char *name, size_t namelen) { if (currentdevice == NULL) { *domain = 0; filename[0] = '\0'; name[0] = '\0'; return -EBADF; } *domain = currentdevice->domain; strncpy(filename, currentdevice->filename, fnlen); filename[fnlen-1] = '\0'; strncpy(name, currentdevice->name, namelen); name[namelen-1] = '\0'; currentdevice = currentdevice->next; return 0; } indi-0.5/src/fli/libfli-usb-sys-null.c0000644000175000017500000000427210605175655015451 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include #include #include "libfli-libfli.h" #include "libfli-sys.h" #include "libfli-usb.h" long null_bulkwrite(flidev_t dev, void *buf, long *wlen) { return -errno; } long null_bulkread(flidev_t dev, void *buf, long *rlen) { return -errno; } long unix_usbverifydescriptor(flidev_t dev, fli_unixio_t *io) { return -errno; } indi-0.5/src/fli/libfli-usb.h0000644000175000017500000000503010605175655013663 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_USB_H_ #define _LIBFLI_USB_H_ #define FLI_CMD_ENDPOINT 2 #if defined(__linux__) #define unix_bulkwrite linux_bulkwrite #define unix_bulkread linux_bulkread #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) #define unix_bulkwrite bsd_bulkwrite #define unix_bulkread bsd_bulkread #else #define unix_bulkwrite null_bulkwrite #define unix_bulkread null_bulkread #warning "using null I/O operations!" #endif long unix_bulkwrite(flidev_t dev, void *buf, long *wlen); long unix_bulkread(flidev_t dev, void *buf, long *rlen); long unix_usbio(flidev_t dev, void *buf, long *wlen, long *rlen); long unix_usbverifydescriptor(flidev_t dev, fli_unixio_t *io); #endif /* _LIBFLI_USB_H_ */ indi-0.5/src/fli/libfli-filter-focuser.h0000644000175000017500000000505310605175655016030 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _FLI_FILTER_FOCUSER_H_ #define _FLI_FILTER_FOCUSER_H_ #define FLI_FILTERPOSITION_HOME (-1) /* Filter wheel and focuser parameters */ typedef struct { long numslots; long stepspersec; long currentslot; } flifilterdata_t; typedef struct { int n_pos; int n_offset; int n_steps[16]; } wheeldata_t; long fli_filter_focuser_open(flidev_t dev); #define fli_filter_open fli_filter_focuser_open #define fli_focuser_open fli_filter_focuser_open long fli_filter_focuser_close(flidev_t dev); #define fli_filter_close fli_filter_focuser_close #define fli_focuser_close fli_filter_focuser_close long fli_filter_command(flidev_t dev, int cmd, int argc, ...); long fli_focuser_command(flidev_t dev, int cmd, int argc, ...); #endif /* _FLI_FILTER_FOCUSER_H_ */ indi-0.5/src/fli/libfli-mem.c0000644000175000017500000001051610605175655013650 0ustar jrjr/* Copyright (c) 2000, 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include #include "libfli-libfli.h" #include "libfli-mem.h" #define DEFAULT_NUM_POINTERS (1024) static struct { void **pointers; int total; int used; } allocated = {NULL, 0, 0}; void *xmalloc(size_t size) { int i; void *ptr; if (allocated.used + 1 > allocated.total) { void **tmp; int num; num = (allocated.total == 0 ? DEFAULT_NUM_POINTERS : 2 * allocated.total); if ((tmp = (void **)realloc(allocated.pointers, num * sizeof(void **))) == NULL) return NULL; allocated.pointers = tmp; memset(&allocated.pointers[allocated.total], 0, num * sizeof(void **)); allocated.total += num; } if ((ptr = malloc(size)) == NULL) return NULL; for (i = 0; i < allocated.total; i++) { if (allocated.pointers[i] == NULL) break; } if (i == allocated.total) { /* This shouldn't happen */ debug(FLIDEBUG_WARN, "Internal memory allocation error"); free(ptr); return NULL; } allocated.pointers[i] = ptr; allocated.used++; return ptr; } void *xcalloc(size_t nmemb, size_t size) { void *ptr; if ((ptr = xmalloc(nmemb * size)) == NULL) return NULL; memset(ptr, 0, nmemb * size); return ptr; } void xfree(void *ptr) { int i; for (i = 0; i < allocated.total; i++) { if (allocated.pointers[i] == ptr) { free(ptr); allocated.pointers[i] = NULL; allocated.used--; return; } } debug(FLIDEBUG_WARN, "Attempting to free an invalid pointer"); return; } void *xrealloc(void *ptr, size_t size) { int i; for (i = 0; i < allocated.total; i++) { if (allocated.pointers[i] == ptr) { void *tmp; if ((tmp = realloc(ptr, size)) == NULL) return NULL; allocated.pointers[i] = tmp; return tmp; } } debug(FLIDEBUG_WARN, "Attempting to realloc an invalid pointer"); return NULL; } int xfree_all(void) { int i; int freed = 0; for (i = 0; i < allocated.total; i++) { if (allocated.pointers[i] != NULL) { free(allocated.pointers[i]); allocated.pointers[i] = NULL; allocated.used--; freed++; } } if (allocated.used != 0) debug(FLIDEBUG_WARN, "Internal memory handling error"); if (allocated.pointers != NULL) free(allocated.pointers); allocated.pointers = NULL; allocated.used = 0; allocated.total = 0; return freed; } char *xstrdup(const char *s) { void *tmp; size_t len; len = strlen(s) + 1; if ((tmp = xmalloc(len)) == NULL) return NULL; memcpy(tmp, s, len); return tmp; } indi-0.5/src/fli/fli_ioctl.h0000644000175000017500000001052510605175655013604 0ustar jrjr/* Copyright (c) 2000 Finger Lakes Instrumentation (FLI), LLC. All rights reserved. email: fli@rpa.net Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation (FLI) web: http://www.fli-cam.com email: fli@rpa.net */ #ifndef _FLI_IOCTL_H #define _FLI_IOCTL_H #include /* 8-bit special value to identify ioctl 'type' */ #define FLI_IOCTL_TYPE 'F' /* Macros declaring ioctl commands and the variables they operate on */ #define FLI_IOCTL_MISC_CMDS \ FLI_IOCTL_CMD(FLI_RESET_PORT_VALUES, **NONE**) \ FLI_IOCTL_CMD(FLI_LOCK_PORT, **NONE**) \ FLI_IOCTL_CMD(FLI_UNLOCK_PORT, **NONE**) #define FLI_IOCTL_SPECIAL_SET_CMDS \ FLI_IOCTL_CMD(FLI_SET_DMABUFFSIZE, dmabuffsize) #define FLI_IOCTL_SET_CMDS \ FLI_IOCTL_CMD(FLI_SET_DMATHRESH, dmathresh) \ FLI_IOCTL_CMD(FLI_SET_DTO, dto) \ FLI_IOCTL_CMD(FLI_SET_RTO, rto) \ FLI_IOCTL_CMD(FLI_SET_WTO, wto) \ FLI_IOCTL_CMD(FLI_SET_LTL, ltl) \ FLI_IOCTL_CMD(FLI_SET_DIR, dir) \ FLI_IOCTL_CMD(FLI_SET_NUMREAD, numread) \ FLI_IOCTL_CMD(FLI_SET_NUMWRITE, numwrite) \ FLI_IOCTL_CMD(FLI_SET_NUMDTO, numdto) \ FLI_IOCTL_CMD(FLI_SET_NUMRTO, numrto) \ FLI_IOCTL_CMD(FLI_SET_NUMWTO, numwto) #define FLI_IOCTL_GET_CMDS \ FLI_IOCTL_CMD(FLI_GET_DMABUFFSIZE, dmabuffsize) \ FLI_IOCTL_CMD(FLI_GET_DMATHRESH, dmathresh) \ FLI_IOCTL_CMD(FLI_GET_DTO, dto) \ FLI_IOCTL_CMD(FLI_GET_RTO, rto) \ FLI_IOCTL_CMD(FLI_GET_WTO, wto) \ FLI_IOCTL_CMD(FLI_GET_DIR, dir) \ FLI_IOCTL_CMD(FLI_GET_LTL, ltl) \ FLI_IOCTL_CMD(FLI_GET_NUMREAD, numread) \ FLI_IOCTL_CMD(FLI_GET_NUMWRITE, numwrite) \ FLI_IOCTL_CMD(FLI_GET_NUMDTO, numdto) \ FLI_IOCTL_CMD(FLI_GET_NUMRTO, numrto) \ FLI_IOCTL_CMD(FLI_GET_NUMWTO, numwto) /* Enumerate ioctl numbers */ #undef FLI_SET_CMD #define FLI_IOCTL_CMD(cmd, var) cmd##_NUM, enum { FLI_IOCTL_MISC_CMDS FLI_IOCTL_SPECIAL_SET_CMDS FLI_IOCTL_SET_CMDS FLI_IOCTL_GET_CMDS }; /* Enumerate the actual ioctl commands */ #undef FLI_IOCTL_CMD #define FLI_IOCTL_CMD(cmd, var) \ enum {cmd = _IO(FLI_IOCTL_TYPE, cmd##_NUM)}; FLI_IOCTL_MISC_CMDS; #undef FLI_IOCTL_CMD #define FLI_IOCTL_CMD(cmd, var) \ enum {cmd = _IOW(FLI_IOCTL_TYPE, cmd##_NUM, int)}; FLI_IOCTL_SPECIAL_SET_CMDS; FLI_IOCTL_SET_CMDS; #undef FLI_IOCTL_CMD #define FLI_IOCTL_CMD(cmd, var ) \ enum {cmd = _IOR(FLI_IOCTL_TYPE, cmd##_NUM, int)}; FLI_IOCTL_GET_CMDS; #endif /* _FLI_IOCTL_H */ indi-0.5/src/fli/libfli.h0000644000175000017500000001640510605175655013104 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_H_ #define _LIBFLI_H_ #include /** An opaque handle used by library functions to refer to FLI hardware. */ typedef long flidev_t; /** The domain of an FLI device. This consists of a bitwise ORed combination of interface method and device type. Valid interfaces are \texttt{FLIDOMAIN_PARALLEL_PORT}, \texttt{FLIDOMAIN_USB}, \texttt{FLIDOMAIN_SERIAL}, and \texttt{FLIDOMAIN_INET}. Valid device types are \texttt{FLIDEVICE_CAMERA}, \texttt{FLIDOMAIN_FILTERWHEEL}, and \texttt{FLIDOMAIN_FOCUSER}. @see FLIOpen @see FLIList */ typedef long flidomain_t; #define FLIDOMAIN_NONE (0x00) #define FLIDOMAIN_PARALLEL_PORT (0x01) #define FLIDOMAIN_USB (0x02) #define FLIDOMAIN_SERIAL (0x03) #define FLIDOMAIN_INET (0x04) #define FLIDEVICE_NONE (0x000) #define FLIDEVICE_CAMERA (0x100) #define FLIDEVICE_FILTERWHEEL (0x200) #define FLIDEVICE_FOCUSER (0x300) /** The frame type for an FLI CCD camera device. Valid frame types are \texttt{FLI_FRAME_TYPE_NORMAL} and \texttt{FLI_FRAME_TYPE_DARK}. @see FLISetFrameType */ typedef long fliframe_t; #define FLI_FRAME_TYPE_NORMAL (0) #define FLI_FRAME_TYPE_DARK (1) /** The gray-scale bit depth for an FLI camera device. Valid bit depths are \texttt{FLI_MODE_8BIT} and \texttt{FLI_MODE_16BIT}. @see FLISetBitDepth */ typedef long flibitdepth_t; #define FLI_MODE_8BIT (0) #define FLI_MODE_16BIT (1) /** Type used for shutter operations for an FLI camera device. Valid shutter types are \texttt{FLI_SHUTTER_CLOSE}, \texttt{FLI_SHUTTER_OPEN}, \texttt{FLI_SHUTTER_EXTERNAL_TRIGGER}, \texttt{FLI_SHUTTER_EXTERNAL_TRIGGER_LOW}, and \texttt{FLI_SHUTTER_EXTERNAL_TRIGGER_HIGH}. @see FLIControlShutter */ typedef long flishutter_t; #define FLI_SHUTTER_CLOSE (0x0000) #define FLI_SHUTTER_OPEN (0x0001) #define FLI_SHUTTER_EXTERNAL_TRIGGER (0x0002) #define FLI_SHUTTER_EXTERNAL_TRIGGER_LOW (0x0002) #define FLI_SHUTTER_EXTERNAL_TRIGGER_HIGH (0x0004) /** Type used for background flush operations for an FLI camera device. Valid bgflush types are \texttt{FLI_BGFLUSH_STOP} and \texttt{FLI_BGFLUSH_START}. @see FLIControlBackgroundFlush */ typedef long flibgflush_t; #define FLI_BGFLUSH_STOP (0x0000) #define FLI_BGFLUSH_START (0x0001) /** Type specifying library debug levels. Valid debug levels are \texttt{FLIDEBUG_NONE}, \texttt{FLIDEBUG_INFO}, \texttt{FLIDEBUG_WARN}, and \texttt{FLIDEBUG_FAIL}. @see FLISetDebugLevel */ typedef long flidebug_t; #define FLIDEBUG_NONE (0x00) #define FLIDEBUG_INFO (0x01) #define FLIDEBUG_WARN (0x02) #define FLIDEBUG_FAIL (0x04) #define FLIDEBUG_ALL (FLIDEBUG_INFO | FLIDEBUG_WARN | FLIDEBUG_FAIL) #ifdef WIN32 #ifndef LIBFLIAPI #define LIBFLIAPI __declspec(dllimport) long __stdcall #endif #else #define LIBFLIAPI long #endif /* Library API Function prototypes */ #ifdef __cplusplus extern "C" { // only need to export C interface if used by C++ source code #endif LIBFLIAPI FLIOpen(flidev_t *dev, char *name, flidomain_t domain); LIBFLIAPI FLISetDebugLevel(char *host, flidebug_t level); LIBFLIAPI FLIClose(flidev_t dev); LIBFLIAPI FLIGetLibVersion(char* ver, size_t len); LIBFLIAPI FLIGetModel(flidev_t dev, char* model, size_t len); LIBFLIAPI FLIGetPixelSize(flidev_t dev, double *pixel_x, double *pixel_y); LIBFLIAPI FLIGetHWRevision(flidev_t dev, long *hwrev); LIBFLIAPI FLIGetFWRevision(flidev_t dev, long *fwrev); LIBFLIAPI FLIGetArrayArea(flidev_t dev, long* ul_x, long* ul_y, long* lr_x, long* lr_y); LIBFLIAPI FLIGetVisibleArea(flidev_t dev, long* ul_x, long* ul_y, long* lr_x, long* lr_y); LIBFLIAPI FLISetExposureTime(flidev_t dev, long exptime); LIBFLIAPI FLISetImageArea(flidev_t dev, long ul_x, long ul_y, long lr_x, long lr_y); LIBFLIAPI FLISetHBin(flidev_t dev, long hbin); LIBFLIAPI FLISetVBin(flidev_t dev, long vbin); LIBFLIAPI FLISetFrameType(flidev_t dev, fliframe_t frametype); LIBFLIAPI FLICancelExposure(flidev_t dev); LIBFLIAPI FLIGetExposureStatus(flidev_t dev, long *timeleft); LIBFLIAPI FLISetTemperature(flidev_t dev, double temperature); LIBFLIAPI FLIGetTemperature(flidev_t dev, double *temperature); LIBFLIAPI FLIGrabRow(flidev_t dev, void *buff, size_t width); LIBFLIAPI FLIExposeFrame(flidev_t dev); LIBFLIAPI FLIFlushRow(flidev_t dev, long rows, long repeat); LIBFLIAPI FLISetNFlushes(flidev_t dev, long nflushes); LIBFLIAPI FLISetBitDepth(flidev_t dev, flibitdepth_t bitdepth); LIBFLIAPI FLIReadIOPort(flidev_t dev, long *ioportset); LIBFLIAPI FLIWriteIOPort(flidev_t dev, long ioportset); LIBFLIAPI FLIConfigureIOPort(flidev_t dev, long ioportset); LIBFLIAPI FLILockDevice(flidev_t dev); LIBFLIAPI FLIUnlockDevice(flidev_t dev); LIBFLIAPI FLIControlShutter(flidev_t dev, flishutter_t shutter); LIBFLIAPI FLIControlBackgroundFlush(flidev_t dev, flibgflush_t bgflush); LIBFLIAPI FLIList(flidomain_t domain, char ***names); LIBFLIAPI FLIFreeList(char **names); LIBFLIAPI FLISetFilterPos(flidev_t dev, long filter); LIBFLIAPI FLIGetFilterPos(flidev_t dev, long *filter); LIBFLIAPI FLIGetFilterCount(flidev_t dev, long *filter); LIBFLIAPI FLIStepMotor(flidev_t dev, long steps); LIBFLIAPI FLIGetStepperPosition(flidev_t dev, long *position); LIBFLIAPI FLIHomeFocuser(flidev_t dev); LIBFLIAPI FLICreateList(flidomain_t domain); LIBFLIAPI FLIDeleteList(void); LIBFLIAPI FLIListFirst(flidomain_t *domain, char *filename, size_t fnlen, char *name, size_t namelen); LIBFLIAPI FLIListNext(flidomain_t *domain, char *filename, size_t fnlen, char *name, size_t namelen); #ifdef __cplusplus } #endif #endif /* _LIBFLI_H_ */ indi-0.5/src/fli/libfli-camera.h0000644000175000017500000000615210605175655014330 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_CAMERA_H_ #define _LIBFLI_CAMERA_H_ typedef struct { int x; /* X coordinate */ int y; /* Y coordinate */ } point_t; typedef struct { point_t ul; /* Upper-left */ point_t lr; /* Lower-right */ } area_t; /* CCD Parameter list */ typedef struct { short index; const char *model; area_t array_area; area_t visible_area; double fillfactor; double pixelwidth; double pixelheight; } fliccdinfo_t; typedef struct { long readto; long writeto; long dirto; fliccdinfo_t ccd; /* Acquisistion parameters */ area_t image_area; long vbin; long hbin; long vflushbin; long hflushbin; long exposure; long expdur; long expmul; long frametype; long flushes; long bitdepth; long exttrigger; long exttriggerpol; double tempslope; double tempintercept; long grabrowcount; long grabrowcounttot; long grabrowindex; long grabrowwidth; long grabrowbatchsize; long grabrowbufferindex; long flushcountbeforefirstrow; long flushcountafterlastrow; unsigned short *gbuf; } flicamdata_t; extern const fliccdinfo_t knowndev[]; long fli_camera_open(flidev_t dev); long fli_camera_close(flidev_t dev); long fli_camera_command(flidev_t dev, int cmd, int argc, ...); #endif /* _LIBFLI_CAMERA_H_ */ indi-0.5/src/fli/libfli-libfli.h0000644000175000017500000001400310605175655014333 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_LIBFLI_H_ #define _LIBFLI_LIBFLI_H_ #include #ifdef WIN32 #define LIBFLIAPI __declspec(dllexport) long __stdcall #endif #include "libfli.h" #include "libfli-sys.h" #include "libfli-debug.h" #define __STRINGIFY(x) ___STRINGIFY(x) #define ___STRINGIFY(x) #x #define __LIBFLIVER_MAJOR__ 1 #define __LIBFLIVER__ __STRINGIFY(__LIBFLIVER_MAJOR__) "." \ __STRINGIFY(__LIBFLI_MINOR__) #define CHKDEVICE(xdev) \ do { \ if((xdev < 0) || (xdev >= MAX_OPEN_DEVICES)) \ { \ debug(FLIDEBUG_WARN, \ "Attempt to use a device out of range (%d)", xdev); \ return -EINVAL; \ } \ if(devices[xdev] == NULL) \ { \ debug(FLIDEBUG_WARN, \ "Attempt to use a NULL device (%d)", xdev); \ return -EINVAL; \ } \ } while(0) #define CHKFUNCTION(func) \ do { \ if(func == NULL) \ { \ debug(FLIDEBUG_WARN, \ "Attempt to use a NULL function (" #func ")"); \ return -EINVAL; \ } \ } while(0) #define IO(dev, buf, wlen, rlen) \ do { \ int err; \ if((err = devices[dev]->fli_io(dev, buf, wlen, rlen))) \ { \ debug(FLIDEBUG_WARN, "Communication error: %d [%s]", \ err, strerror(-err)); \ return err; \ } \ } while(0) #define COMMAND(function) \ do { \ int err; \ if((err = function)) \ { \ debug(FLIDEBUG_WARN, \ "Function `" #function "' failed, error: %d [%s]", \ err, strerror(-err)); \ return err; \ } \ } while(0) #define FLIUSB_VENDORID 0xf18 #define FLIUSB_CAM_ID 0x02 #define FLIUSB_FILTER_ID 0x07 #define FLIUSB_FOCUSER_ID 0x06 #define MAX_OPEN_DEVICES (32) #define MAX_SEARCH_LIST (16) /* Common device information */ typedef struct { long type; long fwrev; long hwrev; long devid; long serno; char *model; char *devnam; } flidevinfo_t; /* A specific device instance */ typedef struct { char *name; /* The device name */ long domain; /* The device's domain */ flidevinfo_t devinfo; /* Device information */ long io_timeout; /* Timeout in msec for all I/O */ void *io_data; /* For holding I/O specific data */ void *device_data; /* For holding device specific data */ void *sys_data; /* For holding system specific data */ /* System-specific functions */ long (*fli_lock)(flidev_t dev); long (*fli_unlock)(flidev_t dev); /* Domain-specific functions */ long (*fli_io)(flidev_t dev, void *buf, long *wlen, long *rlen); /* Device-specific functions */ long (*fli_open)(flidev_t dev); long (*fli_close)(flidev_t dev); long (*fli_command)(flidev_t dev, int cmd, int argc, ...); } flidevdesc_t; extern const char* version; extern flidevdesc_t *devices[MAX_OPEN_DEVICES]; #define DEVICE devices[dev] /* Device commands, the format is FLI_COMMAND(, ) */ #define FLI_COMMANDS \ FLI_COMMAND(FLI_NONE, 0) \ FLI_COMMAND(FLI_GET_PIXEL_SIZE, 2) \ FLI_COMMAND(FLI_GET_ARRAY_AREA, 4) \ FLI_COMMAND(FLI_GET_VISIBLE_AREA, 4) \ FLI_COMMAND(FLI_SET_EXPOSURE_TIME, 1) \ FLI_COMMAND(FLI_SET_IMAGE_AREA, 4) \ FLI_COMMAND(FLI_SET_HBIN, 1) \ FLI_COMMAND(FLI_SET_VBIN, 1) \ FLI_COMMAND(FLI_SET_FRAME_TYPE, 1) \ FLI_COMMAND(FLI_CANCEL_EXPOSURE, 0) \ FLI_COMMAND(FLI_GET_EXPOSURE_STATUS, 1) \ FLI_COMMAND(FLI_SET_TEMPERATURE, 1) \ FLI_COMMAND(FLI_GET_TEMPERATURE, 1) \ FLI_COMMAND(FLI_GRAB_ROW, 2) \ FLI_COMMAND(FLI_EXPOSE_FRAME, 0) \ FLI_COMMAND(FLI_FLUSH_ROWS, 2) \ FLI_COMMAND(FLI_SET_FLUSHES, 1) \ FLI_COMMAND(FLI_SET_BIT_DEPTH, 1) \ FLI_COMMAND(FLI_READ_IOPORT, 1) \ FLI_COMMAND(FLI_WRITE_IOPORT, 1) \ FLI_COMMAND(FLI_CONFIGURE_IOPORT, 1) \ FLI_COMMAND(FLI_CONTROL_SHUTTER, 1) \ FLI_COMMAND(FLI_CONTROL_BGFLUSH, 1) \ FLI_COMMAND(FLI_SET_FILTER_POS, 1) \ FLI_COMMAND(FLI_GET_FILTER_POS, 1) \ FLI_COMMAND(FLI_GET_FILTER_COUNT, 1) \ FLI_COMMAND(FLI_STEP_MOTOR, 1) \ FLI_COMMAND(FLI_GET_STEPPER_POS, 1) \ FLI_COMMAND(FLI_HOME_FOCUSER, 0) /* Enumerate the commands */ enum { #define FLI_COMMAND(name, args) name, FLI_COMMANDS #undef FLI_COMMAND }; #endif /* _LIBFLI_LIBFLI_H_ */ indi-0.5/src/fli/libfli-parport.h0000644000175000017500000000433510605175655014570 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_PARPORT_H_ #define _LIBFLI_PARPORT_H_ #if defined(__linux__) #define unix_parportio unix_parportio_linux #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) #define unix_parportio NULL #else #define unix_parportio NULL #warning "Unknown system" #endif long unix_parportio_linux(flidev_t dev, void *buf, long *wlen, long *rlen); #endif /* _LIBFLI_PARPORT_H_ */ indi-0.5/src/fli/libfli-sys.h0000644000175000017500000000743110605175655013717 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #ifndef _LIBFLI_SYS_H #define _LIBFLI_SYS_H #include #define LIBFLIAPI long #if defined(__linux__) #define __SYSNAME__ "Linux" #define __LIBFLI_MINOR__ 11 #define USB_READ_SIZ_MAX 4096 /* Can only read a page at a time */ #define _USE_FLOCK_ #define PARPORT_GLOB "/dev/ccd*" #define USB_GLOB "/proc/bus/usb/*/*" #define SERIAL_GLOB "/dev/ttyS[0-9]*" #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) // FIXME - this does not actually work on OSX #define __SYSNAME__ "FreeBSD" #define __LIBFLI_MINOR__ 1 #define USB_READ_SIZ_MAX (1024 *1024) /* 1 MB (This is arbitrary, but * must be able to malloc this amount.) */ #define USB_GLOB "/dev/ugen*." __STRINGIFY(FLI_CMD_ENDPOINT) #define SERIAL_GLOB "/dev/cuaa*" #elif defined (__NetBSD__) #define __SYSNAME__ "NetBSD" #define __LIBFLI_MINOR__ 1 #define USB_READ_SIZ_MAX (1024 *1024) /* 1 MB (This is arbitrary, but * must be able to malloc this amount.) */ #define USB_GLOB "/dev/ugen*.0" __STRINGIFY(FLI_CMD_ENDPOINT) #define SERIAL_GLOB "/dev/dty0*" #elif defined(__OpenBSD__) #define __SYSNAME__ "OpenBSD" #define __LIBFLI_MINOR__ 1 #define USB_READ_SIZ_MAX (1024 *1024) /* 1 MB (This is arbitrary, but * must be able to malloc this amount.) */ #define USB_GLOB "/dev/ugen*.0" __STRINGIFY(FLI_CMD_ENDPOINT) #define SERIAL_GLOB "/dev/dty0*" #else #define __SYSNAME__ "Unknown" #define __LIBFLI_MINOR__ 1 #define USB_READ_SIZ_MAX 0 #define USB_GLOB "" #define SERIAL_GLOB "" #warning "Unknown system" #endif typedef struct { int fd; } fli_unixio_t; long unix_fli_connect(flidev_t dev, char *name, long domain); long unix_fli_disconnect(flidev_t dev); long unix_fli_lock(flidev_t dev); long unix_fli_unlock(flidev_t dev); long unix_fli_list(flidomain_t domain, char ***names); #define fli_connect unix_fli_connect #define fli_disconnect unix_fli_disconnect #define fli_list unix_fli_list #endif /* _LIBFLI_SYS_H */ indi-0.5/src/fli/libfli-usb.c0000644000175000017500000000526510605175655013670 0ustar jrjr/* Copyright (c) 2002 Finger Lakes Instrumentation (FLI), L.L.C. (fli@rpa.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Finger Lakes Instrumentation (FLI), LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Finger Lakes Instrumentation, L.L.C. (FLI) web: http://www.fli-cam.com email: support@fli-cam.com */ #include #include "libfli-libfli.h" #include "libfli-debug.h" #include "libfli-sys.h" #include "libfli-usb.h" long unix_usbio(flidev_t dev, void *buf, long *wlen, long *rlen) { int err = 0, locked = 0; long org_wlen = *wlen, org_rlen = *rlen; if ((err = unix_fli_lock(dev))) { debug(FLIDEBUG_WARN, "Lock failed"); goto done; } locked = 1; if ((err = unix_bulkwrite(dev, buf, wlen))) { debug(FLIDEBUG_WARN, "Bulkwrite failed, only %d of %d bytes written", *wlen, org_wlen); goto done; } if (*rlen > 0) { if ((err = unix_bulkread(dev, buf, rlen))) { debug(FLIDEBUG_WARN, "Bulkread failed, only %d of %d bytes read", *rlen, org_rlen); goto done; } } done: if (locked) { int r; if ((r = unix_fli_unlock(dev))) debug(FLIDEBUG_WARN, "Unlock failed"); if (err == 0) err = r; } return err; } indi-0.5/src/observer.c0000755000175000017500000002670710610474331012711 0ustar jrjr#if 0 INDI Copyright (C) 2006 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include #include #include "indiapi.h" #include "indidevapi.h" #include "observer.h" #include "indicom.h" typedef struct { int in_use; char dev[MAXINDIDEVICE]; char name[MAXINDINAME]; IPType property_type; IDType notification_type; fpt fp; } OBP; static OBP *oblist; /* malloced list of work procedures */ static int noblist; /* n entries in wproc[] */ void IOSubscribeProperty(const char *dev, const char *name, IPType property_type, IDType notification_type, fpt fp) { OBP *obp; /* reuse first unused slot or grow */ for (obp = oblist; obp < &oblist[noblist]; obp++) if (!obp->in_use) break; if (obp == &oblist[noblist]) { oblist = oblist ? (OBP *) realloc (oblist, (noblist+1)*sizeof(OBP)) : (OBP *) malloc (sizeof(OBP)); obp = &oblist[noblist++]; } /* init new entry */ obp->in_use = 1; obp->fp = fp; obp->property_type = property_type; obp->notification_type = notification_type; strncpy(obp->dev, dev, MAXINDIDEVICE); strncpy(obp->name, name, MAXINDINAME); printf ("", idtypeStr(notification_type)); fflush (stdout); } void IOUnsubscribeProperty(const char *dev, const char *name) { OBP *obp; for (obp = oblist; obp < &oblist[noblist]; obp++) { if (!strcmp(obp->dev, dev) && !strcmp(obp->name, name)) { obp->in_use = 0; printf ("\n"); fflush (stdout); } } } const char * idtypeStr(IDType type) { switch (type) { case IDT_VALUE: return "Value"; break; case IDT_STATE: return "State"; break; case IDT_ALL: return "All"; break; default: return "Unknown"; break; } } int processObservers(XMLEle *root) { OBP *obp; XMLAtt* ap; IDState state; char prop_dev[MAXINDIDEVICE]; char prop_name[MAXINDINAME]; XMLEle *epx; int n; /* Driver sent which message? */ if (strstr(tagXMLEle(root), "def")) state = IDS_DEFINED; else if (strstr(tagXMLEle(root), "set")) state = IDS_UPDATED; else if (strstr(tagXMLEle(root), "del")) state = IDS_DELETED; /* So far the only alert is when the driver dies, so the xml tag should suffice for now */ else if (!strcmp(tagXMLEle(root), "subscribtionAlert")) state = IDS_DIED; else { /* Silently ignore */ return (-1); } ap = findXMLAtt(root, "device"); if (!ap) { fprintf(stderr, "<%s> missing 'device' attribute.\n", tagXMLEle(root)); exit(1); } else strncpy(prop_dev, valuXMLAtt(ap), MAXINDIDEVICE); /* Del/Die prop might not have name, so don't panic */ ap = findXMLAtt(root, "name"); if (!ap && (state == IDS_DEFINED || state == IDS_UPDATED)) { fprintf(stderr, "<%s> missing 'name' attribute.\n", tagXMLEle(root)); exit(1); } else if (ap) strncpy(prop_name, valuXMLAtt(ap), MAXINDINAME); if (state == IDS_DELETED || state == IDS_DIED) { for (obp = oblist; obp < &oblist[noblist]; obp++) { /* We got a match */ if (!strcmp(obp->dev, prop_dev)) { switch (obp->property_type) { case IPT_SWITCH: case IPT_TEXT: case IPT_NUMBER: case IPT_LIGHT: obp->fp(obp->dev, obp->name, state, NULL, NULL, 0); break; case IPT_BLOB: obp->fp(obp->dev, obp->name, state, NULL, NULL, NULL, NULL, 0); break; } } } return (0); } for (obp = oblist; obp < &oblist[noblist]; obp++) { if (!strcmp(obp->dev, prop_dev) && !strcmp(obp->name, prop_name)) { /* check tag in surmised decreasing order of likelyhood */ if (!strcmp (tagXMLEle(root), "setNumberVector") || !strcmp (tagXMLEle(root), "defNumberVector")) { static double *doubles; static char **names; static int maxn; /* seed for reallocs */ if (!doubles) { doubles = (double *) malloc (sizeof(double*)); names = (char **) malloc (sizeof(double*)); } /* pull out each name/value pair */ for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) { if (strstr(tagXMLEle(epx), "Number")) { XMLAtt *na = findXMLAtt (epx, "name"); if (na) { if (n >= maxn) { /* grow for this and another */ int newsz = (maxn=n+1)*sizeof(double); doubles = (double *) realloc(doubles,newsz); newsz = maxn*sizeof(char *); names = (char **) realloc (names, newsz); } if (f_scansexa (pcdataXMLEle(epx), &doubles[n]) < 0) IDLog ("%s: Bad format %s", obp->name, pcdataXMLEle(epx)); else names[n++] = valuXMLAtt(na); } } } /* invoke driver if something to do, but not an error if not */ if (n > 0) { obp->fp(obp->dev, obp->name, state, doubles, names, n); } else IDLog("%s: NumberVector with no valid members", obp->name); return (0); } if (!strcmp (tagXMLEle(root), "setSwitchVector") || !strcmp (tagXMLEle(root), "defSwitchVector")) { static ISState *states; static char **names; static int maxn; /* seed for reallocs */ if (!states) { states = (ISState *) malloc (sizeof(void*)); names = (char **) malloc (sizeof(void*)); } /* pull out each name/state pair */ for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) { if (strstr(tagXMLEle(epx), "Switch")) { XMLAtt *na = findXMLAtt (epx, "name"); if (na) { if (n >= maxn) { int newsz = (maxn=n+1)*sizeof(ISState); states = (ISState *) realloc(states, newsz); newsz = maxn*sizeof(char *); names = (char **) realloc (names, newsz); } if (strcmp (pcdataXMLEle(epx),"On") == 0) { states[n] = ISS_ON; names[n] = valuXMLAtt(na); n++; } else if (strcmp (pcdataXMLEle(epx),"Off") == 0) { states[n] = ISS_OFF; names[n] = valuXMLAtt(na); n++; } else { IDLog ("%s: must be On or Off: %s\n", obp->name, pcdataXMLEle(epx)); exit(1); } } } } /* invoke driver if something to do, but not an error if not */ if (n > 0) obp->fp(obp->dev, obp->name, state, states, names, n); else IDLog("%s: SwitchVector with no valid members", obp->name); return (0); } if (!strcmp (tagXMLEle(root), "setTextVector") || !strcmp (tagXMLEle(root), "defTextVector")) { static char **texts; static char **names; static int maxn; /* seed for reallocs */ if (!texts) { texts = (char **) malloc (sizeof(char**)); names = (char **) malloc (sizeof(char**)); } /* pull out each name/text pair */ for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) { if (strstr(tagXMLEle(epx), "Text")) { XMLAtt *na = findXMLAtt (epx, "name"); if (na) { if (n >= maxn) { int newsz = (maxn=n+1)*sizeof(char *); texts = (char **) realloc (texts, newsz); names = (char **) realloc (names, newsz); } texts[n] = pcdataXMLEle(epx); names[n] = valuXMLAtt(na); n++; } } } /* invoke driver if something to do, but not an error if not */ if (n > 0) obp->fp(obp->dev, obp->name, state, texts, names, n); else IDLog("%s: TextVector with no valid members", obp->name); return (0); } if (!strcmp (tagXMLEle(root), "setBLOBVector") || !strcmp (tagXMLEle(root), "defBLOBVector")) { static char **blobs; static char **names; static char **formats; static int *blobsizes; static int maxn; /* seed for reallocs */ if (!blobs) { blobs = (char **) malloc (sizeof(void*)); names = (char **) malloc (sizeof(void*)); formats = (char **) malloc (sizeof(void*)); blobsizes = (int *) malloc (sizeof(void*)); } /* pull out each name/BLOB pair */ for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) { if (strstr(tagXMLEle(epx), "BLOB")) { XMLAtt *na = findXMLAtt (epx, "name"); XMLAtt *fa = findXMLAtt (epx, "format"); XMLAtt *sa = findXMLAtt (epx, "size"); if (na && fa && sa) { if (n >= maxn) { int newsz = (maxn=n+1)*sizeof(char *); blobs = (char **) realloc (blobs, newsz); names = (char **) realloc (names, newsz); formats = (char **) realloc(formats,newsz); newsz = maxn*sizeof(int); blobsizes = (int *) realloc(blobsizes,newsz); } blobs[n] = pcdataXMLEle(epx); names[n] = valuXMLAtt(na); formats[n] = valuXMLAtt(fa); blobsizes[n] = atoi(valuXMLAtt(sa)); n++; } } } /* invoke driver if something to do, but not an error if not */ if (n > 0) obp->fp(obp->dev, obp->name, state, blobsizes, blobs, formats, names, n); else IDLog("%s: BLOBVector with no valid members", obp->name); return (0); } if (!strcmp (tagXMLEle(root), "setLightVector") || !strcmp (tagXMLEle(root), "defLightVector")) { static IPState *states; static char **names; static int maxn; /* seed for reallocs */ if (!states) { states = (IPState *) malloc (sizeof(void*)); names = (char **) malloc (sizeof(void*)); } /* pull out each name/state pair */ for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) { if (strstr(tagXMLEle(epx), "Light")) { XMLAtt *na = findXMLAtt (epx, "name"); if (na) { if (n >= maxn) { int newsz = (maxn=n+1)*sizeof(IPState); states = (IPState *) realloc(states, newsz); newsz = maxn*sizeof(char *); names = (char **) realloc (names, newsz); } if (crackPropertyState(pcdataXMLEle(epx)) != -1) { states[n] = crackPropertyState(pcdataXMLEle(epx)); names[n] = valuXMLAtt(na); n++; } } else { IDLog ("%s: invalid state: %s\n", obp->name, pcdataXMLEle(epx)); exit(1); } } } /* invoke driver if something to do, but not an error if not */ if (n > 0) obp->fp(obp->dev, obp->name, state, states, names, n); else IDLog("%s: LightVector with no valid members", obp->name); return (0); } return (-1); } /* End if */ } /* End For */ return (-1); } int crackObserverState(char *stateStr) { if (!strcmp(stateStr, "Value")) return (IDT_VALUE); else if (!strcmp(stateStr, "State")) return (IDT_STATE); else if (!strcmp(stateStr, "All")) return (IDT_ALL); else return -1; } int crackPropertyState(char *pstateStr) { if (!strcmp(pstateStr, "Idle")) return IPS_IDLE; else if (!strcmp(pstateStr, "Ok")) return IPS_OK; else if (!strcmp(pstateStr, "Busy")) return IPS_BUSY; else if (!strcmp(pstateStr, "Alert")) return IPS_ALERT; else return -1; } indi-0.5/src/indiserver.c0000644000175000017500000011106610610533463013224 0ustar jrjr/* INDI Server. * Copyright (C) 2006 Elwood C. Downey ecdowney@clearskyinstitute.com This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * argv lists names of Driver programs to run or sockets to connect for Devices. * Drivers are restarted if they exit up to 4 times, sockets are not reopened. * Each Driver's stdin/out are assumed to provide INDI traffic and are connected * here via pipes. Drivers' stderr are connected to our stderr. * We only support Drivers that advertise support for one Device. The problem * with multiple Devices in one Driver is without a way to know what they * _all_ are there is no way to avoid sending all messages to all Drivers. * For efficiency, we want Client traffic to be restricted to only those * Devices for which they have queried via getProperties. * Similary, messages to Devices on sockets always include Device so * chained indiserver will only pass back info from that Device. * all newXXX() received from one Client are echoed to all other Clients who * have shown an interest in the same Device. * * Implementation notes: * * We fork each driver and open a server socket listening for INDI clients. * Then forever we listen for new clients and pass traffic between clients and * drivers, subject to optimizations based on sniffing getProperties messages. * Whereas it is often the case that a message from a driver will be sent to * more than one client, to avoid starving fast clients able to read quickly * while waiting for messages to drain to slow clients, each client message * is put on a queue for each interested client with a count of consumers. * Similarly, even though it is more rare for a message to be sent to more * than one driver, we still want to avoid blocking on a driver slow to * consume its message so driver messages are also queued in like fashion to * clients. Note that the same messages can be destined for both clients and * devices (for example, new* messages from clients are sent to drivers and * echoed to clients) it is allowed for one message to be on both driver and * client queues. Once queued, select(2) is used to write only to clients and * drivers that are known ready to read or accept more traffic. A message is * freed once it is no longer in use by clients or drivers. * * TODO: * Writing large BLOBs is sufficiently likely to dominate we should fork a new * process each time we write one to a client. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "lilxml.h" #include "indiapi.h" #include "fq.h" /* Observers */ #include "observer.h" #define INDIPORT 7624 /* TCP/IP port on which to listen */ #define BUFSZ 2048 /* max buffering here */ #define MAXDRS 4 /* default times to restart a driver */ #define NOPID (-1234) /* invalid PID to flag remote drivers */ /* name of a device a client is interested in */ typedef char IDev[MAXINDIDEVICE]; /* handy array of char */ /* BLOB handling, NEVER is the default */ typedef enum {B_NEVER=0, B_ALSO, B_ONLY} BLOBHandling; /* associate a usage count with an XMLEle message */ typedef struct { XMLEle *ep; /* a message */ int count; /* number of consumers left */ } Msg; /* info for each connected client */ typedef struct { int active; /* 1 when this record is in use */ int s; /* socket for this client */ FILE *wfp; /* FILE to write to s */ BLOBHandling blob; /* when to send setBLOBs */ LilXML *lp; /* XML parsing context */ FQ *msgq; /* Msg queue */ IDev *devs; /* malloced array of devices we want */ int ndevs; /* n entries in devs[] */ int sawGetProperties; /* mark when see getProperties */ } ClInfo; static ClInfo *clinfo; /* malloced array of clients */ static int nclinfo; /* n total (not active) */ /* info for each connected driver */ typedef struct { char *name; /* malloced process path name */ IDev dev; /* device served by this driver */ int pid; /* process id or NOPID if remote */ int rfd; /* read pipe fd */ int wfd; /* write pipe fd */ FILE *wfp; /* write pipe fp */ int restarts; /* times process has been restarted */ LilXML *lp; /* XML parsing context */ FQ *msgq; /* Msg queue */ } DvrInfo; static DvrInfo *dvrinfo; /* malloced array of drivers */ static int ndvrinfo; /* n total */ /******************************************************* JM: Observer Extension Start ******************************************************/ typedef struct { int in_use; char dev[MAXINDIDEVICE]; char name[MAXINDINAME]; IDType type; IPState last_state; DvrInfo *dp; } ObserverInfo; static ObserverInfo* observerinfo; /* malloced array of drivers */ static int nobserverinfo; /* n total */ static int nobserverinfo_active; /* n total, active */ static Msg *q2Observers (DvrInfo *dp, XMLEle *root, char *dev, Msg *mp); static void manageObservers(DvrInfo *dp, XMLEle *root); static void alertObservers(DvrInfo *dp); /******************************************************/ /***************** Observer End ***********************/ /******************************************************/ static void usage (void); static void noZombies (void); static void noSIGPIPE (void); static void indiRun (void); static void indiListen (void); static void newClient (void); static int newClSocket (void); static void shutdownClient (ClInfo *cp); static void readFromClient (ClInfo *cp); static void startDvr (DvrInfo *dp); static void startLocalDvr (DvrInfo *dp); static void startRemoteDvr (DvrInfo *dp); static int openINDIServer (char host[], int indi_port); static void restartDvr (DvrInfo *dp); static Msg *q2Drivers (XMLEle *root, char *dev, Msg *mp); static Msg * q2Clients (ClInfo *notme, XMLEle *root, char *dev, Msg *mp); static void addClDevice (ClInfo *cp, char *dev); static int findClDevice (ClInfo *cp, char *dev); static void readFromDriver (DvrInfo *dp); static void freeMsg (Msg *mp); static void sendClientMsg (ClInfo *cp); static void sendDriverMsg (DvrInfo *cp); static BLOBHandling crackBLOB (char enableBLOB[]); static void logMsg (XMLEle *root); static char *me; /* our name */ static int port = INDIPORT; /* public INDI port */ static int maxdrs = MAXDRS; /* max times to restart dieing driver */ static int verbose; /* chattiness */ static int lsocket; /* listen socket */ int main (int ac, char *av[]) { /* save our name */ me = av[0]; /* crack args */ while ((--ac > 0) && ((*++av)[0] == '-')) { char *s; for (s = av[0]+1; *s != '\0'; s++) switch (*s) { case 'p': if (ac < 2) usage(); port = atoi(*++av); ac--; break; case 'r': if (ac < 2) usage(); maxdrs = atoi(*++av); ac--; break; case 'v': verbose++; break; default: usage(); } } /* at this point there are ac args in av[] to name our drivers */ if (ac == 0) usage(); /* take care of some unixisms */ noZombies(); noSIGPIPE(); /* seed for realloc */ clinfo = (ClInfo *) malloc (1); nclinfo = 0; /* create driver info array all at once so size never has to change */ ndvrinfo = ac; dvrinfo = (DvrInfo *) malloc (ndvrinfo * sizeof(DvrInfo)); memset (dvrinfo, 0, ndvrinfo * sizeof(DvrInfo)); /* start each driver, malloc name once and keep it */ while (ac-- > 0) { dvrinfo[ac].name = strcpy (malloc(strlen(*av)+1), *av); startDvr (&dvrinfo[ac]); av++; } /* announce we are online */ indiListen(); /* handle new clients and all io */ while (1) indiRun(); /* whoa! */ fprintf (stderr, "%s: unexpected return from main\n", me); return (1); } /* print usage message and exit (1) */ static void usage(void) { fprintf (stderr, "Usage: %s [options] driver [driver ...]\n", me); fprintf (stderr, "%s\n", "$Revision: 631881 $"); fprintf (stderr, "Purpose: INDI Server\n"); fprintf (stderr, "Options:\n"); fprintf (stderr, " -p p : alternate IP port, default %d\n", INDIPORT); fprintf (stderr, " -r n : max driver restarts, default %d\n", MAXDRS); fprintf (stderr, " -v : show connects/disconnects, no traffic\n"); fprintf (stderr, " -vv : -v + key message content\n"); fprintf (stderr, " -vvv : -vv + complete xml\n"); fprintf (stderr, "driver : program or device@host[:port]\n"); exit (1); } /* arrange for no zombies if drivers die */ static void noZombies() { #ifndef _WIN32 struct sigaction sa; sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); #ifdef SA_NOCLDWAIT sa.sa_flags = SA_NOCLDWAIT; #else sa.sa_flags = 0; #endif (void)sigaction(SIGCHLD, &sa, NULL); #endif } /* turn off SIGPIPE on bad write so we can handle it inline */ static void noSIGPIPE() { #ifndef _WIN32 struct sigaction sa; sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); (void)sigaction(SIGPIPE, &sa, NULL); #endif } /* start the INDI driver process or connection usingthe given DvrInfo slot. * exit if trouble. */ static void startDvr (DvrInfo *dp) { if (strchr (dp->name, '@')) startRemoteDvr (dp); else startLocalDvr (dp); } /* start the INDI driver process using the given DvrInfo slot. * exit if trouble. */ static void startLocalDvr (DvrInfo *dp) { int rp[2], wp[2]; int pid; /* build two pipes for r and w */ if (pipe (rp) < 0) { fprintf (stderr, "%s: read pipe: %s\n", me, strerror(errno)); exit(1); } if (pipe (wp) < 0) { fprintf (stderr, "%s: write pipe: %s\n", me, strerror(errno)); exit(1); } /* fork&exec new process */ pid = fork(); if (pid < 0) { fprintf (stderr, "%s: fork: %s\n", me, strerror(errno)); exit(1); } if (pid == 0) { /* child: exec name */ int fd; /* rig up pipes as stdin/out; stderr stays, everything else goes */ dup2 (wp[0], 0); dup2 (rp[1], 1); for (fd = 3; fd < 100; fd++) (void) close (fd); /* go -- should never return */ execlp (dp->name, dp->name, NULL); fprintf (stderr, "Driver %s: %s\n", dp->name, strerror(errno)); _exit (1); /* parent will notice EOF shortly */ } /* don't need child's side of pipes */ close (rp[1]); close (wp[0]); /* record pid, io channel, init lp */ dp->pid = pid; dp->rfd = rp[0]; dp->wfd = wp[1]; dp->wfp = fdopen (dp->wfd, "a"); dp->lp = newLilXML(); dp->msgq = newFQ(1); if (verbose > 0) fprintf (stderr, "Driver %s: rfd=%d wfd=%d\n", dp->name, dp->rfd, dp->wfd); } /* start the remote INDI driver connection using the given DvrInfo slot. * exit if trouble. */ static void startRemoteDvr (DvrInfo *dp) { char dev[1024]; char host[1024]; int indi_port, sockfd; /* extract host and port */ indi_port = INDIPORT; if (sscanf (dp->name, "%[^@]@%[^:]:%d", dev, host, &indi_port) < 2) { fprintf (stderr, "Bad remote device syntax: %s\n", dp->name); exit(1); } /* connect */ sockfd = openINDIServer (host, indi_port); /* record fake pid, io channel, init lp */ dp->pid = NOPID; dp->rfd = sockfd; dp->wfd = sockfd; dp->wfp = fdopen (sockfd, "a"); dp->lp = newLilXML(); dp->msgq = newFQ(1); /* N.B. storing name now is key to limiting remote traffic to this dev*/ strncpy (dp->dev, dev, sizeof(IDev)-1); dp->dev[sizeof(IDev)-1] = '\0'; if (verbose > 0) fprintf (stderr, "Driver %s: socket=%d\n", dp->name, sockfd); } /* open a connection to the given host and port or die. * return socket fd. */ static int openINDIServer (char host[], int indi_port) { struct sockaddr_in serv_addr; struct hostent *hp; int sockfd; /* lookup host address */ hp = gethostbyname (host); if (!hp) { fprintf (stderr, "gethostbyname(%s): %s\n", host, strerror(errno)); exit (1); } /* create a socket to the INDI server */ (void) memset ((char *)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr_list[0]))->s_addr; serv_addr.sin_port = htons(indi_port); if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { fprintf (stderr, "socket(%s,%d): %s\n", host, indi_port,strerror(errno)); exit(1); } /* connect */ if (connect (sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0){ fprintf (stderr, "connect(%s,%d): %s\n", host,indi_port,strerror(errno)); exit(1); } /* ok */ return (sockfd); } /* create the public INDI Driver endpoint lsocket on port. * return server socket else exit. */ static void indiListen () { struct sockaddr_in serv_socket; int sfd; int reuse = 1; /* make socket endpoint */ if ((sfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { fprintf (stderr, "%s: socket: %s", me, strerror(errno)); exit(1); } /* bind to given port for any IP address */ memset (&serv_socket, 0, sizeof(serv_socket)); serv_socket.sin_family = AF_INET; #ifdef SSH_TUNNEL serv_socket.sin_addr.s_addr = htonl (INADDR_LOOPBACK); #else serv_socket.sin_addr.s_addr = htonl (INADDR_ANY); #endif serv_socket.sin_port = htons ((unsigned short)port); if (setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) < 0){ fprintf (stderr, "%s: setsockopt: %s", me, strerror(errno)); exit(1); } if (bind(sfd,(struct sockaddr*)&serv_socket,sizeof(serv_socket)) < 0){ fprintf (stderr, "%s: bind: %s", me, strerror(errno)); exit(1); } /* willing to accept connections with a backlog of 5 pending */ if (listen (sfd, 5) < 0) { fprintf (stderr, "%s: listen: %s", me, strerror(errno)); exit(1); } /* ok */ lsocket = sfd; if (verbose > 0) fprintf (stderr, "%s: listening to port %d on fd %d\n",me,port,sfd); } /* service traffic from clients and drivers */ static void indiRun(void) { fd_set rs, ws; int maxfd; int i, s; /* init with no writers or readers */ FD_ZERO(&ws); FD_ZERO(&rs); /* always listen for new clients */ FD_SET(lsocket, &rs); maxfd = lsocket; /* add all client readers and pending client writers */ for (i = 0; i < nclinfo; i++) { ClInfo *cp = &clinfo[i]; if (cp->active) { FD_SET(cp->s, &rs); if (nFQ(cp->msgq) > 0) FD_SET(cp->s, &ws); if (cp->s > maxfd) maxfd = cp->s; } } /* add all driver readers and pending driver writers */ for (i = 0; i < ndvrinfo; i++) { DvrInfo *dp = &dvrinfo[i]; FD_SET(dp->rfd, &rs); if (dp->rfd > maxfd) maxfd = dp->rfd; if (nFQ(dp->msgq) > 0) { FD_SET(dp->wfd, &ws); if (dp->wfd > maxfd) maxfd = dp->wfd; } } /* wait for action */ s = select (maxfd+1, &rs, &ws, NULL, NULL); if (s < 0) { fprintf (stderr, "%s: select(%d): %s\n",me,maxfd+1,strerror(errno)); exit(1); } /* new client? */ if (s > 0 && FD_ISSET(lsocket, &rs)) { newClient(); s--; } /* message to/from client? */ for (i = 0; s > 0 && i < nclinfo; i++) { ClInfo *cp = &clinfo[i]; if (cp->active) { if (FD_ISSET(cp->s, &rs)) { readFromClient(cp); s--; } } if (cp->active) { /* read might have shut it down */ if (FD_ISSET(cp->s, &ws)) { sendClientMsg(cp); s--; } } } /* message to/from driver? */ for (i = 0; s > 0 && i < ndvrinfo; i++) { DvrInfo *dp = &dvrinfo[i]; if (FD_ISSET(dp->rfd, &rs)) { readFromDriver(dp); s--; } if (FD_ISSET(dp->wfd, &ws) && nFQ(dp->msgq) > 0) { sendDriverMsg(dp); s--; } } } /* prepare for new client arriving on lsocket. * exit if trouble. */ static void newClient() { ClInfo *cp; int s, cli; /* assign new socket */ s = newClSocket (); /* try to reuse a clinfo slot, else add one */ for (cli = 0; cli < nclinfo; cli++) if (!(cp = &clinfo[cli])->active) break; if (cli == nclinfo) { /* grow clinfo */ clinfo = (ClInfo *) realloc (clinfo, (nclinfo+1)*sizeof(ClInfo)); if (!clinfo) { fprintf (stderr, "%s: no memory for new client\n", me); exit(1); } cp = &clinfo[nclinfo++]; } /* rig up new clinfo entry */ memset (cp, 0, sizeof(*cp)); cp->active = 1; cp->s = s; cp->lp = newLilXML(); cp->msgq = newFQ(1); cp->devs = malloc (1); cp->wfp = fdopen (cp->s, "a"); if (verbose > 0) fprintf (stderr, "Client %d: new arrival - welcome!\n", cp->s); } /* read more from the given client, send to each appropriate driver when see * xml closure. also send all newXXX() to all other interested clients. * shut down client if any trouble. */ static void readFromClient (ClInfo *cp) { char buf[BUFSZ]; int i, nr; /* read client */ nr = read (cp->s, buf, sizeof(buf)); if (nr <= 0) { if (nr < 0) fprintf (stderr, "Client %d: read: %s\n",cp->s,strerror(errno)); else if (verbose > 0) fprintf (stderr, "Client %d: read EOF\n", cp->s); shutdownClient (cp); return; } /* process XML, sending when find closure */ for (i = 0; i < nr; i++) { char err[1024]; XMLEle *root = readXMLEle (cp->lp, buf[i], err); if (root) { char *roottag = tagXMLEle(root); char *dev = findXMLAttValu (root, "device"); Msg *mp; if (verbose > 1) { fprintf (stderr, "Client %d: read ", cp->s); logMsg (root); } /* snag enableBLOB */ if (!strcmp (roottag, "enableBLOB")) cp->blob = crackBLOB (pcdataXMLEle(root)); /* snag interested devices */ if (!strcmp (roottag, "getProperties")) { addClDevice (cp, dev); cp->sawGetProperties = 1; } /* send message to all interested observers for dev */ mp = q2Observers(NULL, root, dev, NULL); /* send message to driver(s) responsible for dev */ mp = q2Drivers (root, dev, mp); /* echo new* commands back to other clients */ if (!strncmp (roottag, "new", 3)) q2Clients (cp, root, dev, mp); /* N.B. delXMLele(root) called when root no longer in any q */ } else if (err[0]) fprintf (stderr, "Client %d: %s\n", cp->s, err); } } /* read more from the given driver, send to each interested client when see * xml closure. if driver dies, try to restarting up to MAXDRS times. */ static void readFromDriver (DvrInfo *dp) { char buf[BUFSZ]; int i, nr; Msg *mp=NULL; /* read driver */ nr = read (dp->rfd, buf, sizeof(buf)); if (nr <= 0) { if (nr < 0) fprintf (stderr, "Driver %s: %s\n", dp->name, strerror(errno)); else fprintf (stderr, "Driver %s: died, or failed to start\n", dp->name); restartDvr (dp); return; } /* process XML, sending when find closure */ for (i = 0; i < nr; i++) { char err[1024]; XMLEle *root = readXMLEle (dp->lp, buf[i], err); if (root) { char *dev = findXMLAttValu (root, "device"); if (verbose > 1) { fprintf(stderr, "Driver %s: read ", dp->name); logMsg (root); } /* snag device name if not known yet */ if (!dp->dev[0] && dev[0]) { strncpy (dp->dev, dev, sizeof(IDev)-1); dp->dev[sizeof(IDev)-1] = '\0'; } /* send to interested observers */ mp = q2Observers (dp, root, dev, NULL); /* send to interested clients */ q2Clients (NULL, root, dev, mp); /* N.B. delXMLele(root) called when root no longer in any q */ } else if (err[0]) fprintf (stderr, "Driver %s: %s\n", dp->name, err); } } /* close down the given client */ static void shutdownClient (ClInfo *cp) { Msg *mp; /* close connection */ #ifndef _WIN32 shutdown (cp->s, SHUT_RDWR); #endif fclose (cp->wfp); /* also closes cp->s */ cp->wfp = 0; /* free memory */ delLilXML (cp->lp); free (cp->devs); cp->devs = 0; /* decrement and possibly free any unsent messages for this client */ while ((mp = (Msg*) popFQ(cp->msgq)) != NULL) if (--mp->count == 0) freeMsg (mp); delFQ (cp->msgq); /* ok now to recycle */ cp->active = 0; if (verbose > 0) fprintf (stderr, "Client %d: shut down complete - bye!\n", cp->s); } /* close down the given driver and restart if not too many already */ static void restartDvr (DvrInfo *dp) { #ifndef _WIN32 /* JM: Alert observers */ alertObservers(dp); /* make sure it's dead, reclaim resources */ if (dp->pid == NOPID) { /* socket connection */ shutdown (dp->wfd, SHUT_RDWR); fclose (dp->wfp); /* also closes wfd */ } else { /* local pipe connection */ kill (dp->pid, SIGKILL); /* we've insured there are no zombies */ fclose (dp->wfp); /* also closes wfd */ close (dp->rfd); } #endif delLilXML (dp->lp); delFQ (dp->msgq); /* restart unless too many already */ if (++dp->restarts > maxdrs) { fprintf (stderr, "Driver %s: still dead after %d restarts\n", dp->name, maxdrs); exit(1); } fprintf (stderr, "Driver %s: restart #%d\n", dp->name, dp->restarts); startDvr (dp); } /* queue the xml command in root to each driver supporting device dev, or all * drivers if unknown. * add more count to mp if not NULL, else make a fresh Msg here. * return the Msg we create in case we want to add it to more queues. We may * return NULL if there were no drivers interested in root msg. */ static Msg * q2Drivers (XMLEle *root, char *dev, Msg *mp) { DvrInfo *dp; if (!mp) { /* build a new message */ mp = (Msg *) malloc (sizeof(Msg)); mp->ep = root; mp->count = 0; } /* queue message to each interested driver */ for (dp = dvrinfo; dp < &dvrinfo[ndvrinfo]; dp++) { int adddev = 0; if (dev[0]) { /* skip unless we know driver supports this device */ if (dp->dev[0] && strcmp (dev, dp->dev)) continue; } else { /* add dev to message if known from driver. * N.B. this is key to limiting remote traffic to this dev */ if (dp->dev[0]) { addXMLAtt (root, "device", dp->dev); adddev = 1; } } /* ok: queue message to given driver */ mp->count++; pushFQ (dp->msgq, mp); if (verbose > 2) fprintf (stderr,"Driver %s: message %d queued with count %d\n", dp->name, nFQ(dp->msgq), mp->count); if (adddev) rmXMLAtt (root, "device"); } /* forget it if no drivers wanted the message */ if (mp->count == 0) { if (verbose > 2) { fprintf (stderr, "no drivers want "); logMsg (root); } freeMsg (mp); mp = NULL; } /* return mp in case someone else wants to add to it */ return (mp); } /* queue the xml command in root known to be from the given device to each * interested client, except notme. * add more count to mp if not NULL, else make a fresh Msg here. * return the Msg we create in case we want to add it to more queues. We may * return NULL if there were no clients interested in root msg. */ static Msg * q2Clients (ClInfo *notme, XMLEle *root, char *dev, Msg *mp) { ClInfo *cp; /* Ignore subscribtion requests, don't send them to clients if (!strcmp(tagXMLEle(root), "propertyVectorSubscribtion")) return NULL; */ if (!mp) { /* build a new message */ mp = (Msg *) malloc (sizeof(Msg)); mp->ep = root; mp->count = 0; } /* queue message to each interested client */ for (cp = clinfo; cp < &clinfo[nclinfo]; cp++) { int isblob; /* cp in use? notme? valid dev? blob? */ if (!cp->active || cp == notme) continue; if (findClDevice (cp, dev) < 0) continue; isblob = !strcmp (tagXMLEle(root), "setBLOBVector"); if ((isblob && cp->blob==B_NEVER) || (!isblob && cp->blob==B_ONLY)) continue; /* ok: queue message to given client */ mp->count++; pushFQ (cp->msgq, mp); if (verbose > 2) fprintf (stderr,"Client %d: message %d queued with count %d\n", cp->s, nFQ(cp->msgq), mp->count); } /* forget it if no clients wanted the message */ if (mp->count == 0) { if (verbose > 2) { fprintf (stderr, "no clients want "); logMsg (root); } freeMsg (mp); mp = NULL; } /* return mp in case someone else wants to add to it */ return (mp); } Msg * q2Observers (DvrInfo *sender, XMLEle *root, char *dev, Msg *mp) { ObserverInfo *ob; XMLAtt* ap; int prop_state = 0; char prop_name[MAXINDINAME]; if (dev == NULL) return mp; if (sender == NULL) { // If we don't have observers, or the message is newXXX, discard. if (nobserverinfo_active == 0 || strstr(tagXMLEle(root), "new")) return mp; /* if message from a client (and not a driver), then let's first make sure we have an observer with it before wasting any resources decoding the xml message */ for (ob = observerinfo; ob < &observerinfo[nobserverinfo]; ob++) { if (!strcmp(ob->dev, dev)) break; } /* If no observers interested, return */ if (ob == &observerinfo[nobserverinfo]) return mp; } /* Subscribtion request */ if (!strcmp(tagXMLEle(root), "propertyVectorSubscribtion")) { manageObservers(sender, root); return mp; } /* We discard messages */ else if (!strcmp(tagXMLEle(root), "message")) return mp; /* if We have no observers, return */ if (nobserverinfo_active == 0) return mp; /* Del prop might not have name, so don't panic */ ap = findXMLAtt(root, "name"); if (!ap && strcmp(tagXMLEle(root), "delProperty")) { fprintf(stderr, "<%s> missing 'name' attribute.\n", tagXMLEle(root)); return mp; } else if (ap) strncpy(prop_name, valuXMLAtt(ap), MAXINDINAME); /* Del prop does not have state, so don't panic */ ap = findXMLAtt(root, "state"); if (!ap && strcmp(tagXMLEle(root), "delProperty")) { fprintf(stderr, "<%s> missing 'state' attribute.\n", tagXMLEle(root)); return mp; } else if (ap) { prop_state = crackPropertyState(valuXMLAtt(ap)); if (prop_state < 0) { fprintf(stderr, "<%s> invalid property state '%s'.\n", tagXMLEle(root), valuXMLAtt(ap)); return mp; } } if (!mp) { /* build a new message */ mp = (Msg *) malloc (sizeof(Msg)); mp->ep = root; mp->count = 0; } /* Now let's see if a registered observer is interested in this property */ for (ob = observerinfo; ob < &observerinfo[nobserverinfo]; ob++) { if (!ob->in_use) continue; if (!strcmp(ob->dev, dev) && ((!strcmp(tagXMLEle(root), "delProperty")) || (!strcmp(ob->name, prop_name)))) { /* Check for state requirtments only if property is of setXXXVector type defXXX and delXXX go through */ if (strstr(tagXMLEle(root), "set") && ob->type == IDT_STATE) { /* If state didn't change, there is no need to update observer */ if (ob->last_state == (unsigned) prop_state) { free(mp); return NULL; } /* Otherwise, record last state transition */ ob->last_state = prop_state; } /* ok: queue message to given driver */ mp->count++; pushFQ (ob->dp->msgq, mp); if (verbose > 2) fprintf (stderr,"Driver %s: message %d queued with count %d\n", ob->dp->name, nFQ(ob->dp->msgq), mp->count); break; } } /* Return mp if anyone else want to use it */ return mp; } void manageObservers (DvrInfo *dp, XMLEle *root) { char ob_dev[MAXINDIDEVICE]; char ob_name[MAXINDINAME]; int ob_type = 0; XMLAtt* ap; ObserverInfo* ob; DvrInfo *observed; Msg *mp; char xmlAlertStr[BUFSZ]; char errmsg[BUFSZ]; XMLEle* xmlAlert = NULL; unsigned int i=0; if (dp == NULL || root == NULL) return; snprintf(xmlAlertStr, BUFSZ, "", INDIV); for (i=0; i < strlen(xmlAlertStr); i++) { xmlAlert = readXMLEle(dp->lp, xmlAlertStr[i], errmsg); if (xmlAlert) break; } /* Shouldn't happen! */ if (!xmlAlert) return; /* build a new message */ mp = (Msg *) malloc (sizeof(Msg)); mp->ep = xmlAlert; mp->count = 0; ap = findXMLAtt(root, "device"); if (!ap) { fprintf(stderr, "<%s> missing 'device' attribute.\n", tagXMLEle(root)); freeMsg(mp); return; } strncpy(ob_dev, valuXMLAtt(ap), MAXINDIDEVICE); ap = findXMLAtt(root, "name"); if (!ap) { fprintf(stderr, "<%s> missing 'name' attribute.\n", tagXMLEle(root)); freeMsg(mp); return; } strncpy(ob_name, valuXMLAtt(ap), MAXINDINAME); ap = findXMLAtt(root, "notification"); if (ap) { ob_type = crackObserverState(valuXMLAtt(ap)); if (ob_type < 0) { fprintf(stderr, "<%s> invalid notification state '%s'.\n", tagXMLEle(root), valuXMLAtt(ap)); freeMsg(mp); return; } } ap = findXMLAtt(root, "action"); if (!ap) { fprintf(stderr, "<%s> missing 'action' attribute.\n", tagXMLEle(root)); freeMsg(mp); return; } /* Subscribe */ if (!strcmp(valuXMLAtt(ap), "subscribe")) { /* First check if it's already in the list. If found, silenty ignore. */ for (ob = observerinfo; ob < &observerinfo[nobserverinfo]; ob++) { if (ob->in_use && (ob->dp == dp) && !strcmp(ob->dev, ob_dev) && !strcmp(ob->name, ob_name) && (ob->type == (unsigned) ob_type)) { freeMsg(mp); return; } } /* Next check for the first avaiable slot to use */ for (ob = observerinfo; ob < &observerinfo[nobserverinfo]; ob++) { if (!ob->in_use) break; } /* If list if full, allocate more memory, or seed */ if (ob == &observerinfo[nobserverinfo]) { observerinfo = observerinfo ? (ObserverInfo *) realloc (observerinfo, (nobserverinfo+1)*sizeof(ObserverInfo)) : (ObserverInfo *) malloc (sizeof(ObserverInfo)); ob = &observerinfo[nobserverinfo++]; } /* init new entry */ ob->in_use = 1; ob->dp = dp; ob->type = ob_type; ob->last_state = -1; strncpy(ob->dev, ob_dev, MAXINDIDEVICE); strncpy(ob->name, ob_name, MAXINDINAME); nobserverinfo_active++; /* Tell driver to redefine its properties which shall update the observer with the current state/value of the observed property */ for (observed = dvrinfo; observed < &dvrinfo[ndvrinfo]; observed++) { if (!strcmp(ob->dev, observed->dev)) { mp->count++; pushFQ (observed->msgq, mp); break; } } if (verbose > 1) fprintf(stderr, "Added observer <%s> to listen to changes in %s.%s\n", dp->dev, ob->dev, ob->name); } else if (!strcmp(valuXMLAtt(ap), "unsubscribe")) { /* Search list, if found, set in_use to 0 */ for (ob = observerinfo; ob < &observerinfo[nobserverinfo]; ob++) { if ((ob->dp == dp) && !strcmp(ob->dev, ob_dev) && !strcmp(ob->name, ob_name)) { ob->in_use = 0; nobserverinfo_active--; if (verbose > 1) fprintf(stderr, "Removed observer <%s> which was listening to changes in %s.%s\n", dp->dev, ob->dev, ob->name); break; } } } else { fprintf(stderr, "<%s> invalid action value: %s\n", tagXMLEle(root), valuXMLAtt(ap)); } if (!mp->count) /* not added anywhere */ freeMsg(mp); } /* free Msg mp and everything it contains */ static void freeMsg (Msg *mp) { delXMLEle (mp->ep); free (mp); } static void alertObservers(DvrInfo *dp) { ObserverInfo* ob; Msg *mp; char xmlAlertStr[BUFSZ]; char errmsg[BUFSZ]; XMLEle* xmlAlert = NULL; unsigned int i=0; snprintf(xmlAlertStr, BUFSZ, "", dp->dev); for (i=0; i < strlen(xmlAlertStr); i++) { xmlAlert = readXMLEle(dp->lp, xmlAlertStr[i], errmsg); if (xmlAlert) break; } /* Shouldn't happen! */ if (!xmlAlert) return; /* build a new message */ mp = (Msg *) malloc (sizeof(Msg)); mp->ep = xmlAlert; mp->count = 0; /* Check if any observers are listening to this driver */ for (ob = observerinfo; ob < &observerinfo[nobserverinfo]; ob++) { if (!strcmp(ob->dev,dp->dev)) { mp->count++; pushFQ (ob->dp->msgq, mp); if (verbose > 2) fprintf (stderr,"Driver %s: message %d queued with count %d\n", ob->dp->name, nFQ(ob->dp->msgq), mp->count); } } if (!mp->count) /* not added anywhere */ freeMsg(mp); } /* write the next message in the queue for the given client. * free the message if we are the last client to use it. * shut down this client if trouble. */ static void sendClientMsg (ClInfo *cp) { Msg *mp; if (!cp->active) return; /* get next message for this client */ mp = popFQ (cp->msgq); /* send it */ prXMLEle (cp->wfp, mp->ep, 0); fflush (cp->wfp); /* trace */ if (verbose > 2) { fprintf (stderr, "Client %d: send msg %d:\n", cp->s, nFQ(cp->msgq)); prXMLEle (stderr, mp->ep, 0); } else if (verbose > 1) { fprintf (stderr, "Client %d: sent msg %d ", cp->s, nFQ(cp->msgq)); logMsg (mp->ep); } /* update message usage count, free if goes to 0 */ if (--mp->count == 0) { if (verbose > 2) fprintf (stderr, "Client %d: last client, freeing msg\n",cp->s); freeMsg (mp); } /* shut down this client if encountered write errors */ if (ferror(cp->wfp)) { fprintf (stderr, "Client %d: write: %s\n", cp->s, strerror(errno)); shutdownClient (cp); } } /* write the next message in the queue for the given driver. * free the message if we are the last driver to use it. * restart this driver if trouble. */ static void sendDriverMsg (DvrInfo *dp) { Msg *mp; /* get next message for this driver */ mp = popFQ (dp->msgq); /* send it */ prXMLEle (dp->wfp, mp->ep, 0); fflush (dp->wfp); /* trace */ if (verbose > 2) { fprintf (stderr,"Driver %s: send msg %d:\n",dp->name,nFQ(dp->msgq)); prXMLEle (stderr, mp->ep, 0); } else if (verbose > 1) { fprintf (stderr, "Driver %s: sent msg %d ", dp->name,nFQ(dp->msgq)); logMsg (mp->ep); } /* update message usage count, free if goes to 0 */ if (--mp->count == 0) { if (verbose > 2) fprintf (stderr, "Driver %s: last client, freeing msg\n", dp->name); freeMsg (mp); } /* restart this driver if encountered write errors */ if (ferror(dp->wfp)) { fprintf (stderr, "Driver %s: write: %s\n",dp->name,strerror(errno)); restartDvr (dp); } } /* return 0 if we have seen getProperties from this client and dev is in its * devs[] list or the list is empty or no dev specified, else return -1 */ static int findClDevice (ClInfo *cp, char *dev) { int i; if (!cp->sawGetProperties) return (-1); if (cp->ndevs == 0 || !dev[0]) return (0); for (i = 0; i < cp->ndevs; i++) if (!strncmp (dev, cp->devs[i], sizeof(IDev)-1)) return (0); return (-1); } /* add the given device to the devs[] list of client cp unless empty. */ static void addClDevice (ClInfo *cp, char *dev) { if (dev[0]) { char *ip; cp->devs = (IDev *) realloc (cp->devs,(cp->ndevs+1)*sizeof(IDev)); ip = (char*)&cp->devs[cp->ndevs++]; strncpy (ip, dev, sizeof(IDev)-1); ip[sizeof(IDev)-1] = '\0'; } } /* block to accept a new client arriving on lsocket. * return private nonblocking socket or exit. */ static int newClSocket () { struct sockaddr_in cli_socket; socklen_t cli_len; int cli_fd; /* get a private connection to new client */ cli_len = sizeof(cli_socket); cli_fd = accept (lsocket, (struct sockaddr *)&cli_socket, &cli_len); if(cli_fd < 0) { fprintf (stderr, "%s: accept: %s", me, strerror(errno)); exit (1); } /* ok */ return (cli_fd); } /* convert the string value of enableBLOB to our state value */ static BLOBHandling crackBLOB (char enableBLOB[]) { if (!strcmp (enableBLOB, "Also")) return (B_ALSO); if (!strcmp (enableBLOB, "Only")) return (B_ONLY); return (B_NEVER); } /* print key attributes and values of the given xml to stderr. */ static void logMsg (XMLEle *root) { static char *prtags[] = { "defNumber", "oneNumber", "defText", "oneText", "defSwitch", "oneSwitch", "defLight", "oneLight", }; XMLEle *e; char *msg, *perm; int i; /* print tag header */ fprintf (stderr, "%s %s %s %s", tagXMLEle(root), findXMLAttValu(root,"device"), findXMLAttValu(root,"name"), findXMLAttValu(root,"state")); perm = findXMLAttValu(root,"perm"); if (perm[0]) fprintf (stderr, " %s", perm); msg = findXMLAttValu(root,"message"); if (msg[0]) fprintf (stderr, " '%s'", msg); /* print each array value */ for (e = nextXMLEle(root,1); e; e = nextXMLEle(root,0)) for (i = 0; i < sizeof(prtags)/sizeof(prtags[0]); i++) if (strcmp (prtags[i], tagXMLEle(e)) == 0) fprintf (stderr, " %s='%s'", findXMLAttValu(e,"name"), pcdataXMLEle (e)); fprintf (stderr, "\n"); } int crackObserverState(char *stateStr) { if (!strcmp(stateStr, "Value")) return (IDT_VALUE); else if (!strcmp(stateStr, "State")) return (IDT_STATE); else if (!strcmp(stateStr, "All")) return (IDT_ALL); else return -1; } int crackPropertyState(char *pstateStr) { if (!strcmp(pstateStr, "Idle")) return IPS_IDLE; else if (!strcmp(pstateStr, "Ok")) return IPS_OK; else if (!strcmp(pstateStr, "Busy")) return IPS_BUSY; else if (!strcmp(pstateStr, "Alert")) return IPS_ALERT; else return -1; } indi-0.5/src/orionatlas.cpp0000644000175000017500000006217210610474326013572 0ustar jrjr/* OrionAtlas (EQ-G/EQ-6 with SkyScan/SynScan controller) Copyright (C) 2005 Bruce Bockius (bruceb@WhiteAntelopeSoftware.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include "orionatlas.h" #define mydev "OrionAtlas" #define ATLAS_DEBUG 1 #define POLLMS 5000 #define lat geo[0].value #define lon geo[1].value OrionAtlas *telescope = NULL; /* There is _one_ binary for all LX200 drivers, but each binary is renamed ** to its device name (i.e. lx200gps, lx200_16..etc). The main function will ** fetch from std args the binary name and ISInit will create the apporpiate ** device afterwards. If the binary name does not match any known devices, ** we simply create a generic device */ extern char* me; #define COMM_GROUP "Communication" #define BASIC_GROUP "Main Control" #define SETUP_GROUP "Setup" #define ATLAS_MIN_RA 0.0 #define ATLAS_MAX_RA 24.0 #define ATLAS_MIN_DEC -90.0 #define ATLAS_MAX_DEC 90.0 #define ATLAS_MIN_AZ 0.0 #define ATLAS_MAX_AZ 360.0 #define ATLAS_MIN_ALT -90.0 #define ATLAS_MAX_ALT 90.0 static void ISPoll(void *); //static ISwitch abortSlewS[] = {{"ABORT", "Abort", ISS_OFF, 0, 0}}; /* Fundamental group */ static ISwitch PowerS[] = {{"CONNECT","Connect",ISS_OFF,0,0},{"DISCONNECT","Disconnect",ISS_ON,0,0},{"RECONNECT","Reconnect",ISS_OFF,0,0}}; static ISwitchVectorProperty PowerSw = { mydev, "CONNECTION" , "Connection", COMM_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_OK, PowerS, NARRAY(PowerS), "", 0}; static IText PortT[] = {{"PORT", "Port", 0, 0, 0, 0}}; static ITextVectorProperty Port = { mydev, "DEVICE_PORT", "Ports", COMM_GROUP, IP_RW, 0, IPS_OK, PortT, NARRAY(PortT), "", 0}; /* Movement group */ //static ISwitchVectorProperty abortSlewSw = { mydev, "ABORT_MOTION", "Abort Slew/Track", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, abortSlewS, NARRAY(abortSlewS), "", 0}; static INumber eq[] = { {"RA", "RA (hh:mm.m)", "%010.5m", ATLAS_MIN_RA, ATLAS_MAX_RA, 0., 0., 0, 0, 0}, {"DEC", "Dec (dd:mm.m)", "%010.5m", ATLAS_MIN_DEC, ATLAS_MAX_DEC, 0., 0., 0, 0, 0}}; // Azimuth/Altitude static INumber aa[] = { {"XAZ", "Az (ddd:mm.m)", "%010.5m", ATLAS_MIN_AZ, ATLAS_MAX_AZ, 0.0, 0.0, 0, 0, 0}, {"XALT", "Alt (dd:mm.m)", "%010.5m", ATLAS_MIN_ALT, ATLAS_MAX_ALT, 0.0, 0.0, 0, 0, 0}}; static INumberVectorProperty eqNum = { mydev, "EQUATORIAL_EOD_COORD", "Eq. Coordinates", BASIC_GROUP, IP_RW, 0, IPS_OK, eq, NARRAY(eq), "", 0}; static INumberVectorProperty aaNum = { mydev, "XHORIZONTAL_COORD", "Horz. Coordinates", BASIC_GROUP, IP_RW, 0, IPS_OK, aa, NARRAY(aa), "", 0}; static ISwitch OnCoordSetS[] = {{"TRACK", "Track", ISS_ON, 0, 0}}; // switch does nothing, but some clients won't let you track w/o it. static ISwitchVectorProperty OnCoordSetSw = { mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_OK, OnCoordSetS, NARRAY(OnCoordSetS), "", 0}; static ISwitch UpdateS[] = {{"UPDATE1", "On", ISS_ON, 0, 0},{"UPDATE0","Off", ISS_OFF,0,0}}; static ISwitch MovementRADecS[] = {{"XRAPLUS", "RA+", ISS_OFF, 0, 0}, {"XRAMINUS", "RA-", ISS_OFF, 0, 0}, {"XDECPLUS", "Dec+", ISS_OFF, 0, 0}, {"XDECMINUS", "Dec-", ISS_OFF, 0, 0}}; static ISwitch MovementAzAltS[] = {{"XAZPLUS", "Az+", ISS_OFF, 0, 0}, {"XAZMINUS", "Az-", ISS_OFF, 0, 0}, {"XALTPLUS", "Alt+", ISS_OFF, 0, 0}, {"XALTMINUS", "Alt-", ISS_OFF, 0, 0}}; static ISwitchVectorProperty MovementRADecSw = { mydev, "XRADECMOVEMENT", "Nudge", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_OK, MovementRADecS, NARRAY(MovementRADecS), "", 0}; static ISwitchVectorProperty MovementAzAltSw = { mydev, "XAZALTMOVEMENT", "Nudge", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_OK, MovementAzAltS, NARRAY(MovementAzAltS), "", 0}; static ISwitchVectorProperty UpdateSw = { mydev, "XUPDATE", "Update Coords", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_OK, UpdateS, NARRAY(UpdateS), "", 0}; /* Telescope Parameters group */ // Setup group static INumber steps[] = { {"XRASTEP", "RA Step", "%010.6m", 0.0, 5.0, 0.0, 0.0, 0, 0, 0}, {"XDECSTEP", "Dec Step", "%010.6m", 0.0, 5.0, 0.0, 0.0, 0, 0, 0}, {"XAZSTEP", "Az Step", "%010.6m", 0.0, 5.0, 0.0, 0.0, 0, 0, 0}, {"XALTSTEP", "Alt Step", "%010.6m", 0.0, 5.0, 0.0, 0.0, 0, 0, 0}}; // geographic position static INumber geo[] = { {"LAT", "Lat (dd:mm.m)", "%010.5m", -90.0, 90.0, 0.0, 0.0, 0, 0, 0}, {"LONG", "Lon (ddd:mm.m)", "%010.5m", -180.0, 360.0, 0.0, 0.0, 0, 0, 0}}; static INumberVectorProperty geoNum = { mydev, "GEOGRAPHIC_COORD", "Scope Location", SETUP_GROUP, IP_RW, 0, IPS_OK, geo, NARRAY(geo), "", 0}; static INumberVectorProperty stepNum = { mydev, "XSTEPS", "Nudge Steps", SETUP_GROUP, IP_RW, 0, IPS_OK, steps, NARRAY(steps), "", 0}; /* send client definitions of all properties */ void ISInit() { static int isInit=0; if (isInit) return; isInit = 1; PortT[0].text = strcpy(new char[32], "/dev/ttyUSB0"); steps[0].value=1.0/60.0; steps[1].value=1.0/60.0; steps[2].value=1.0/60.0; steps[3].value=1.0/60.0; telescope = new OrionAtlas(); IEAddTimer (POLLMS, ISPoll, NULL); } void ISGetProperties (const char *dev) { ISInit(); telescope->ISGetProperties(dev);} void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { ISInit(); telescope->ISNewSwitch(dev, name, states, names, n);} void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { ISInit(); telescope->ISNewText(dev, name, texts, names, n);} void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { ISInit(); telescope->ISNewNumber(dev, name, values, names, n);} void ISPoll (void *p) { telescope->ISPoll(); IEAddTimer (POLLMS, ISPoll, NULL); p=p;} void ISNewBLOB (const char */*dev*/, const char */*name*/, int */*sizes[]*/, char **/*blobs[]*/, char **/*formats[]*/, char **/*names[]*/, int /*n*/) {} OrionAtlas::OrionAtlas() { geo[0].value=0; geo[1].value=0; lat=lon=-1000; TelConnectFlag=0; Updating=true; // Children call parent routines, this is the default IDLog("Initialized Orion Atlas EQ-G device, driver ver 0.101\n"); if (ATLAS_DEBUG) IDLog("Driver in DEBUG mode."); } void OrionAtlas::ISGetProperties(const char *dev) { if (dev && strcmp (mydev, dev)) return; // COMM_GROUP IDDefSwitch (&PowerSw, NULL); IDDefText (&Port, NULL); // BASIC_GROUP IDDefNumber (&eqNum, NULL); IDDefNumber (&aaNum, NULL); IDDefSwitch (&UpdateSw, NULL); // IDDefSwitch (&abortSlewSw, NULL); IDDefSwitch (&OnCoordSetSw,NULL); IDDefSwitch (&MovementRADecSw, NULL); IDDefSwitch (&MovementAzAltSw, NULL); // SETUP_GROUP IDDefNumber (&geoNum, NULL); IDDefNumber (&stepNum, NULL); /* Send the basic data to the new client if the previous client(s) are already connected. */ if (PowerSw.s == IPS_OK) { if (ATLAS_DEBUG) log("Initial call to getBasicData()\n"); getBasicData(); } } void OrionAtlas::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { IText *tp; // suppress warning n=n; // ignore if not ours // if (strcmp (dev, mydev)) return; if (!strcmp(name, Port.name) ) { Port.s = IPS_OK; tp = IUFindText( &Port, names[0] ); if (!tp) return; tp->text = new char[strlen(texts[0])+1]; strcpy(tp->text, texts[0]); IDSetText (&Port, NULL); return; } else { if (ATLAS_DEBUG) log("ISNewText('%s')\n",name); } } void OrionAtlas::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { double newRA=0, newDEC=0, newAlt=0, newAz=0; // ignore if not ours // if (strcmp (dev, mydev)) return; if (!strcmp (name, eqNum.name)) { int i=0, nset=0; if (checkPower(&eqNum)) return; for (nset = i = 0; i < n; i++) { INumber *eqp = IUFindNumber (&eqNum, names[i]); if (eqp == &eq[0]) { newRA = values[i]; nset += newRA >= 0 && newRA <= 24.0; } else if (eqp == &eq[1]) { newDEC = values[i]; nset += newDEC >= -90.0 && newDEC <= 90.0; } } if (nset==2) { // both coords were valid. Slew. MoveScope(RADEC,newRA,newDEC); } } else if (!strcmp(name, aaNum.name)) { int i=0, nset=0; if (checkPower(&eqNum)) return; for (nset = i = 0; i < n; i++) { INumber *aap = IUFindNumber (&aaNum, names[i]); if (aap == &aa[1]) { newAlt = values[i]; nset += newAlt >= -90.0 && newAlt <= 90.0; } else if (aap == &aa[0]) { newAz = values[i]; nset += newAz >= 0.0 && newAz <=360.0; } } if (nset==2) { // both coords were valid. Slew. MoveScope(AZALT,newAz,newAlt); } } else if (!strcmp(name, geoNum.name)) { if (ATLAS_DEBUG) log("NewNumber(geoName)\n"); int i=0; for (i=0;ivalue=values[i]; } IDSetNumber(&geoNum,NULL); } else if (!strcmp(name, stepNum.name)) { if (ATLAS_DEBUG) log("NewNumber(stepNum)\n"); for (int i=0;ivalue=values[i]; } IDSetNumber(&stepNum,NULL); } else { if (ATLAS_DEBUG) log("ISNewNumber('%s')\n",name); } } void OrionAtlas::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { int index; ISwitch *swp; // Suppress warning names = names; // ignore if not ours // if (strcmp(dev,mydev)) return; // FIRST Switch ALWAYS for power if (!strcmp(name,PowerSw.name)) { IUResetSwitches(&PowerSw); // sets all to off? IUUpdateSwitches(&PowerSw,states,names,n); if (PowerS[2].s == ISS_ON) { DisconnectTel(); } powerTelescope(); return; } else if (!strcmp(name,UpdateSw.name)) { IUResetSwitches(&UpdateSw); IUUpdateSwitches(&UpdateSw,states,names,n); IDSetSwitch(&UpdateSw,NULL); Updating=!Updating; } else if (!strcmp(name,MovementRADecSw.name)) { if (!GetCoords(RADEC)) { IDMessage(mydev,"Invalid coordinates from scope - aborted nudge."); } log("before RA=%f Dec=%f\n",returnRA,returnDec); for (int i=0; ilabel, "")) IDMessage (mydev, "Cannot change property %s while the telescope is offline.", sp->name); else IDMessage (mydev, "Cannot change property %s while the telescope is offline.", sp->label); sp->s = IPS_IDLE; IDSetSwitch(sp, NULL); return -1; } return 0; } int OrionAtlas::checkPower(INumberVectorProperty *np) { if (PowerSw.s != IPS_OK) { if (!strcmp(np->label, "")) IDMessage (mydev, "Cannot change property %s while the telescope is offline.", np->name); else IDMessage (mydev, "Cannot change property %s while the telescope is offline.", np->label); np->s = IPS_IDLE; IDSetNumber(np, NULL); return -1; } return 0; } int OrionAtlas::checkPower(ITextVectorProperty *tp) { if (PowerSw.s != IPS_OK) { if (!strcmp(tp->label, "")) IDMessage (mydev, "Cannot change property %s while the telescope is offline.", tp->name); else IDMessage (mydev, "Cannot change property %s while the telescope is offline.", tp->label); tp->s = IPS_IDLE; IDSetText(tp, NULL); return -1; } return 0; } void OrionAtlas::getBasicData() { if (ATLAS_DEBUG) log("getBasicData\n"); UpdateCoords(); } void OrionAtlas::powerTelescope() { if (PowerSw.sp[0].s==ISS_ON||PowerSw.sp[2].s==ISS_ON) { // CONNECT or RECONNECT if (ConnectTel(Port.tp[0].text) < 0) { PowerS[0].s = PowerS[2].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch (&PowerSw, "Error connecting to port %s", Port.tp[0].text); return; } PowerSw.s = IPS_OK; PowerS[0].s = ISS_ON; PowerS[1].s = PowerS[2].s= ISS_OFF; IDSetSwitch (&PowerSw, "Telescope is online. Updating coordinates."); if (ATLAS_DEBUG) log("Powered on scope, calling getBasicData()\n"); getBasicData(); } else if (PowerSw.sp[0].s==ISS_OFF) { IDSetSwitch (&PowerSw, "Telescope is offline."); DisconnectTel(); } } int OrionAtlas::CheckConnectTel(void) { return TelConnectFlag; } int OrionAtlas::ConnectTel(char *port) { struct termios tty; unsigned char returnStr[128]; int numRead; if (ATLAS_DEBUG) log( "Connecting to port: %s\n",port); if(TelConnectFlag != 0) return 0; /* Make the connection */ TelPortFD = open(port,O_RDWR); if(TelPortFD == -1) { IDMessage(mydev,"Could not open the supplied port!"); return -1; } tcgetattr(TelPortFD,&tty); cfsetospeed(&tty, (speed_t) B9600); cfsetispeed(&tty, (speed_t) B9600); tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; tty.c_iflag = IGNBRK; tty.c_lflag = 0; tty.c_oflag = 0; tty.c_cflag |= CLOCAL | CREAD; tty.c_cc[VMIN] = 1; tty.c_cc[VTIME] = 5; tty.c_iflag &= ~(IXON|IXOFF|IXANY); tty.c_cflag &= ~(PARENB | PARODD); tcsetattr(TelPortFD, TCSANOW, &tty); /* Flush the input (read) buffer */ tcflush(TelPortFD,TCIOFLUSH); /* Test connection */ writen(TelPortFD,(unsigned char*)"?",1); numRead=readn(TelPortFD,returnStr,1,2); returnStr[numRead] = '\0'; if (numRead == 1 && returnStr[0]=='#') { TelConnectFlag = 1; IDMessage(mydev,"Successfully connected."); return (0); } else if (numRead>0) { IDMessage(mydev,"Connect failure: Did not detect an Orion Atlas EQ-G on this port!"); return -2; } else { IDMessage(mydev,"Connect failure: Did not detect any device on this port!"); return -3; } } void OrionAtlas::DisconnectTel(void) { if(TelConnectFlag == 1) close(TelPortFD); TelConnectFlag = 0; IDMessage(mydev,"Telescope is offline."); } // If System=RADEC, c1=RA, c2=Dec // =AZALT, c1=Az, c2=Alt int OrionAtlas::MoveScope(int System, double c1, double c2) { MovementRADecSw.s=MovementAzAltSw.s=eqNum.s=aaNum.s=OnCoordSetSw.s=IPS_BUSY; IDSetSwitch(&MovementRADecSw,NULL); IDSetSwitch(&MovementAzAltSw,NULL); IDSetSwitch(&OnCoordSetSw,NULL); IDSetNumber(&eqNum,NULL); IDSetNumber(&aaNum,NULL); union { signed short int ints[2]; unsigned short int uints[2]; unsigned char bytes[4]; }; char Command=' '; while (1) { if (System==RADEC) Command='R'; else if (System==AZALT) Command='A'; else { log("Invalid command '%c' to MoveScope!",Command); break; } unsigned char sendStr[5]; writen(TelPortFD,(unsigned char*)"?",1); int numRead=readn(TelPortFD,sendStr,1,3); if (numRead!=1 || sendStr[0]!='#') { IDMessage(mydev,"Failure: Scope not ready for movement command!"); break; } if (Command=='R') { IDMessage(mydev,"Beginning slew to RA=%f Dec=%f\n",c1,c2); // RA: uints[0]=c1*65536.0/24.0; ints[1]=c2*65536.0/360.0; sendStr[2]=bytes[0]; sendStr[1]=bytes[1]; sendStr[4]=bytes[2]; sendStr[3]=bytes[3]; } else { //c2=c2-lat+90.0; // decorrect IDMessage(mydev,"Beginning slew to Az=%f Alt=%f\n",c1,c2); // Az uints[0]=c1*65536.0/360.0; ints[1]=c2*65536.0/360.0; sendStr[2]=bytes[0]; sendStr[1]=bytes[1]; sendStr[4]=bytes[2]; sendStr[3]=bytes[3]; } sendStr[0]=Command; if (ATLAS_DEBUG) log("Sending '%c' %X %X %X %X\n",Command,sendStr[1],sendStr[2],sendStr[3],sendStr[4]); writen(TelPortFD,sendStr,5); // it should send us an '@' when done slewing numRead=readn(TelPortFD,sendStr,1,60); if (numRead!=1||sendStr[0]!='@') { IDMessage(mydev,"Timeout waiting for scope to complete slewing."); break; } IDMessage(mydev,"Slewing complete."); MovementRADecSw.s=MovementAzAltSw.s=eqNum.s=aaNum.s=OnCoordSetSw.s=IPS_OK; IDSetSwitch(&MovementRADecSw,NULL); IDSetSwitch(&MovementAzAltSw,NULL); IDSetSwitch(&OnCoordSetSw,NULL); IDSetNumber(&eqNum,NULL); IDSetNumber(&aaNum,NULL); return 1; } // only here if break = error MovementRADecSw.s=MovementAzAltSw.s=eqNum.s=aaNum.s=OnCoordSetSw.s=IPS_ALERT; IDSetSwitch(&MovementRADecSw,NULL); IDSetSwitch(&MovementAzAltSw,NULL); IDSetSwitch(&OnCoordSetSw,NULL); IDSetNumber(&eqNum,NULL); IDSetNumber(&aaNum,NULL); return 0; } /* Read the telescope coordinates */ int OrionAtlas::GetCoords(int System) { UpdateSw.s=IPS_BUSY; IDSetSwitch(&UpdateSw,NULL); unsigned char returnStr[4]; union { signed short int ints[2]; unsigned short int uints[2]; unsigned char bytes[4]; }; while (1) { if (System&AZALT) { returnAz=returnAlt=-1000; if (System&RADEC) {returnRA=returnDec=-1000;} // is scope ready? writen(TelPortFD,(unsigned char*)"?",1); int numRead=readn(TelPortFD,returnStr,1,3); if (numRead!=1 || returnStr[0]!='#') { IDMessage(mydev,"Failure: Scope not ready for Z command"); break; } // Send request for current Az/Alt coords writen(TelPortFD,(unsigned char*)"Z",1); numRead=readn(TelPortFD,returnStr,4,1); if (numRead!=4) break; // bytes as expected if (ATLAS_DEBUG) log("Received '%c' %02x %02x %02x %02x\n",'Z',returnStr[0],returnStr[1],returnStr[2],returnStr[3]); bytes[0]=returnStr[1]; bytes[1]=returnStr[0]; bytes[2]=returnStr[3]; bytes[3]=returnStr[2]; returnAz=uints[0]/65536.0*360.0; returnAlt=ints[1]/65536.0*360.0; // returnAlt=returnAlt+lat-90.0; } if (System&RADEC) { returnRA=returnDec=-1000; // Check scope is ready writen(TelPortFD,(unsigned char*)"?",1); int numRead=readn(TelPortFD,returnStr,1,3); if (numRead!=1 || returnStr[0]!='#') { IDMessage(mydev,"Failure: Scope not ready for E command"); break; } // Send get RA/Dec writen(TelPortFD,(unsigned char*)"E",1); numRead=readn(TelPortFD,returnStr,4,1); if (ATLAS_DEBUG) log("Received '%c' %02x %02x %02x %02x\n",'E',returnStr[0],returnStr[1],returnStr[2],returnStr[3]); if (numRead!=4) break; // bytes read is as expected bytes[0]=returnStr[1]; bytes[1]=returnStr[0]; bytes[2]=returnStr[3]; bytes[3]=returnStr[2]; returnRA=uints[0]/65536.0*24.0; returnDec=ints[1]/65536.0*360.0; } // Yep, data is valid. UpdateSw.s=IPS_OK; IDSetSwitch(&UpdateSw,NULL); return(1); } // only here if break -> error! UpdateSw.s=IPS_ALERT; IDSetSwitch(&UpdateSw,NULL); return 0; } // Get coords from scope and update INumbers void OrionAtlas::UpdateCoords(int System) { if (GetCoords(System)) { if (System&RADEC) { eqNum.np[0].value = returnRA; eqNum.np[1].value = returnDec; IDSetNumber(&eqNum, NULL); } if (System&AZALT) { aaNum.np[1].value = returnAlt; aaNum.np[0].value = returnAz; IDSetNumber(&aaNum, NULL); } } } int OrionAtlas::writen(int fd, unsigned char* ptr, int nbytes) { int nleft, nwritten; nleft = nbytes; while (nleft > 0) { nwritten = write (fd, ptr, nleft); if (nwritten <=0 ) break; nleft -= nwritten; ptr += nwritten; } return (nbytes - nleft); } int OrionAtlas::readn(int fd, unsigned char* ptr, int nbytes, int sec) { int status; int nleft, nread; nleft = nbytes; while (nleft > 0) { status = telstat(fd,sec,0); if (status <= 0 ) break; nread = read (fd, ptr, nleft); /* Diagnostic */ /* printf("readn: %d read\n", nread); */ if (nread <= 0) break; nleft -= nread; ptr += nread; } return (nbytes - nleft); } /* * Examines the read status of a file descriptor. * The timeout (sec, usec) specifies a maximum interval to * wait for data to be available in the descriptor. * To effect a poll, the timeout (sec, usec) should be 0. * Returns non-negative value on data available. * 0 indicates that the time limit referred by timeout expired. * On failure, it returns -1 and errno is set to indicate the * error. */ int OrionAtlas::telstat(int fd,int sec,int usec) { int ret; int width; struct timeval timeout; telfds readfds; memset((char *)&readfds,0,sizeof(readfds)); FD_SET(fd, &readfds); width = fd+1; timeout.tv_sec = sec; timeout.tv_usec = usec; ret = select(width,&readfds,(telfds *)0,(telfds *)0,&timeout); return(ret); } void OrionAtlas::ISPoll() { // Called every 2 seconds. if (!TelConnectFlag) return; if (!Updating) return; // Check status of if (eqNum.s==IPS_IDLE||eqNum.s==IPS_OK) { GetCoords(); eqNum.np[0].value=returnRA; eqNum.np[1].value=returnDec; aaNum.np[0].value=returnAz; aaNum.np[1].value=returnAlt; IDSetNumber(&eqNum,NULL); IDSetNumber(&aaNum,NULL); } else { // Slewing. Don't get coords yet. if (ATLAS_DEBUG) log(" (still slewing)\n"); } } void OrionAtlas::log(const char *fmt,...) { if (fmt) { va_list ap; va_start (ap, fmt); time_t t; fprintf(stderr, "%i: ", time(NULL)); vfprintf(stderr, fmt, ap); va_end(ap); } } indi-0.5/src/indidevapi.h0000644000175000017500000006104610610474336013200 0ustar jrjr#if 0 INDI Copyright (C) 2003-2006 Elwood C. Downey Modified by Jasem Mutlaq (2003-2006) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #ifndef INDI_DEVAPI_H #define INDI_DEVAPI_H /** \file indidevapi.h \brief Interface to the reference INDI C API device implementation on the Device Driver side. \author Elwood C. Downey \author Jasem Mutlaq This file is divided into two main sections:\n

  1. Functions the INDI device driver framework defines which the Driver may call:
    • IDxxx functions to send messages to an INDI client.
    • IExxx functions to implement the event driven model.
    • IUxxx functions to perform handy utility functions.
  2. Functions the INDI device driver framework calls which the Driver must define:
    • ISxxx to respond to messages from a Client.

These functions are the interface to the INDI C-language Device Driver reference implementation library. Any driver that uses this interface is expected to #include "indidevapi.h" and to link with indidrivermain.o and eventloop.o. Indidevapi.h further includes indiapi.h. The former contains the prototypes for the functions documented here, although many functions take arguments defined in the latter.

These functions make it much easier to write a compliant INDI driver than starting from scratch, and also serve as a concrete example of the interactions an INDI driver, in any language, is expected to accommodate.

The reference driver framework and the optimizations made within the reference indiserver both assume and require that one driver program implements exactly one logical INDI device.

The functions in this framework fall into two broad categories. Some are functions that a driver must define because they are called by the reference framework; these functions begin with IS. The remaining functions are library utilities a driver may use to do important operations.

A major point to realize is that an INDI driver built with this framework does not contain the C main() function. As soon as a driver begins executing, it listens on stdin for INDI messages. Only when a valid and appropriate message is received will it then call the driver via one of the IS functions. The driver is then expected to respond promptly by calling one of the ID library functions. It may also use any of the IU utility functions as desired to make processing a message easier.

Rather separate from these IS, ID and IU functions are a collection of functions that utilize the notion of a callback. In a callback design, the driver registers a function with the framework to be called under certain circumstances. When said circumstances occur, the framework will call the callback function. The driver never calls these callbacks directly. These callback functions begin with IE. They can arrange for a callback function to be called under three kinds of circumstances: when a given file descriptor may be read without blocking (because either data is available or EOF has been encountered), when a given time interval has elapsed, or when the framework has nothing urgent to do. The callback functions for each circumstance must be written according to a well defined prototype since, after all, the framework must know how to call the callback correctlty.

*/ /******************************************************************************* * get the data structures */ #include "indiapi.h" /******************************************************************************* ******************************************************************************* * * Functions the INDI device driver framework defines which the Driver calls * ******************************************************************************* ******************************************************************************* */ #ifdef __cplusplus extern "C" { #endif /** * \defgroup d2cFunctions IDDef Functions: Functions drivers call to define their properties to clients.

Each of the following functions creates the appropriate XML formatted INDI message from its arguments and writes it to stdout. From there, is it typically read by indiserver which then sends it to the clients that have expressed interest in messages from the Device indicated in the message.

In addition to type-specific arguments, all end with a printf-style format string, and appropriate subsequent arguments, that form the \param msg attribute within the INDI message. If the format argument is NULL, no message attribute is included with the message. Note that a \e timestamp attribute is also always added automatically based on the clock on the computer on which this driver is running.

*/ /*@{*/ /** \brief Tell client to create a text vector property. \param t pointer to the vector text property to be defined. \param msg message in printf style to send to the client. May be NULL. */ extern void IDDefText (const ITextVectorProperty *t, const char *msg, ...) #ifdef __GNUC__ __attribute__ ( ( format( printf, 2, 3 ) ) ) #endif ; /** \brief Tell client to create a number number property. \param n pointer to the vector number property to be defined. \param msg message in printf style to send to the client. May be NULL. */ extern void IDDefNumber (const INumberVectorProperty *n, const char *msg, ...) #ifdef __GNUC__ __attribute__ ( ( format( printf, 2, 3 ) ) ) #endif ; /** \brief Tell client to create a switch vector property. \param s pointer to the vector switch property to be defined. \param msg message in printf style to send to the client. May be NULL. */ extern void IDDefSwitch (const ISwitchVectorProperty *s, const char *msg, ...) #ifdef __GNUC__ __attribute__ ( ( format( printf, 2, 3 ) ) ) #endif ; /** \brief Tell client to create a light vector property. \param l pointer to the vector light property to be defined. \param msg message in printf style to send to the client. May be NULL. */ extern void IDDefLight (const ILightVectorProperty *l, const char *msg, ...) #ifdef __GNUC__ __attribute__ ( ( format( printf, 2, 3 ) ) ) #endif ; /** \brief Tell client to create a BLOB vector property. \param b pointer to the vector BLOB property to be defined. \param msg message in printf style to send to the client. May be NULL. */ extern void IDDefBLOB (const IBLOBVectorProperty *b, const char *msg, ...) #ifdef __GNUC__ __attribute__ ( ( format( printf, 2, 3 ) ) ) #endif ; /*@}*/ /** * \defgroup d2cuFunctions IDSet Functions: Functions drivers call to tell clients of new values for existing properties. */ /*@{*/ /** \brief Tell client to update an existing text vector property. \param t pointer to the vector text property. \param msg message in printf style to send to the client. May be NULL. */ extern void IDSetText (const ITextVectorProperty *t, const char *msg, ...) #ifdef __GNUC__ __attribute__ ( ( format( printf, 2, 3 ) ) ) #endif ; /** \brief Tell client to update an existing number vector property. \param n pointer to the vector number property. \param msg message in printf style to send to the client. May be NULL. */ extern void IDSetNumber (const INumberVectorProperty *n, const char *msg, ...) #ifdef __GNUC__ __attribute__ ( ( format( printf, 2, 3 ) ) ) #endif ; /** \brief Tell client to update an existing switch vector property. \param s pointer to the vector switch property. \param msg message in printf style to send to the client. May be NULL. */ extern void IDSetSwitch (const ISwitchVectorProperty *s, const char *msg, ...) #ifdef __GNUC__ __attribute__ ( ( format( printf, 2, 3 ) ) ) #endif ; /** \brief Tell client to update an existing light vector property. \param l pointer to the vector light property. \param msg message in printf style to send to the client. May be NULL. */ extern void IDSetLight (const ILightVectorProperty *l, const char *msg, ...) #ifdef __GNUC__ __attribute__ ( ( format( printf, 2, 3 ) ) ) #endif ; /** \brief Tell client to update an existing BLOB vector property. \param b pointer to the vector BLOB property. \param msg message in printf style to send to the client. May be NULL. */ extern void IDSetBLOB (const IBLOBVectorProperty *b, const char *msg, ...) #ifdef __GNUC__ __attribute__ ( ( format( printf, 2, 3 ) ) ) #endif ; /*@}*/ /** \brief Function Drivers call to send log messages to Clients. If dev is specified the Client shall associate the message with that device; if dev is NULL the Client shall treat the message as generic from no specific Device. \param dev device name \param msg message in printf style to send to the client. */ extern void IDMessage (const char *dev, const char *msg, ...) #ifdef __GNUC__ __attribute__ ( ( format( printf, 2, 3 ) ) ) #endif ; /** \brief Function Drivers call to inform Clients a Property is no longer available, or the entire device is gone if name is NULL. \param dev device name. If device name is NULL, the entire device will be deleted. \param name property name to be deleted. \param msg message in printf style to send to the client. */ extern void IDDelete (const char *dev, const char *name, const char *msg, ...) #ifdef __GNUC__ __attribute__ ( ( format( printf, 3, 4 ) ) ) #endif ; /** \brief Function Drivers call to log a message locally. The message is not sent to any Clients. \param msg message in printf style to send to the client. */ extern void IDLog (const char *msg, ...) #ifdef __GNUC__ __attribute__ ( ( format( printf, 1, 2 ) ) ) #endif ; /** * \defgroup deventFunctions IE Functions: Functions drivers call to register with the INDI event utilities. Callbacks are called when a read on a file descriptor will not block. Timers are called once after a specified interval. Workprocs are called when there is nothing else to do. The "Add" functions return a unique id for use with their corresponding "Rm" removal function. An arbitrary pointer may be specified when a function is registered which will be stored and forwarded unchanged when the function is later invoked. */ /*@{*/ /* signature of a callback, timout caller and work procedure function */ /** \typedef IE_CBF Signature of a callback. */ typedef void (IE_CBF) (int readfiledes, void *userpointer); /** \typedef IE_CBF Signature of a timeout caller. */ typedef void (IE_TCF) (void *userpointer); /** \typedef IE_CBF Signature of a work procedure function. */ typedef void (IE_WPF) (void *userpointer); /* functions to add and remove callbacks, timers and work procedures */ /** \brief Register a new callback, \e fp, to be called with \e userpointer as argument when \e readfiledes is ready. * * \param readfiledes file descriptor. * \param fp a pointer to the callback function. * \param userpointer a pointer to be passed to the callback function when called. * \return a unique callback id for use with IERmCallback(). */ extern int IEAddCallback (int readfiledes, IE_CBF *fp, void *userpointer); /** \brief Remove a callback function. * * \param callbackid the callback ID returned from IEAddCallback() */ extern void IERmCallback (int callbackid); /** \brief Register a new timer function, \e fp, to be called with \e ud as argument after \e ms. Add to list in order of decreasing time from epoch, ie, last entry runs soonest. The timer will only invoke the callback function \b once. You need to call addTimer again if you want to repeat the process. * * \param millisecs timer period in milliseconds. * \param fp a pointer to the callback function. * \param userpointer a pointer to be passed to the callback function when called. * \return a unique id for use with IERmTimer(). */ extern int IEAddTimer (int millisecs, IE_TCF *fp, void *userpointer); /** \brief Remove the timer with the given \e timerid, as returned from IEAddTimer. * * \param timerid the timer callback ID returned from IEAddTimer(). */ extern void IERmTimer (int timerid); /** \brief Add a new work procedure, fp, to be called with ud when nothing else to do. * * \param fp a pointer to the work procedure callback function. * \param userpointer a pointer to be passed to the callback function when called. * \return a unique id for use with IERmWorkProc(). */ extern int IEAddWorkProc (IE_WPF *fp, void *userpointer); /** \brief Remove the work procedure with the given \e workprocid, as returned from IEAddWorkProc(). * * \param workprocid the work procedure callback ID returned from IEAddWorkProc(). */ extern void IERmWorkProc (int workprocid); /*@}*/ /** * \defgroup dutilFunctions IU Functions: Functions drivers call to perform handy utility routines.

This section describes handy utility functions that are provided by the framework for tasks commonly required in the processing of client messages. It is not strictly necessary to use these functions, but it both prudent and efficient to do so.

These do not communicate with the Client in any way.

*/ /*@{*/ /** \brief Find an IText member in a vector text property. * * \param tp a pointer to a text vector property. * \param name the name of the member to search for. * \return a pointer to an IText member on match, or NULL if nothing is found. */ extern IText *IUFindText (const ITextVectorProperty *tp, const char *name); /** \brief Find an INumber member in a number text property. * * \param tp a pointer to a number vector property. * \param name the name of the member to search for. * \return a pointer to an INumber member on match, or NULL if nothing is found. */ extern INumber *IUFindNumber(const INumberVectorProperty *tp, const char *name); /** \brief Find an ISwitch member in a vector switch property. * * \param tp a pointer to a switch vector property. * \param name the name of the member to search for. * \return a pointer to an ISwitch member on match, or NULL if nothing is found. */ extern ISwitch *IUFindSwitch(const ISwitchVectorProperty *tp, const char *name); /** \brief Returns the first ON switch it finds in the vector switch property. * \note This is only valid for ISR_1OFMANY mode. That is, when only one switch out of many is allowed to be ON. Do not use this function if you can have multiple ON switches in the same vector property. * * \param tp a pointer to a switch vector property. * \return a pointer to the \e first ON ISwitch member if found. If all switches are off, NULL is returned. */ extern ISwitch *IUFindOnSwitch (const ISwitchVectorProperty *tp); /** \brief Reset all switches in a switch vector property to OFF. * * \param svp a pointer to a switch vector property. */ extern void IUResetSwitches(const ISwitchVectorProperty *svp); /** \brief Update all switches in a switch vector property. * * \param svp a pointer to a switch vector property. * \param states the states of the new ISwitch members. * \param names the names of the ISwtich members to update. * \param n the number of ISwitch members to update. * \return 0 if update successful, -1 otherwise. */ extern int IUUpdateSwitches(ISwitchVectorProperty *svp, ISState *states, char *names[], int n); /** \brief Update all numbers in a number vector property. * * \param nvp a pointer to a number vector property. * \param values the states of the new INumber members. * \param names the names of the INumber members to update. * \param n the number of INumber members to update. * \return 0 if update successful, -1 otherwise. Update will fail if values are out of scope, or in case of property name mismatch. */ extern int IUUpdateNumbers(INumberVectorProperty *nvp, double values[], char *names[], int n); /** \brief Update all text members in a text vector property. * * \param nvp a pointer to a text vector property. * \param text a pointer to the text members * \param names the names of the IText members to update. * \param n the number of IText members to update. * \return 0 if update successful, -1 otherwise. Update will fail in case of property name mismatch. */ extern int IUUpdateTexts(ITextVectorProperty *tvp, char * texts[], char *names[], int n); /** \brief Function to update the min and max elements of a number in the client \param nvp pointer to an INumberVectorProperty. */ extern void IUUpdateMinMax(INumberVectorProperty *nvp); /** \brief Function to reliably save new text in a IText. \param tp pointer to an IText member. \param newtext the new text to be saved */ extern void IUSaveText (IText *tp, const char *newtext); /** \brief Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL. \param sp pointer a switch property to fill \param name the switch name \param label the switch label \param s the switch state (ISS_ON or ISS_OFF) */ extern void IUFillSwitch(ISwitch *sp, const char *name, const char * label, ISState s); /** \brief Assign attributes for a number property. The number's auxiliary elements will be set to NULL. \param np pointer a number property to fill \param name the number name \param label the number label \param format the number format in printf style (e.g. "%02d") \param min the minimum possible value \param max the maximum possible value \param step the step used to climb from minimum value to maximum value \param value the number's current value */ extern void IUFillNumber(INumber *np, const char *name, const char * label, const char *format, double min, double max, double step, double value); /** \brief Assign attributes for a text property. The text's auxiliary elements will be set to NULL. \param tp pointer a text property to fill \param name the text name \param label the text label \param initialText the initial text */ extern void IUFillText(IText *tp, const char *name, const char * label, const char *initialText); /** \brief Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL. \param svp pointer a switch vector property to fill \param sp pointer to an array of switches \param nsp the dimension of sp \param dev the device name this vector property belongs to \param name the vector property name \param label the vector property label \param group the vector property group \param p the vector property permission \param r the switches behavior \param timeout vector property timeout in seconds \param s the vector property initial state. */ extern void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char * dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s); /** \brief Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL. \param nvp pointer a number vector property to fill \param np pointer to an array of numbers \param nnp the dimension of np \param dev the device name this vector property belongs to \param name the vector property name \param label the vector property label \param group the vector property group \param p the vector property permission \param timeout vector property timeout in seconds \param s the vector property initial state. */ extern void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char * dev, const char *name, const char *label, const char* group, IPerm p, double timeout, IPState s); /** \brief Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL. \param tvp pointer a text vector property to fill \param tp pointer to an array of texts \param ntp the dimension of tp \param dev the device name this vector property belongs to \param name the vector property name \param label the vector property label \param group the vector property group \param p the vector property permission \param timeout vector property timeout in seconds \param s the vector property initial state. */ extern void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char * dev, const char *name, const char *label, const char* group, IPerm p, double timeout, IPState s); /*@}*/ /******************************************************************************* ******************************************************************************* * * Functions the INDI Device Driver framework calls which the Driver must * define. * ******************************************************************************* ******************************************************************************* */ /** * \defgroup dcuFunctions IS Functions: Functions all drivers must define. This section defines functions that must be defined in each driver. These functions are never called by the driver, but are called by the driver framework. These must always be defined even if they do nothing. */ /*@{*/ /** \brief Get Device Properties \param dev the name of the device. This function is called by the framework whenever the driver has received a getProperties message from an INDI client. The argument \param dev is either a string containing the name of the device specified within the message, or NULL if no device was specified. If the driver does not recognize the device, it should ignore the message and do nothing. If dev matches the device the driver is implementing, or dev is NULL, the driver must respond by sending one defXXX message to describe each property defined by this device, including its current (or initial) value. The recommended way to send these messages is to call the appropriate IDDef functions. */ extern void ISGetProperties (const char *dev); /** \brief Update the value of an existing text vector property. \param dev the name of the device. \param name the name of the text vector property to update. \param texts an array of text values. \param names parallel names to the array of text values. \param n the dimension of texts[]. \note You do not need to call this function, it is called by INDI when new text values arrive from the client. */ extern void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n); /** \brief Update the value of an existing number vector property. \param dev the name of the device. \param name the name of the number vector property to update. \param doubles an array of number values. \param names parallel names to the array of number values. \param n the dimension of doubles[]. \note You do not need to call this function, it is called by INDI when new number values arrive from the client. */ extern void ISNewNumber (const char *dev, const char *name, double *doubles, char *names[], int n); /** \brief Update the value of an existing switch vector property. \param dev the name of the device. \param name the name of the switch vector property to update. \param states an array of switch states. \param names parallel names to the array of switch states. \param n the dimension of states[]. \note You do not need to call this function, it is called by INDI when new switch values arrive from the client. */ extern void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); /** \brief Update data of an existing blob vector property. \param dev the name of the device. \param name the name of the blob vector property to update. \param sizes an array of blob sizes in bytes. \param blobs the blob data array in bytes \param formats Blob data format (e.g. fits.z). \param names names of blob members to update. \param n the number of blobs to update. \note You do not need to call this function, it is called by INDI when new blob values arrive from the client. e.g. BLOB element with name names[0] has data located in blobs[0] with size sizes[0] and format formats[0]. */ extern void ISNewBLOB (const char *dev, const char *name, int sizes[], char *blobs[], char *formats[], char *names[], int n); /*@}*/ #ifdef __cplusplus } #endif #endif indi-0.5/src/lx200driver.h0000644000175000017500000002374110610474336013145 0ustar jrjr/* LX200 Driver Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef LX200DRIVER_H #define LX200DRIVER_H /* Slew speeds */ enum TSlew { LX200_SLEW_MAX, LX200_SLEW_FIND, LX200_SLEW_CENTER, LX200_SLEW_GUIDE}; /* Alignment modes */ enum TAlign { LX200_ALIGN_POLAR, LX200_ALIGN_ALTAZ, LX200_ALIGN_LAND }; /* Directions */ enum TDirection { LX200_NORTH, LX200_WEST, LX200_EAST, LX200_SOUTH, LX200_ALL}; /* Formats of Right ascention and Declenation */ enum TFormat { LX200_SHORT_FORMAT, LX200_LONG_FORMAT}; /* Time Format */ enum TTimeFormat { LX200_24, LX200_AM, LX200_PM}; /* Focus operation */ enum TFocusMotion { LX200_FOCUSIN, LX200_FOCUSOUT }; enum TFocusSpeed { LX200_HALTFOCUS = 0, LX200_FOCUSSLOW, LX200_FOCUSFAST}; /* Library catalogs */ enum TCatalog { LX200_STAR_C, LX200_DEEPSKY_C}; /* Frequency mode */ enum StarCatalog { LX200_STAR, LX200_SAO, LX200_GCVS }; /* Deep Sky Catalogs */ enum DeepSkyCatalog { LX200_NGC, LX200_IC, LX200_UGC, LX200_CALDWELL, LX200_ARP, LX200_ABELL, LX200_MESSIER_C}; /* Mount tracking frequency, in Hz */ enum TFreq { LX200_TRACK_DEFAULT, LX200_TRACK_LUNAR, LX200_TRACK_MANUAL}; #define MaxReticleDutyCycle 15 #define MaxFocuserSpeed 4 /* GET formatted sexagisemal value from device, return as double */ #define getLX200RA(fd, x) getCommandSexa(fd, x, "#:GR#") #define getLX200DEC(fd, x) getCommandSexa(fd, x, "#:GD#") #define getObjectRA(fd, x) getCommandSexa(fd, x, "#:Gr#") #define getObjectDEC(fd, x) getCommandSexa(fd, x, "#:Gd#") #define getLocalTime12(fd, x) getCommandSexa(fd, x, "#:Ga#") #define getLocalTime24(fd, x) getCommandSexa(fd, x, "#:GL#") #define getSDTime(fd, x) getCommandSexa(fd, x, "#:GS#") #define getLX200Alt(fd, x) getCommandSexa(fd, x, "#:GA#") #define getLX200Az(fd, x) getCommandSexa(fd, x, "#:GZ#") /* GET String from device and store in supplied buffer x */ #define getObjectInfo(fd, x) getCommandString(fd, x, "#:LI#") #define getVersionDate(fd, x) getCommandString(fd, x, "#:GVD#") #define getVersionTime(fd, x) getCommandString(fd, x, "#:GVT#") #define getFullVersion(fd, x) getCommandString(fd, x, "#:GVF#") #define getVersionNumber(fd, x) getCommandString(fd, x, "#:GVN#") #define getProductName(fd, x) getCommandString(fd, x, "#:GVP#") #define turnGPS_StreamOn(fd) getCommandString(fd, x, "#:gps#") /* GET Int from device and store in supplied pointer to integer x */ #define getUTCOffset(fd, x) getCommandInt(fd, x, "#:GG#") #define getMaxElevationLimit(fd, x) getCommandInt(fd, x, "#:Go#") #define getMinElevationLimit(fd, x) getCommandInt(fd, x, "#:Gh#") /* Generic set, x is an integer */ #define setReticleDutyFlashCycle(fd, x) setCommandInt(fd, x, "#:BD") #define setReticleFlashRate(fd, x) setCommandInt(fd, x, "#:B") #define setFocuserSpeed(fd, x) setCommandInt(fd, x, "#:F") #define setSlewSpeed(fd, x) setCommandInt(fd, x, "#:Sw") /* Set X:Y:Z */ #define setLocalTime(fd, x,y,z) setCommandXYZ(fd, x,y,z, "#:SL") #define setSDTime(fd, x,y,z) setCommandXYZ(fd, x,y,z, "#:SS") /* GPS Specefic */ #define turnGPSOn(fd) write(fd, "#:g+#", 5) #define turnGPSOff(fd) write(fd, "#:g-#", 5) #define alignGPSScope(fd) write(fd, "#:Aa#", 5) #define gpsSleep(fd) write(fd, "#:hN#", 5) #define gpsWakeUp(fd) write(fd, "#:hW#", 5); #define gpsRestart(fd) write(fd, "#:I#", 4); #define updateGPS_System(fd) setStandardProcedure(fd, "#:gT#") #define enableDecAltPec(fd) write(fd, "#:QA+#", 6) #define disableDecAltPec(fd) write(fd, "#:QA-#", 6) #define enableRaAzPec(fd) write(fd, "#:QZ+#", 6) #define disableRaAzPec(fd) write(fd, "#:QZ-#", 6) #define activateAltDecAntiBackSlash(fd) write(fd, "#$BAdd#", 7) #define activateAzRaAntiBackSlash(fd) write(fd, "#$BZdd#", 7) #define SelenographicSync(fd) write(fd, "#:CL#", 5); #define slewToAltAz(fd) setStandardProcedure(fd, "#:MA#") #define toggleTimeFormat(fd) write(fd, "#:H#", 4) #define increaseReticleBrightness(fd) write(fd, "#:B+#", 5) #define decreaseReticleBrightness(fd) write(fd, "#:B-#", 5) #define turnFanOn(fd) write(fd, "#:f+#", 5) #define turnFanOff(fd) write(fd, "#:f-#", 5) #define seekHomeAndSave(fd) write(fd, "#:hS#", 5) #define seekHomeAndSet(fd) write(fd, "#:hF#", 5) #define turnFieldDeRotatorOn(fd) write(fd, "#:r+#", 5) #define turnFieldDeRotatorOff(fd) write(fd, "#:r-#", 5) #define slewToPark(fd) write(fd, "#:hP#", 5) #ifdef __cplusplus extern "C" { #endif /************************************************************************** Basic I/O - OBSELETE **************************************************************************/ /*int openPort(const char *portID); int portRead(char *buf, int nbytes, int timeout); int portWrite(const char * buf); int LX200readOut(int timeout); int Connect(const char* device); void Disconnect();*/ /************************************************************************** Diagnostics **************************************************************************/ char ACK(int fd); /*int testTelescope(); int testAP();*/ int check_lx200_connection(int fd); /************************************************************************** Get Commands: store data in the supplied buffer. Return 0 on success or -1 on failure **************************************************************************/ /* Get Double from Sexagisemal */ int getCommandSexa(int fd, double *value, const char *cmd); /* Get String */ int getCommandString(int fd, char *data, const char* cmd); /* Get Int */ int getCommandInt(int fd, int *value, const char* cmd); /* Get tracking frequency */ int getTrackFreq(int fd, double * value); /* Get site Latitude */ int getSiteLatitude(int fd, int *dd, int *mm); /* Get site Longitude */ int getSiteLongitude(int fd, int *ddd, int *mm); /* Get Calender data */ int getCalenderDate(int fd, char *date); /* Get site Name */ int getSiteName(int fd, char *siteName, int siteNum); /* Get Number of Bars */ int getNumberOfBars(int fd, int *value); /* Get Home Search Status */ int getHomeSearchStatus(int fd, int *status); /* Get OTA Temperature */ int getOTATemp(int fd, double * value); /* Get time format: 12 or 24 */ int getTimeFormat(int fd, int *format); /* Get RA, DEC from Sky Commander controller */ int updateSkyCommanderCoord(int fd, double *ra, double *dec); /* Get RA, DEC from Intelliscope/SkyWizard controllers */ int updateIntelliscopeCoord (int fd, double *ra, double *dec); /************************************************************************** Set Commands **************************************************************************/ /* Set Int */ int setCommandInt(int fd, int data, const char *cmd); /* Set Sexigesimal */ int setCommandXYZ(int fd, int x, int y, int z, const char *cmd); /* Common routine for Set commands */ int setStandardProcedure(int fd, char * writeData); /* Set Slew Mode */ int setSlewMode(int fd, int slewMode); /* Set Alignment mode */ int setAlignmentMode(int fd, unsigned int alignMode); /* Set Object RA */ int setObjectRA(int fd, double ra); /* set Object DEC */ int setObjectDEC(int fd, double dec); /* Set Calender date */ int setCalenderDate(int fd, int dd, int mm, int yy); /* Set UTC offset */ int setUTCOffset(int fd, double hours); /* Set Track Freq */ int setTrackFreq(int fd, double trackF); /* Set current site longitude */ int setSiteLongitude(int fd, double Long); /* Set current site latitude */ int setSiteLatitude(int fd, double Lat); /* Set Object Azimuth */ int setObjAz(int fd, double az); /* Set Object Altitude */ int setObjAlt(int fd, double alt); /* Set site name */ int setSiteName(int fd, char * siteName, int siteNum); /* Set maximum slew rate */ int setMaxSlewRate(int fd, int slewRate); /* Set focuser motion */ int setFocuserMotion(int fd, int motionType); /* SET GPS Focuser raneg (1 to 4) */ int setGPSFocuserSpeed (int fd, int speed); /* Set focuser speed mode */ int setFocuserSpeedMode (int fd, int speedMode); /* Set minimum elevation limit */ int setMinElevationLimit(int fd, int min); /* Set maximum elevation limit */ int setMaxElevationLimit(int fd, int max); /************************************************************************** Motion Commands **************************************************************************/ /* Slew to the selected coordinates */ int Slew(int fd); /* Synchronize to the selected coordinates and return the matching object if any */ int Sync(int fd, char *matchedObject); /* Abort slew in all axes */ int abortSlew(int fd); /* Move into one direction, two valid directions can be stacked */ int MoveTo(int fd, int direction); /* Half movement in a particular direction */ int HaltMovement(int fd, int direction); /* Select the tracking mode */ int selectTrackingMode(int fd, int trackMode); /* Select Astro-Physics tracking mode */ int selectAPTrackingMode(int fd, int trackMode); /************************************************************************** Other Commands **************************************************************************/ /* Ensures LX200 RA/DEC format is long */ int checkLX200Format(int fd); /* Select a site from the LX200 controller */ int selectSite(int fd, int siteNum); /* Select a catalog object */ int selectCatalogObject(int fd, int catalog, int NNNN); /* Select a sub catalog */ int selectSubCatalog(int fd, int catalog, int subCatalog); #ifdef __cplusplus } #endif #endif indi-0.5/src/celestronprotocol.c0000644000175000017500000004006310610506213014621 0ustar jrjr/* * Telescope Control Protocol for Celestron NexStar GPS telescopes * * Copyright 2003 John Kielkopf * John Kielkopf (kielkopf@louisville.edu) * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 15 May 2003 -- Version 2.00 * * * */ #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #ifndef _WIN32 #include #endif #endif #include #include "celestronprotocol.h" #define NULL_PTR(x) (x *)0 /* There are two classes of routines defined here: */ /* XmTel commands to allow easy NexStar access. These */ /* include routines that mimic the extensive LX200 command */ /* language and, for the most part, trap calls and */ /* respond with an error message to the console. */ /* NexStar specific commands and data. */ /* The NexStar command set as documented by Celestron */ /* is very limited. This version of xmtel uses ta few */ /* auxilliary commands which permit direct access to the motor */ /* controllers. */ /* XmTel compatibility commands */ int ConnectTel(char *port); void DisconnectTel(void); int CheckConnectTel(void); void SetRate(int newRate); void SetLimits(double limitLower, double limitHigher); void StartSlew(int direction); void StopSlew(int direction); double GetRA(void); double GetDec(void); int SlewToCoords(double newRA, double newDec); int SyncToCoords(double newRA, double newDec); int CheckCoords(double desRA, double desDec, double tolRA, double tolDEC); void StopNSEW(void); int SetSlewRate(void); int SyncLST(double newTime); int SyncLocalTime(void); void Reticle(int reticle); void Focus(int focus); void Derotator(int rotate); void Fan(int fan); static int TelPortFD; static int TelConnectFlag = 0; /* NexStar local data */ static double returnRA; /* Last update of RA */ static double returnDec; /* Last update of Dec */ static int updateRA; /* Set if no RA inquiry since last update */ static int updateDec; /* Set if no Dec inquiry since last update */ static int slewRate; /* Rate for slew request in StartSlew */ /* Coordinate reported by NexStar = true coordinate + offset. */ static double offsetRA = 0; /* Correction to RA from NexStar */ static double offsetDec = 0; /* Correction to Dec from NexStar */ /* NexStar local commands */ void GetRAandDec(void); /* Update RA and Dec from NexStar */ /* Serial communication utilities */ typedef fd_set telfds; static int readn(int fd, char *ptr, int nbytes, int sec); static int writen(int fd, char *ptr, int nbytes); static int telstat(int fd,int sec,int usec); int CheckConnectTel(void) { return TelConnectFlag; } int ConnectTel(char *port) { #ifdef _WIN32 return -1; #else struct termios tty; char returnStr[128]; int numRead; fprintf(stderr, "Connecting to port: %s\n",port); if(TelConnectFlag != 0) return 0; /* Make the connection */ TelPortFD = open(port,O_RDWR); if(TelPortFD == -1) return -1; tcgetattr(TelPortFD,&tty); cfsetospeed(&tty, (speed_t) B9600); cfsetispeed(&tty, (speed_t) B9600); tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; tty.c_iflag = IGNBRK; tty.c_lflag = 0; tty.c_oflag = 0; tty.c_cflag |= CLOCAL | CREAD; tty.c_cc[VMIN] = 1; tty.c_cc[VTIME] = 5; tty.c_iflag &= ~(IXON|IXOFF|IXANY); tty.c_cflag &= ~(PARENB | PARODD); tcsetattr(TelPortFD, TCSANOW, &tty); /* Flush the input (read) buffer */ tcflush(TelPortFD,TCIOFLUSH); /* Test connection */ writen(TelPortFD,"Kx",2); numRead=readn(TelPortFD,returnStr,3,2); returnStr[numRead] = '\0'; /* Diagnostic tests */ fprintf(stderr, "ConnectTel read %d characters: %s\n",numRead,returnStr); fprintf(stderr, "TelConnectFlag set to: %d\n",TelConnectFlag); if (numRead == 2) { TelConnectFlag = 1; return (0); } else return -1; #endif } /* Assign and save slewRate for use in StartSlew */ void SetRate(int newRate) { if(newRate == SLEW) { slewRate = 9; } else if(newRate == FIND) { slewRate = 6; } else if(newRate == CENTER) { slewRate = 3; } else if(newRate == GUIDE) { slewRate = 1; } } /* Start a slew in chosen direction at slewRate */ /* Use auxilliary NexStar command set through the hand control computer */ void StartSlew(int direction) { char slewCmd[] = { 0x50, 0x02, 0x11, 0x24, 0x09, 0x00, 0x00, 0x00 }; char inputStr[2048]; if(direction == NORTH) { slewCmd[2] = 0x11; slewCmd[3] = 0x24; slewCmd[4] = slewRate; } else if(direction == EAST) { slewCmd[2] = 0x10; slewCmd[3] = 0x25; slewCmd[4] = slewRate; } else if(direction == SOUTH) { slewCmd[2] = 0x11; slewCmd[3] = 0x25; slewCmd[4] = slewRate; } else if(direction == WEST) { slewCmd[2] = 0x10; slewCmd[3] = 0x24; slewCmd[4] = slewRate; } writen(TelPortFD,slewCmd,8); /* Look for '#' acknowledgment of request*/ for (;;) { if ( readn(TelPortFD,inputStr,1,1) ) { if (inputStr[0] == '#') break; } else { fprintf(stderr,"No acknowledgment from telescope in StartSlew.\n"); } } } /* Stop the slew in chosen direction */ void StopSlew(int direction) { char slewCmd[] = { 0x50, 0x02, 0x11, 0x24, 0x00, 0x00, 0x00, 0x00 }; char inputStr[2048]; if(direction == NORTH) { slewCmd[2] = 0x11; slewCmd[3] = 0x24; } else if(direction == EAST) { slewCmd[2] = 0x10; slewCmd[3] = 0x24; } else if(direction == SOUTH) { slewCmd[2] = 0x11; slewCmd[3] = 0x24; } else if(direction == WEST) { slewCmd[2] = 0x10; slewCmd[3] = 0x24; } writen(TelPortFD,slewCmd,8); /* Look for '#' acknowledgment of request*/ for (;;) { if ( readn(TelPortFD,inputStr,1,1) ) { if (inputStr[0] == '#') break; } else { fprintf(stderr,"No acknowledgment from telescope in StartSlew.\n"); } } } void DisconnectTel(void) { /* printf("DisconnectTel\n"); */ if(TelConnectFlag == 1) close(TelPortFD); TelConnectFlag = 0; } /* Test update status and return the telescope right ascension */ /* Set updateRA flag false */ /* Last telescope readout will be returned if no RA inquiry since then */ /* Otherwise force a new readout */ /* Two successive calls to GetRA will always force a new readout */ double GetRA(void) { if( updateRA != 1) GetRAandDec(); updateRA = 0; return returnRA; } /* Test update status and return the telescope declination */ /* Set updateDec flag false */ /* Last telescope readout will returned if no Dec inquiry since then */ /* Otherwise force a new readout */ /* Two successive calls to GetDec will always force a new readout */ double GetDec(void) { if( updateDec != 1) GetRAandDec(); updateDec = 0; return returnDec; } /* Read the telescope right ascension and declination and set update status */ void GetRAandDec(void) { char returnStr[12]; int countRA,countDec; int numRead; writen(TelPortFD,"E",1); numRead=readn(TelPortFD,returnStr,10,1); returnStr[4] = returnStr[9] = '\0'; /* Diagnostic * * printf("GetRAandDec: %d read %x\n",numRead,returnStr); * */ sscanf(returnStr,"%x",&countRA); sscanf(returnStr+5,"%x:",&countDec); returnRA = (double) countRA; returnRA = returnRA / (3. * 15. * 60. * 65536./64800.); returnDec = (double) countDec; returnDec = returnDec / (3. * 60. * 65536./64800.); /* Account for the quadrant in declination */ /* 90 to 180 */ if ( (returnDec > 90.) && (returnDec <= 180.) ) { returnDec = 180. - returnDec; } /* 180 to 270 */ if ( (returnDec > 180.) && (returnDec <= 270.) ) { returnDec = returnDec - 270.; } /* 270 to 360 */ if ( (returnDec > 270.) && (returnDec <= 360.) ) { returnDec = returnDec - 360.; } /* Set update flags */ updateRA = 1; updateDec = 1; /* Correct for offsets and return true coordinate */ /* Coordinate reported by NexStar = true coordinate + offset. */ returnRA = returnRA - offsetRA; returnDec = returnDec - offsetDec; } /* Reset telescope coordinates to new coordinates by adjusting offsets*/ /* Coordinate reported by NexStar = true coordinate + offset. */ int SyncToCoords(double newRA, double newDec) { offsetRA = 0.; offsetDec = 0.; GetRAandDec(); offsetRA = returnRA - newRA; offsetDec = returnDec - newDec; return (0); } /* Slew to new coordinates */ /* Coordinate sent to NexStar = true coordinate + offset. */ int SlewToCoords(double newRA, double newDec) { int countRA,countDec; char r0,r1,r2,r3,d0,d1,d2,d3; double degs, hrs; char outputStr[32], inputStr[2048]; /* Add offsets */ hrs = newRA + offsetRA; degs = newDec + offsetDec; /* Convert float RA to integer count */ hrs = hrs*(3. * 15. * 60. * 65536./64800.); countRA = (int) hrs; /* Account for the quadrant in declination */ if ( (newDec >= 0.0) && (newDec <= 90.0) ) { degs = degs*(3. * 60. * 65536./64800.); } else if ( (newDec < 0.0) && (newDec >= -90.0) ) { degs = (360. + degs)*(3. * 60. * 65536./64800.); } else { fprintf(stderr,"Invalid newDec in SlewToCoords.\n"); return 1; } /* Convert float Declination to integer count */ countDec = (int) degs; /* Convert each integer count to four HEX characters */ /* Inline coding just to be fast */ if(countRA < 65536) { r0 = countRA % 16; if(r0 < 10) { r0 = r0 + 48; } else { r0 = r0 + 55; } countRA = countRA/16; r1 = countRA % 16; if(r1 < 10) { r1 = r1 + 48; } else { r1 = r1 + 55; } countRA = countRA/16; r2 = countRA % 16; if(r2 < 10) { r2 = r2 + 48; } else { r2 = r2 + 55; } r3 = countRA/16; if(r3 < 10) { r3 = r3 + 48; } else { r3 = r3 + 55; } } else { printf("RA count overflow in SlewToCoords.\n"); return 2; } if(countDec < 65536) { d0 = countDec % 16; if(d0 < 10) { d0 = d0 + 48; } else { d0 = d0 + 55; } countDec = countDec/16; d1 = countDec % 16; if(d1 < 10) { d1 = d1 + 48; } else { d1 = d1 + 55; } countDec = countDec/16; d2 = countDec % 16; if(d2 < 10) { d2 = d2 + 48; } else { d2 = d2 + 55; } d3 = countDec/16; if(d3 < 10) { d3 = d3 + 48; } else { d3 = d3 + 55; } } else { fprintf(stderr,"Dec count overflow in SlewToCoords.\n"); return 3; } /* Send the command and characters to the NexStar */ sprintf(outputStr,"R%c%c%c%c,%c%c%c%c",r3,r2,r1,r0,d3,d2,d1,d0); writen(TelPortFD,outputStr,10); /* Look for '#' in response */ for (;;) { if ( readn(TelPortFD,inputStr,1,2) ) { if (inputStr[0] == '#') break; } else fprintf(stderr,"No acknowledgment from telescope after SlewToCoords.\n"); return 4; } return 0; } /* Test whether the destination has been reached */ /* With the NexStar we use the goto in progress query */ /* Return value is */ /* 0 -- goto in progress */ /* 1 -- goto complete within tolerance */ /* 2 -- goto complete but outside tolerance */ int CheckCoords(double desRA, double desDec, double tolRA, double tolDEC) { double errorRA, errorDec, nowRA, nowDec; char inputStr[2048]; writen(TelPortFD,"L",1); /* Look for '0#' in response indicating goto is not in progress */ for (;;) { if ( readn(TelPortFD,inputStr,2,2) ) { if ( (inputStr[0] == '0') && (inputStr[1] == '#')) break; } else return 0; } nowRA=GetRA(); errorRA = nowRA - desRA; nowDec=GetDec(); errorDec = nowDec - desDec; /* For 6 minute of arc precision; change as needed. */ if( fabs(errorRA) > tolRA || fabs(errorDec) > tolDEC) return 1; else return 2; } /* Set lower and upper limits to protect hardware */ void SetLimits(double limitLower, double limitHigher) { limitLower = limitHigher; fprintf(stderr,"NexStar does not support software limits.\n"); } /* Set slew speed limited by MAXSLEWRATE */ int SetSlewRate(void) { fprintf(stderr,"NexStar does not support remote setting of slew rate.\n"); return 0; } /* Stop all slew motion */ void StopNSEW(void) { char inputStr[2048]; writen(TelPortFD,"M",1); /* Look for '#' */ for (;;) { if ( readn(TelPortFD,inputStr,1,1) ) { if (inputStr[0] == '#') break; } else { fprintf(stderr,"No acknowledgment from telescope in StopNSEW.\n"); } } } /* Control the reticle function using predefined values */ void Reticle(int reticle) { reticle = reticle; fprintf(stderr,"NexStar does not support remote setting of reticle.\n"); } /* Control the focus using predefined values */ void Focus(int focus) { focus = focus; fprintf(stderr,"NexStar does not support remote setting of focus.\n"); } /* Control the derotator using predefined values */ void Derotator(int rotate) { rotate = rotate; fprintf(stderr,"NexStar does not support an image derotator.\n"); } /* Control the fan using predefined values */ void Fan(int fan) { fan = fan; fprintf(stderr,"NexStar does not have a fan.\n"); } /* Time synchronization utilities */ /* Reset the telescope sidereal time */ int SyncLST(double newTime) { newTime = newTime; fprintf(stderr,"NexStar does not support remote setting of sidereal time.\n"); return -1; } /* Reset the telescope local time */ int SyncLocalTime() { fprintf(stderr,"NexStar does not support remote setting of local time.\n"); return -1; } /* Serial port utilities */ static int writen(fd, ptr, nbytes) int fd; char *ptr; int nbytes; { int nleft, nwritten; nleft = nbytes; while (nleft > 0) { nwritten = write (fd, ptr, nleft); if (nwritten <=0 ) break; nleft -= nwritten; ptr += nwritten; } return (nbytes - nleft); } static int readn(fd, ptr, nbytes, sec) int fd; char *ptr; int nbytes; int sec; { int status; int nleft, nread; nleft = nbytes; while (nleft > 0) { status = telstat(fd,sec,0); if (status <= 0 ) break; nread = read (fd, ptr, nleft); /* Diagnostic */ /* printf("readn: %d read\n", nread); */ if (nread <= 0) break; nleft -= nread; ptr += nread; } return (nbytes - nleft); } /* * Examines the read status of a file descriptor. * The timeout (sec, usec) specifies a maximum interval to * wait for data to be available in the descriptor. * To effect a poll, the timeout (sec, usec) should be 0. * Returns non-negative value on data available. * 0 indicates that the time limit referred by timeout expired. * On failure, it returns -1 and errno is set to indicate the * error. */ static int telstat(fd,sec,usec) register int fd, sec, usec; { int ret; int width; struct timeval timeout; telfds readfds; memset((char *)&readfds,0,sizeof(readfds)); FD_SET(fd, &readfds); width = fd+1; timeout.tv_sec = sec; timeout.tv_usec = usec; ret = select(width,&readfds,NULL_PTR(telfds),NULL_PTR(telfds),&timeout); return(ret); } indi-0.5/src/apogee_caminfo.xml0000644000175000017500000000175310605175713014371 0ustar jrjr 1 Short True 16 CCD 0x2 0x6 Normal 0x00 8 63 False 1024 1024 12 6 6 2 8 50 False 10.0 3.5 24 24 indi-0.5/src/fq.c0000644000175000017500000001317710610474331011462 0ustar jrjr/* a fifo queue that never fills. * Copyright (C) 2005 Elwood C. Downey ecdowney@clearskyinstitute.com * includes standalone commandline test program, see below. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** \file fq.c \brief a fifo queue that never fills. Generic FIFO Queue. an FQ is a FIFO list of pointers to void, each called an "element". elements are added at q[head]. there are (nq) elements in the list. the element to be removed next is q[head-nq]. there are (head-nq) empty slots at the front of the q array. there are (nmem-head) elements available at the end. if the head reaches the end, existing enties are slid to the front of the array and total memory is adjusted up or down as required. example: <-------------------- nmem = 17 ---------------------------------> <-- head - nq = 6 ---> <-- nq = 4 --> <---- nmem - head = 7 --> --------------------------------------------------------------------- | | | | | | | x | x | x | x | | | | | | | | --------------------------------------------------------------------- 0 1 2 3 4 5 6 7 8 9 ^ head = 10 \author Elwood Downey */ #include #include #include "fq.h" struct _FQ { void **q; /* malloced array of (void *) */ int nq; /* number of elements on queue */ int head; /* index into q[] of next empty spot */ int nmem; /* number of total slots in q[] */ int grow; /* n elements to grow when out of room*/ }; /* default memory managers, override with setMemFuncsFQ() */ static void *(*mymalloc)(size_t size) = malloc; static void *(*myrealloc)(void *ptr, size_t size) = realloc; static void (*myfree)(void *ptr) = free; static void chkFQ (FQ *q); /* return pointer to a new FQ, or NULL if no more memory. * grow is an efficiency hint of the number of elements to grow when out of * room, nothing terrible happens if it is wrong. */ FQ * newFQ (int grow) { FQ *q = (FQ *)(*mymalloc)(sizeof(FQ)); memset (q, 0, sizeof(FQ)); q->q = (*mymalloc) (1); /* seed for realloc */ q->grow = grow > 0 ? grow : 1; return (q); } /* delete a FQ no longer needed */ void delFQ (FQ *q) { (*myfree) (q->q); /* guaranteed set in newFQ() */ (*myfree) ((void *)q); } /* push an element onto the given FQ */ void pushFQ (FQ *q, void *e) { chkFQ (q); q->q[q->head++] = e; q->nq++; } /* pop and return the next element in the given FQ, or NULL if empty */ void * popFQ (FQ *q) { return (q->nq > 0 ? q->q[q->head - q->nq--] : NULL); } /* return next element in the given FQ leaving it on the q, or NULL if empty */ void * peekFQ (FQ *q) { return (q->nq > 0 ? q->q[q->head - q->nq] : NULL); } /* return the number of elements in the given FQ */ int nFQ (FQ *q) { return (q->nq); } /* install new version of malloc/realloc/free. * N.B. don't call after first use of any other FQ function */ void setMemFuncsFQ (void *(*newmalloc)(size_t size), void *(*newrealloc)(void *ptr, size_t size), void (*newfree)(void *ptr)) { mymalloc = newmalloc; myrealloc = newrealloc; myfree = newfree; } /* insure q can hold one more element */ static void chkFQ (FQ *q) { int infront; /* done if still room at end */ if (q->nmem > q->head) return; /* move list to front */ infront = q->head - q->nq; memmove (q->q, &q->q[infront], q->nq * sizeof(void*)); q->head -= infront; /* realloc to minimum number of grow-sized chunks required */ q->nmem = q->grow*(q->head/q->grow+1); q->q = (*myrealloc) (q->q, q->nmem * sizeof(void*)); } #if defined(TEST_FQ) /* to build a stand-alone commandline test program: * cc -DTEST_FQ -o fq fq.c * run ./fq to test push/pop/peek and watch the queue after each operation. * the queue test elements are char, please excuse the ugly casts. */ #include /* draw a simple graphical representation of the given FQ */ static void prFQ (FQ *q) { int i; /* print the q, empty slots print as '.' */ for (i = 0; i < q->nmem; i++) { if (i >= q->head - q->nq && i < q->head) printf ("%c", (char)(int)q->q[i]); else printf ("."); } /* add right-justified stats */ printf ("%*s nmem = %2d head = %2d nq = %2d\n", 50-i, "", q->nmem, q->head, q->nq); } int main (int ac, char *av[]) { FQ *q = newFQ(8); int c, e = -1; void *p; printf ("Commands:\n"); printf (" P = push a letter a-z\n"); printf (" p = pop a letter\n"); printf (" k = peek into queue\n"); while ((c = fgetc(stdin)) != EOF) { switch (c) { case 'P': pushFQ (q, (void*)('a'+(e=(e+1)%26))); prFQ(q); break; case 'p': p = popFQ (q); if (p) printf ("popped %c\n", (char)(int)p); else printf ("popped empty q\n"); prFQ(q); break; case 'k': p = peekFQ (q); if (p) printf ("peeked %c\n", (char)(int)p); else printf ("peeked empty q\n"); prFQ(q); break; default: break; } } return (0); } #endif /* TEST_FQ */ indi-0.5/src/lilxml.h0000644000175000017500000002122510610525553012356 0ustar jrjr#if 0 liblilxml Copyright (C) 2003 Elwood C. Downey This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif /** \file lilxml.h \brief A little DOM-style library to handle parsing and processing an XML file. It only handles elements, attributes and pcdata content. and are silently ignored. pcdata is collected into one string, sans leading whitespace first line. \n The following is an example of a cannonical usage for the lilxml library. Initialize a lil xml context and read an XML file in a root element. \code #include LilXML *lp = newLilXML(); char errmsg[1024]; XMLEle *root, *ep; int c; while ((c = fgetc(stdin)) != EOF) { root = readXMLEle (lp, c, errmsg); if (root) break; if (errmsg[0]) error ("Error: %s\n", errmsg); } // print the tag and pcdata content of each child element within the root for (ep = nextXMLEle (root, 1); ep != NULL; ep = nextXMLEle (root, 0)) printf ("%s: %s\n", tagXMLEle(ep), pcdataXMLEle(ep)); // finished with root element and with lil xml context delXMLEle (root); delLilXML (lp); \endcode */ #ifndef LILXML_H #define LILXML_H #include #ifdef __cplusplus extern "C" { #endif /* opaque handle types */ typedef struct _xml_att XMLAtt; typedef struct _xml_ele XMLEle; typedef struct _LilXML LilXML; /** * \defgroup lilxmlFunctions XML Functions: Functions to parse, process, and search XML. */ /*@{*/ /* creation and destruction functions */ /** \brief Create a new lilxml parser. \return a pointer to the lilxml parser on success. NULL on failure. */ extern LilXML *newLilXML(void); /** \brief Delete a lilxml parser. \param lp a pointer to a lilxml parser to be deleted. */ extern void delLilXML (LilXML *lp); /** \brief Delete an XML element. \return a pointer to the XML Element to be deleted. */ extern void delXMLEle (XMLEle *e); /** \brief Process an XML one char at a time. \param lp a pointer to a lilxml parser. \param c one character to process. \param errmsg a buffer to store error messages if an error in parsing is encounterd. \return When the function parses a complete valid XML element, it will return a pointer to the XML element. A NULL is returned when parsing the element is still in progress, or if a parsing error occurs. Check errmsg for errors if NULL is returned. */ extern XMLEle *readXMLEle (LilXML *lp, int c, char errmsg[]); /* search functions */ /** \brief Find an XML attribute within an XML element. \param e a pointer to the XML element to search. \param name the attribute name to search for. \return A pointer to the XML attribute if found or NULL on failure. */ extern XMLAtt *findXMLAtt (XMLEle *e, const char *name); /** \brief Find an XML element within an XML element. \param e a pointer to the XML element to search. \param tag the element tag to search for. \return A pointer to the XML element if found or NULL on failure. */ extern XMLEle *findXMLEle (XMLEle *e, const char *tag); /* iteration functions */ /** \brief Iterate an XML element for a list of nesetd XML elements. \param ep a pointer to the XML element to iterate. \param first the index of the starting XML element. Pass 1 to start iteration from the beginning of the XML element. Pass 0 to get the next element thereater. \return On success, a pointer to the next XML element is returned. NULL when there are no more elements. */ extern XMLEle *nextXMLEle (XMLEle *ep, int first); /** \brief Iterate an XML element for a list of XML attributes. \param ep a pointer to the XML element to iterate. \param first the index of the starting XML attribute. Pass 1 to start iteration from the beginning of the XML element. Pass 0 to get the next attribute thereater. \return On success, a pointer to the next XML attribute is returned. NULL when there are no more attributes. */ extern XMLAtt *nextXMLAtt (XMLEle *ep, int first); /* tree functions */ /** \brief Return the parent of an XML element. \return a pointer to the XML element parent. */ extern XMLEle *parentXMLEle (XMLEle *ep); /** \brief Return the parent of an XML attribute. \return a pointer to the XML element parent. */ extern XMLEle *parentXMLAtt (XMLAtt *ap); /* access functions */ /** \brief Return the tag of an XML element. \param ep a pointer to an XML element. \return the tag string. */ extern char *tagXMLEle (XMLEle *ep); /** \brief Return the pcdata of an XML element. \param ep a pointer to an XML element. \return the pcdata string on success. */ extern char *pcdataXMLEle (XMLEle *ep); /** \brief Return the name of an XML attribute. \param ap a pointer to an XML attribute. \return the name string of the attribute. */ extern char *nameXMLAtt (XMLAtt *ap); /** \brief Return the value of an XML attribute. \param ap a pointer to an XML attribute. \return the value string of the attribute. */ extern char *valuXMLAtt (XMLAtt *ap); /** \brief Return the number of characters in pcdata in an XML element. \param ep a pointer to an XML element. \return the length of the pcdata string. */ extern int pcdatalenXMLEle (XMLEle *ep); /** \brief Return the number of nested XML elements in a parent XML element. \param ep a pointer to an XML element. \return the number of nested XML elements. */ extern int nXMLEle (XMLEle *ep); /** \brief Return the number of XML attributes in a parent XML element. \param ep a pointer to an XML element. \return the number of XML attributes within the XML element. */ extern int nXMLAtt (XMLEle *ep); /* editing functions */ /** \brief Add an XML attribute to an existing XML element. \param ep pointer to an XML element \param name the name of the XML attribute to add. \param value the value of the XML attribute to add. */ extern void addXMLAtt (XMLEle *ep, const char *name, char *value); /** \brief Remove an XML attribute from an XML element. \param ep pointer to an XML element. \param name the name of the XML attribute to remove */ extern void rmXMLAtt (XMLEle *ep, const char *name); /* convenience functions */ /** \brief Find an XML element's attribute value. \param ep a pointer to an XML element. \param name the name of the XML attribute to retrieve its value. \return the value string of an XML element on success. NULL on failure. */ extern char *findXMLAttValu (XMLEle *ep, const char *name); /** \brief Handy wrapper to read one xml file. \param fp pointer to FILE to read. \param lp pointer to lilxml parser. \param errmsg a buffer to store error messages on failure. \return root element else NULL with report in errmsg[]. */ extern XMLEle *readXMLFile (FILE *fp, LilXML *lp, char errmsg[]); /** \brief Print an XML element. \param fp a pointer to FILE where the print output is directed. \param e the XML element to print. \param level the printing level, set to 0 to print the whole element. */ extern void prXMLEle (FILE *fp, XMLEle *e, int level); /* install alternatives to malloc/realloc/free */ extern void indi_xmlMalloc (void *(*newmalloc)(size_t size), void *(*newrealloc)(void *ptr, size_t size), void (*newfree)(void *ptr)); /*@}*/ #ifdef __cplusplus } #endif /* examples. initialize a lil xml context and read an XML file in a root element LilXML *lp = newLilXML(); char errmsg[1024]; XMLEle *root, *ep; int c; while ((c = fgetc(stdin)) != EOF) { root = readXMLEle (lp, c, errmsg); if (root) break; if (errmsg[0]) error ("Error: %s\n", errmsg); } print the tag and pcdata content of each child element within the root for (ep = nextXMLEle (root, 1); ep != NULL; ep = nextXMLEle (root, 0)) printf ("%s: %s\n", tagXMLEle(ep), pcdataXMLEle(ep)); finished with root element and with lil xml context delXMLEle (root); delLilXML (lp); */ /* For RCS Only -- Do Not Edit * @(#) $RCSfile$ $Date: 2006-05-20 17:49:17 +0300 (Sat, 20 May 2006) $ $Revision: 542858 $ $Name: $ */ #endif /* LILXML_H */ indi-0.5/src/webcam/0000755000175000017500000000000011017761434012142 5ustar jrjrindi-0.5/src/webcam/v4l1_base.h0000644000175000017500000000515710605175707014107 0ustar jrjr/* Copyright (C) 2005 by Jasem Mutlaq Some code based on qastrocam This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef V4L1_BASE_H #define V4L1_BASE_H #include #include #include "videodev.h" #include "../eventloop.h" class V4L1_Base { public: V4L1_Base(); virtual ~V4L1_Base(); /* Connection */ virtual int connectCam(const char * devpath, char *errmsg); virtual void disconnectCam(); char * getDeviceName(); /* Image settings */ int getBrightness(); int getContrast(); int getColor(); int getHue(); int getWhiteness(); void setContrast(int val); void setBrightness(int val); void setColor(int val); void setHue(int val); void setWhiteness(int val); /* Updates */ static void updateFrame(int d, void * p); void newFrame(); void setPictureSettings(); void getPictureSettings(); /* Image Size */ int getWidth(); int getHeight(); void checkSize(int & x, int & y); virtual bool setSize(int x, int y); virtual void getMaxMinSize(int & xmax, int & ymax, int & xmin, int & ymin); /* Frame rate */ void setFPS(int fps); int getFPS(); void init(int preferedPalette); void allocBuffers(); int mmapInit(); void mmapCapture(); void mmapSync(); unsigned char * mmapFrame(); unsigned char * getY(); unsigned char * getU(); unsigned char * getV(); unsigned char * getColorBuffer(); int start_capturing(char *errmsg); int stop_capturing(char *errmsg); void registerCallback(WPF *fp, void *ud); protected: int fd; WPF *callback; void *uptr; unsigned long options; struct video_capability capability; struct video_window window; struct video_picture picture_format; struct video_mbuf mmap_buffer; unsigned char * buffer_start; long mmap_sync_buffer; long mmap_capture_buffer; int frameRate; bool streamActive; int selectCallBackID; unsigned char * YBuf,*UBuf,*VBuf, *colorBuffer; }; #endif indi-0.5/src/webcam/pwc-ioctl.h0000644000175000017500000002523710605175707014231 0ustar jrjr#ifndef PWC_IOCTL_H #define PWC_IOCTL_H /* (C) 2001-2004 Nemosoft Unv. (C) 2004-2006 Luc Saillard (luc@saillard.org) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx driver and thus may have bugs that are not present in the original version. Please send bug reports and support requests to . The decompression routines have been implemented by reverse-engineering the Nemosoft binary pwcx module. Caveat emptor. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* This is pwc-ioctl.h belonging to PWC 10.0.10 It contains structures and defines to communicate from user space directly to the driver. */ /* Changes 2001/08/03 Alvarado Added ioctl constants to access methods for changing white balance and red/blue gains 2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE 2003/12/13 Nemosft Unv. Some modifications to make interfacing to PWCX easier 2006/01/01 Luc Saillard Add raw format definition */ /* These are private ioctl() commands, specific for the Philips webcams. They contain functions not found in other webcams, and settings not specified in the Video4Linux API. The #define names are built up like follows: VIDIOC VIDeo IOCtl prefix PWC Philps WebCam G optional: Get S optional: Set ... the function */ #include /* Enumeration of image sizes */ #define PSZ_SQCIF 0x00 #define PSZ_QSIF 0x01 #define PSZ_QCIF 0x02 #define PSZ_SIF 0x03 #define PSZ_CIF 0x04 #define PSZ_VGA 0x05 #define PSZ_MAX 6 /* The frame rate is encoded in the video_window.flags parameter using the upper 16 bits, since some flags are defined nowadays. The following defines provide a mask and shift to filter out this value. This value can also be passing using the private flag when using v4l2 and VIDIOC_S_FMT ioctl. In 'Snapshot' mode the camera freezes its automatic exposure and colour balance controls. */ #define PWC_FPS_SHIFT 16 #define PWC_FPS_MASK 0x00FF0000 #define PWC_FPS_FRMASK 0x003F0000 #define PWC_FPS_SNAPSHOT 0x00400000 #define PWC_QLT_MASK 0x03000000 #define PWC_QLT_SHIFT 24 /* structure for transferring x & y coordinates */ struct pwc_coord { int x, y; /* guess what */ int size; /* size, or offset */ }; /* Used with VIDIOCPWCPROBE */ struct pwc_probe { char name[32]; int type; }; struct pwc_serial { char serial[30]; /* String with serial number. Contains terminating 0 */ }; /* pwc_whitebalance.mode values */ #define PWC_WB_INDOOR 0 #define PWC_WB_OUTDOOR 1 #define PWC_WB_FL 2 #define PWC_WB_MANUAL 3 #define PWC_WB_AUTO 4 /* Used with VIDIOCPWC[SG]AWB (Auto White Balance). Set mode to one of the PWC_WB_* values above. *red and *blue are the respective gains of these colour components inside the camera; range 0..65535 When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read; otherwise undefined. 'read_red' and 'read_blue' are read-only. */ struct pwc_whitebalance { int mode; int manual_red, manual_blue; /* R/W */ int read_red, read_blue; /* R/O */ }; /* 'control_speed' and 'control_delay' are used in automatic whitebalance mode, and tell the camera how fast it should react to changes in lighting, and with how much delay. Valid values are 0..65535. */ struct pwc_wb_speed { int control_speed; int control_delay; }; /* Used with VIDIOCPWC[SG]LED */ struct pwc_leds { int led_on; /* Led on-time; range = 0..25000 */ int led_off; /* Led off-time; range = 0..25000 */ }; /* Image size (used with GREALSIZE) */ struct pwc_imagesize { int width; int height; }; /* Defines and structures for Motorized Pan & Tilt */ #define PWC_MPT_PAN 0x01 #define PWC_MPT_TILT 0x02 #define PWC_MPT_TIMEOUT 0x04 /* for status */ /* Set angles; when absolute != 0, the angle is absolute and the driver calculates the relative offset for you. This can only be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns absolute angles. */ struct pwc_mpt_angles { int absolute; /* write-only */ int pan; /* degrees * 100 */ int tilt; /* degress * 100 */ }; /* Range of angles of the camera, both horizontally and vertically. */ struct pwc_mpt_range { int pan_min, pan_max; /* degrees * 100 */ int tilt_min, tilt_max; }; struct pwc_mpt_status { int status; int time_pan; int time_tilt; }; /* This is used for out-of-kernel decompression. With it, you can get all the necessary information to initialize and use the decompressor routines in standalone applications. */ struct pwc_video_command { int type; /* camera type (645, 675, 730, etc.) */ int release; /* release number */ int size; /* one of PSZ_* */ int alternate; int command_len; /* length of USB video command */ unsigned char command_buf[13]; /* Actual USB video command */ int bandlength; /* >0 = compressed */ int frame_size; /* Size of one (un)compressed frame */ }; /* Flags for PWCX subroutines. Not all modules honor all flags. */ #define PWCX_FLAG_PLANAR 0x0001 #define PWCX_FLAG_BAYER 0x0008 /* IOCTL definitions */ /* Restore user settings */ #define VIDIOCPWCRUSER _IO('v', 192) /* Save user settings */ #define VIDIOCPWCSUSER _IO('v', 193) /* Restore factory settings */ #define VIDIOCPWCFACTORY _IO('v', 194) /* You can manipulate the compression factor. A compression preference of 0 means use uncompressed modes when available; 1 is low compression, 2 is medium and 3 is high compression preferred. Of course, the higher the compression, the lower the bandwidth used but more chance of artefacts in the image. The driver automatically chooses a higher compression when the preferred mode is not available. */ /* Set preferred compression quality (0 = uncompressed, 3 = highest compression) */ #define VIDIOCPWCSCQUAL _IOW('v', 195, int) /* Get preferred compression quality */ #define VIDIOCPWCGCQUAL _IOR('v', 195, int) /* Retrieve serial number of camera */ #define VIDIOCPWCGSERIAL _IOR('v', 198, struct pwc_serial) /* This is a probe function; since so many devices are supported, it becomes difficult to include all the names in programs that want to check for the enhanced Philips stuff. So in stead, try this PROBE; it returns a structure with the original name, and the corresponding Philips type. To use, fill the structure with zeroes, call PROBE and if that succeeds, compare the name with that returned from VIDIOCGCAP; they should be the same. If so, you can be assured it is a Philips (OEM) cam and the type is valid. */ #define VIDIOCPWCPROBE _IOR('v', 199, struct pwc_probe) /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */ #define VIDIOCPWCSAGC _IOW('v', 200, int) /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */ #define VIDIOCPWCGAGC _IOR('v', 200, int) /* Set shutter speed; int < 0 = auto; >= 0 = fixed, range 0..65535 */ #define VIDIOCPWCSSHUTTER _IOW('v', 201, int) /* Color compensation (Auto White Balance) */ #define VIDIOCPWCSAWB _IOW('v', 202, struct pwc_whitebalance) #define VIDIOCPWCGAWB _IOR('v', 202, struct pwc_whitebalance) /* Auto WB speed */ #define VIDIOCPWCSAWBSPEED _IOW('v', 203, struct pwc_wb_speed) #define VIDIOCPWCGAWBSPEED _IOR('v', 203, struct pwc_wb_speed) /* LEDs on/off/blink; int range 0..65535 */ #define VIDIOCPWCSLED _IOW('v', 205, struct pwc_leds) #define VIDIOCPWCGLED _IOR('v', 205, struct pwc_leds) /* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */ #define VIDIOCPWCSCONTOUR _IOW('v', 206, int) #define VIDIOCPWCGCONTOUR _IOR('v', 206, int) /* Backlight compensation; 0 = off, otherwise on */ #define VIDIOCPWCSBACKLIGHT _IOW('v', 207, int) #define VIDIOCPWCGBACKLIGHT _IOR('v', 207, int) /* Flickerless mode; = 0 off, otherwise on */ #define VIDIOCPWCSFLICKER _IOW('v', 208, int) #define VIDIOCPWCGFLICKER _IOR('v', 208, int) /* Dynamic noise reduction; 0 off, 3 = high noise reduction */ #define VIDIOCPWCSDYNNOISE _IOW('v', 209, int) #define VIDIOCPWCGDYNNOISE _IOR('v', 209, int) /* Real image size as used by the camera; tells you whether or not there's a gray border around the image */ #define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize) /* Motorized pan & tilt functions */ #define VIDIOCPWCMPTRESET _IOW('v', 211, int) #define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range) #define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles) #define VIDIOCPWCMPTGANGLE _IOR('v', 212, struct pwc_mpt_angles) #define VIDIOCPWCMPTSTATUS _IOR('v', 213, struct pwc_mpt_status) /* Get the USB set-video command; needed for initializing libpwcx */ #define VIDIOCPWCGVIDCMD _IOR('v', 215, struct pwc_video_command) struct pwc_table_init_buffer { int len; char *buffer; }; #define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer) /* * This is private command used when communicating with v4l2. * In the future all private ioctl will be remove/replace to * use interface offer by v4l2. */ #define V4L2_CID_PRIVATE_SAVE_USER (V4L2_CID_PRIVATE_BASE + 0) #define V4L2_CID_PRIVATE_RESTORE_USER (V4L2_CID_PRIVATE_BASE + 1) #define V4L2_CID_PRIVATE_RESTORE_FACTORY (V4L2_CID_PRIVATE_BASE + 2) #define V4L2_CID_PRIVATE_COLOUR_MODE (V4L2_CID_PRIVATE_BASE + 3) #define V4L2_CID_PRIVATE_AUTOCONTOUR (V4L2_CID_PRIVATE_BASE + 4) #define V4L2_CID_PRIVATE_CONTOUR (V4L2_CID_PRIVATE_BASE + 5) #define V4L2_CID_PRIVATE_BACKLIGHT (V4L2_CID_PRIVATE_BASE + 6) #define V4L2_CID_PRIVATE_FLICKERLESS (V4L2_CID_PRIVATE_BASE + 7) #define V4L2_CID_PRIVATE_NOISE_REDUCTION (V4L2_CID_PRIVATE_BASE + 8) struct pwc_raw_frame { unsigned short type; /* type of the webcam */ unsigned short vbandlength; /* Size of 4lines compressed (used by the decompressor) */ unsigned char cmd[4]; /* the four byte of the command (in case of nala version, only the first 3 bytes is filled) */ #ifndef __cplusplus unsigned char rawframe[0]; /* frame_size = H/4*vbandlength */ #endif } __attribute__ ((packed)); #endif indi-0.5/src/webcam/ccvt_types.h0000644000175000017500000000275210605175707014510 0ustar jrjr/* CCVT: ColourConVerT: simple library for converting colourspaces Copyright (C) 2002 Nemosoft Unv. Email:athomas@nemsoft.co.uk 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA For questions, remarks, patches, etc. for this program, the author can be reached at nemosoft@smcc.demon.nl. */ #ifndef CCVT_TYPES_H #define CCVT_TYPES_H typedef struct { unsigned char b; unsigned char g; unsigned char r; unsigned char z; } PIXTYPE_bgr32; typedef struct { unsigned char b; unsigned char g; unsigned char r; } PIXTYPE_bgr24; typedef struct { unsigned char r; unsigned char g; unsigned char b; unsigned char z; } PIXTYPE_rgb32; typedef struct { unsigned char r; unsigned char g; unsigned char b; } PIXTYPE_rgb24; #define SAT(c) \ if (c & (~255)) { if (c < 0) c = 0; else c = 255; } #endif indi-0.5/src/webcam/port.h0000644000175000017500000001013310605175707013301 0ustar jrjr/* libcqcam - shared Color Quickcam routines * Copyright (C) 1996-1998 by Patrick Reynolds * Email: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ // I/O ports wrapper definitions and prototypes // This file might need tweaking if you're trying to port my code to other // x86 Unix platforms. Code is already available for Linux, FreeBSD, and // QNX; see the Makefile. // // QNX code by: Anders Arpteg // FreeBSD code by: Patrick Reynolds and Charles // Henrich // Inlining implemented by: Philip Blundell #ifndef PORT_H #define PORT_H //#include "config.h" #include #ifdef __linux__ #if !defined(arm) && !defined(__hppa__) && !defined(__sparc__) && !defined(__ppc__) && !defined(__powerpc__) && !defined(__s390__) && !defined(__s390x__) && !defined(__mips__) && !defined(__mc68000__) #include #endif /* !arm */ #elif defined(QNX) #include #elif defined(__FreeBSD__) #include #include #elif defined(BSDI) #include #elif defined(OPENBSD) #include #elif defined(LYNX) #include "lynx-io.h" #elif defined(SOLARIS) #include "solaris-io.h" #else #error Please define a platform in the Makefile #endif #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__) static char ports_temp; #ifdef inb #undef inb #endif /* inb */ #define inb(port) \ lseek(devport, port, SEEK_SET), \ read(devport, &ports_temp, 1), \ ports_temp #ifdef outb #undef outb #endif /* inb */ #define outb(data, port) \ lseek(devport, port, SEEK_SET); \ ports_temp = data; \ write(devport, &ports_temp, 1); #endif /* arm, hppa */ class port_t { public: port_t(int iport); ~port_t(void); inline int read_data(void) { return inb(port); } inline int read_status(void) { return inb(port1); } inline int read_control(void) { return inb(port2); } #if defined(LINUX) || defined(LYNX) inline void write_data(int data) { outb(data, port); } inline void write_control(int data) { outb(control_reg = data, port2); } inline void setbit_control(int data) { outb(control_reg |= data, port2); } inline void clearbit_control(int data) { outb(control_reg &= ~data, port2); } #else // Solaris, QNX, and *BSD use (port, data) instead inline void write_data(int data) { outb(port, data); } inline void write_control(int data) { outb(port2, control_reg = data); } inline void setbit_control(int data) { outb(port2, control_reg |= data); } inline void clearbit_control(int data) { outb(port2, control_reg &= ~data); } #endif inline int get_port() { return port; } inline operator bool () const { return port != -1; } private: int port; // number of the base port int port1; // port+1, precalculated for speed int port2; // port+2, precalculated for speed int control_reg; // current contents of the control register #ifdef LOCKING int lock_fd; int lock(int portnum); void unlock(int portnum); #endif #ifdef FREEBSD FILE *devio; #endif #if defined(__linux__) && (defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__)) int devport; #endif }; #endif indi-0.5/src/webcam/ccvt.h0000644000175000017500000001630210605175707013260 0ustar jrjr/* CCVT: ColourConVerT: simple library for converting colourspaces Copyright (C) 2002 Nemosoft Unv. Email:athomas@nemsoft.co.uk 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA For questions, remarks, patches, etc. for this program, the author can be reached at nemosoft@smcc.demon.nl. */ /* $Log$ Revision 1.4 2005/04/29 16:51:20 mutlaqja Adding initial support for Video 4 Linux 2 drivers. This mean that KStars can probably control Meade Lunar Planetary Imager (LPI). V4L2 requires a fairly recent kernel (> 2.6.9) and many drivers don't fully support it yet. It will take sometime. KStars still supports V4L1 and will continue so until V4L1 is obselete. Please test KStars video drivers if you can. Any comments welcomed. CCMAIL: kstars-devel@kde.org Revision 1.3 2004/06/26 23:12:03 mutlaqja Hopefully this will fix compile issues on 64bit archs, and FreeBSD, among others. The assembly code is replaced with a more portable, albeit slower C implementation. I imported the videodev.h header after cleaning it for user space. Anyone who has problems compiling this, please report the problem to kstars-devel@kde.org I noticed one odd thing after updating my kdelibs, the LEDs don't change color when state is changed. Try that by starting any INDI device, and hit connect, if the LED turns to yellow and back to grey then it works fine, otherwise, we've got a problem. CCMAIL: kstars-devel@kde.org Revision 1.10 2003/10/24 16:55:18 nemosoft removed erronous log messages Revision 1.9 2002/11/03 22:46:25 nemosoft Adding various RGB to RGB functions. Adding proper copyright header too. Revision 1.8 2002/04/14 01:00:27 nemosoft Finishing touches: adding const, adding libs for 'show' */ #ifndef CCVT_H #define CCVT_H #ifdef __cplusplus extern "C" { #endif /* Colour ConVerT: going from one colour space to another. ** NOTE: the set of available functions is far from complete! ** Format descriptions: 420i = "4:2:0 interlaced" YYYY UU YYYY UU even lines YYYY VV YYYY VV odd lines U/V data is subsampled by 2 both in horizontal and vertical directions, and intermixed with the Y values. 420p = "4:2:0 planar" YYYYYYYY N lines UUUU N/2 lines VVVV N/2 lines U/V is again subsampled, but all the Ys, Us and Vs are placed together in separate buffers. The buffers may be placed in one piece of contiguous memory though, with Y buffer first, followed by U, followed by V. yuyv = "4:2:2 interlaced" YUYV YUYV YUYV ... N lines The U/V data is subsampled by 2 in horizontal direction only. bgr24 = 3 bytes per pixel, in the order Blue Green Red (whoever came up with that idea...) rgb24 = 3 bytes per pixel, in the order Red Green Blue (which is sensible) rgb32 = 4 bytes per pixel, in the order Red Green Blue Alpha, with Alpha really being a filler byte (0) bgr32 = last but not least, 4 bytes per pixel, in the order Blue Green Red Alpha, Alpha again a filler byte (0) */ /* 4:2:0 YUV planar to RGB/BGR */ void ccvt_420p_bgr24(int width, int height, const void *src, void *dst); void ccvt_420p_rgb24(int width, int height, const void *src, void *dst); void ccvt_420p_bgr32(int width, int height, const void *src, void *dst); void ccvt_420p_rgb32(int width, int height, const void *src, void *dst); /* 4:2:2 YUYV interlaced to RGB/BGR */ void ccvt_yuyv_rgb32(int width, int height, const void *src, void *dst); void ccvt_yuyv_bgr32(int width, int height, const void *src, void *dst); /* 4:2:2 YUYV interlaced to 4:2:0 YUV planar */ void ccvt_yuyv_420p(int width, int height, const void *src, void *dsty, void *dstu, void *dstv); /* RGB/BGR to 4:2:0 YUV interlaced */ /* RGB/BGR to 4:2:0 YUV planar */ void ccvt_rgb24_420p(int width, int height, const void *src, void *dsty, void *dstu, void *dstv); void ccvt_bgr24_420p(int width, int height, const void *src, void *dsty, void *dstu, void *dstv); /* RGB/BGR to RGB/BGR */ void ccvt_bgr24_bgr32(int width, int height, const void *const src, void *const dst); void ccvt_bgr24_rgb32(int width, int height, const void *const src, void *const dst); void ccvt_bgr32_bgr24(int width, int height, const void *const src, void *const dst); void ccvt_bgr32_rgb24(int width, int height, const void *const src, void *const dst); void ccvt_rgb24_bgr32(int width, int height, const void *const src, void *const dst); void ccvt_rgb24_rgb32(int width, int height, const void *const src, void *const dst); void ccvt_rgb32_bgr24(int width, int height, const void *const src, void *const dst); void ccvt_rgb32_rgb24(int width, int height, const void *const src, void *const dst); int RGB2YUV (int x_dim, int y_dim, void *bmp, void *y_out, void *u_out, void *v_out, int flip); /* * BAYER2RGB24 ROUTINE TAKEN FROM: * * Sonix SN9C101 based webcam basic I/F routines * Copyright (C) 2004 Takafumi Mizuno * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ void bayer2rgb24(unsigned char *dst, unsigned char *src, long int WIDTH, long int HEIGHT); #ifdef __cplusplus } #endif enum Options { ioNoBlock=(1<<0), ioUseSelect=(1<<1), haveBrightness=(1<<2), haveContrast=(1<<3), haveHue=(1<<4), haveColor=(1<<5), haveWhiteness=(1<<6) }; #endif indi-0.5/src/webcam/v4l2_base.cpp0000644000175000017500000007602710605175707014447 0ustar jrjr/* Copyright (C) 2005 by Jasem Mutlaq Based on V4L 2 Example http://v4l2spec.bytesex.org/spec-single/v4l2.html#CAPTURE-EXAMPLE This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include /* for videodev2.h */ #include "ccvt.h" #include "v4l2_base.h" #include "../eventloop.h" #include "../indidevapi.h" #define ERRMSGSIZ 1024 #define CLEAR(x) memset (&(x), 0, sizeof (x)) using namespace std; V4L2_Base::V4L2_Base() { frameRate=10; selectCallBackID = -1; dropFrame = false; xmax = xmin = 160; ymax = ymin = 120; io = IO_METHOD_MMAP; fd = -1; buffers = NULL; n_buffers = 0; YBuf = NULL; UBuf = NULL; VBuf = NULL; colorBuffer = NULL; rgb24_buffer = NULL; callback = NULL; } V4L2_Base::~V4L2_Base() { delete (YBuf); delete (UBuf); delete (VBuf); delete (colorBuffer); delete (rgb24_buffer); } int V4L2_Base::xioctl(int fd, int request, void *arg) { int r; do r = ioctl (fd, request, arg); while (-1 == r && EINTR == errno); return r; } int V4L2_Base::errno_exit(const char *s, char *errmsg) { fprintf (stderr, "%s error %d, %s\n", s, errno, strerror (errno)); snprintf(errmsg, ERRMSGSIZ, "%s error %d, %s\n", s, errno, strerror (errno)); return -1; } int V4L2_Base::connectCam(const char * devpath, char *errmsg , int pixelFormat , int width , int height ) { frameRate=10; selectCallBackID = -1; dropFrame = false; if (open_device (devpath, errmsg) < 0) return -1; if (init_device(errmsg, pixelFormat, width, height) < 0) return -1; cerr << "V4L 2 - All successful, returning\n"; return fd; } void V4L2_Base::disconnectCam() { char errmsg[ERRMSGSIZ]; delete YBuf; delete UBuf; delete VBuf; YBuf = UBuf = VBuf = NULL; if (selectCallBackID != -1) rmCallback(selectCallBackID); stop_capturing (errmsg); uninit_device (errmsg); close_device (); fprintf(stderr, "Disconnect cam\n"); } int V4L2_Base::read_frame(char *errmsg) { struct v4l2_buffer buf; unsigned int i; //cerr << "in read Frame" << endl; switch (io) { case IO_METHOD_READ: if (-1 == read (fd, buffers[0].start, buffers[0].length)) { switch (errno) { case EAGAIN: return 0; case EIO: /* Could ignore EIO, see spec. */ /* fall through */ default: return errno_exit ("read", errmsg); } } //process_image (buffers[0].start); break; case IO_METHOD_MMAP: CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) { switch (errno) { case EAGAIN: return 0; case EIO: /* Could ignore EIO, see spec. */ /* fall through */ default: return errno_exit ("VIDIOC_DQBUF", errmsg); } } assert (buf.index < n_buffers); switch (fmt.fmt.pix.pixelformat) { case V4L2_PIX_FMT_YUV420: memcpy(YBuf,((unsigned char *) buffers[buf.index].start), fmt.fmt.pix.width * fmt.fmt.pix.height); memcpy(UBuf,((unsigned char *) buffers[buf.index].start) + fmt.fmt.pix.width * fmt.fmt.pix.height, (fmt.fmt.pix.width/2) * (fmt.fmt.pix.height/2)); memcpy(VBuf,((unsigned char *) buffers[buf.index].start) + fmt.fmt.pix.width * fmt.fmt.pix.height + (fmt.fmt.pix.width/2) * (fmt.fmt.pix.height/2), (fmt.fmt.pix.width/2) * (fmt.fmt.pix.width/2)); break; case V4L2_PIX_FMT_YUYV: ccvt_yuyv_420p( fmt.fmt.pix.width , fmt.fmt.pix.height, buffers[buf.index].start, YBuf, UBuf, VBuf); break; case V4L2_PIX_FMT_RGB24: RGB2YUV(fmt.fmt.pix.width, fmt.fmt.pix.height, buffers[buf.index].start, YBuf, UBuf, VBuf, 0); break; case V4L2_PIX_FMT_SBGGR8: bayer2rgb24(rgb24_buffer, ((unsigned char *) buffers[buf.index].start), fmt.fmt.pix.width, fmt.fmt.pix.height); break; } if (-1 == xioctl (fd, VIDIOC_QBUF, &buf)) return errno_exit ("VIDIOC_QBUF", errmsg); /*if (dropFrame) { dropFrame = false; return 0; } */ /* Call provided callback function if any */ if (callback) (*callback)(uptr); break; case IO_METHOD_USERPTR: CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_USERPTR; if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) { switch (errno) { case EAGAIN: return 0; case EIO: /* Could ignore EIO, see spec. */ /* fall through */ default: errno_exit ("VIDIOC_DQBUF", errmsg); } } for (i = 0; i < n_buffers; ++i) if (buf.m.userptr == (unsigned long) buffers[i].start && buf.length == buffers[i].length) break; assert (i < n_buffers); //process_image ((void *) buf.m.userptr); if (-1 == xioctl (fd, VIDIOC_QBUF, &buf)) errno_exit ("VIDIOC_QBUF", errmsg); break; } return 0; } int V4L2_Base::stop_capturing(char *errmsg) { enum v4l2_buf_type type; switch (io) { case IO_METHOD_READ: /* Nothing to do. */ break; case IO_METHOD_MMAP: case IO_METHOD_USERPTR: type = V4L2_BUF_TYPE_VIDEO_CAPTURE; IERmCallback(selectCallBackID); selectCallBackID = -1; // N.B. I used this as a hack to solve a problem with capturing a frame // long time ago. I recently tried taking this hack off, and it worked fine! //dropFrame = true; if (-1 == xioctl (fd, VIDIOC_STREAMOFF, &type)) return errno_exit ("VIDIOC_STREAMOFF", errmsg); break; } return 0; } int V4L2_Base::start_capturing(char * errmsg) { unsigned int i; enum v4l2_buf_type type; switch (io) { case IO_METHOD_READ: /* Nothing to do. */ break; case IO_METHOD_MMAP: for (i = 0; i < n_buffers; ++i) { struct v4l2_buffer buf; CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (-1 == xioctl (fd, VIDIOC_QBUF, &buf)) return errno_exit ("VIDIOC_QBUF", errmsg); } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == xioctl (fd, VIDIOC_STREAMON, &type)) return errno_exit ("VIDIOC_STREAMON", errmsg); selectCallBackID = IEAddCallback(fd, newFrame, this); break; case IO_METHOD_USERPTR: for (i = 0; i < n_buffers; ++i) { struct v4l2_buffer buf; CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_USERPTR; buf.m.userptr = (unsigned long) buffers[i].start; buf.length = buffers[i].length; if (-1 == xioctl (fd, VIDIOC_QBUF, &buf)) return errno_exit ("VIDIOC_QBUF", errmsg); } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == xioctl (fd, VIDIOC_STREAMON, &type)) return errno_exit ("VIDIOC_STREAMON", errmsg); break; } return 0; } void V4L2_Base::newFrame(int /*fd*/, void *p) { char errmsg[ERRMSGSIZ]; ( (V4L2_Base *) (p))->read_frame(errmsg); } int V4L2_Base::uninit_device(char *errmsg) { switch (io) { case IO_METHOD_READ: free (buffers[0].start); break; case IO_METHOD_MMAP: for (unsigned int i = 0; i < n_buffers; ++i) if (-1 == munmap (buffers[i].start, buffers[i].length)) return errno_exit ("munmap", errmsg); break; case IO_METHOD_USERPTR: for (unsigned int i = 0; i < n_buffers; ++i) free (buffers[i].start); break; } free (buffers); return 0; } void V4L2_Base::init_read(unsigned int buffer_size) { buffers = (buffer *) calloc (1, sizeof (*buffers)); if (!buffers) { fprintf (stderr, "Out of memory\n"); exit (EXIT_FAILURE); } buffers[0].length = buffer_size; buffers[0].start = malloc (buffer_size); if (!buffers[0].start) { fprintf (stderr, "Out of memory\n"); exit (EXIT_FAILURE); } } int V4L2_Base::init_mmap(char *errmsg) { struct v4l2_requestbuffers req; CLEAR (req); req.count = 4; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) { if (EINVAL == errno) { fprintf (stderr, "%s does not support " "memory mapping\n", dev_name); snprintf(errmsg, ERRMSGSIZ, "%s does not support " "memory mapping\n", dev_name); return -1; } else { return errno_exit ("VIDIOC_REQBUFS", errmsg); } } if (req.count < 2) { fprintf (stderr, "Insufficient buffer memory on %s\n", dev_name); snprintf(errmsg, ERRMSGSIZ, "Insufficient buffer memory on %s\n", dev_name); return -1; } buffers = (buffer *) calloc (req.count, sizeof (*buffers)); if (!buffers) { fprintf (stderr, "buffers. Out of memory\n"); strncpy(errmsg, "buffers. Out of memory\n", ERRMSGSIZ); return -1; } for (n_buffers = 0; n_buffers < req.count; ++n_buffers) { struct v4l2_buffer buf; CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = n_buffers; if (-1 == xioctl (fd, VIDIOC_QUERYBUF, &buf)) return errno_exit ("VIDIOC_QUERYBUF", errmsg); buffers[n_buffers].length = buf.length; buffers[n_buffers].start = mmap (NULL /* start anywhere */, buf.length, PROT_READ | PROT_WRITE /* required */, MAP_SHARED /* recommended */, fd, buf.m.offset); if (MAP_FAILED == buffers[n_buffers].start) return errno_exit ("mmap", errmsg); } return 0; } void V4L2_Base::init_userp(unsigned int buffer_size) { struct v4l2_requestbuffers req; char errmsg[ERRMSGSIZ]; CLEAR (req); req.count = 4; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_USERPTR; if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) { if (EINVAL == errno) { fprintf (stderr, "%s does not support " "user pointer i/o\n", dev_name); exit (EXIT_FAILURE); } else { errno_exit ("VIDIOC_REQBUFS", errmsg); } } buffers = (buffer *) calloc (4, sizeof (*buffers)); if (!buffers) { fprintf (stderr, "Out of memory\n"); exit (EXIT_FAILURE); } for (n_buffers = 0; n_buffers < 4; ++n_buffers) { buffers[n_buffers].length = buffer_size; buffers[n_buffers].start = malloc (buffer_size); if (!buffers[n_buffers].start) { fprintf (stderr, "Out of memory\n"); exit (EXIT_FAILURE); } } } int V4L2_Base::init_device(char *errmsg, int pixelFormat , int width, int height) { unsigned int min; if (-1 == xioctl (fd, VIDIOC_QUERYCAP, &cap)) { if (EINVAL == errno) { fprintf (stderr, "%s is no V4L2 device\n", dev_name); snprintf(errmsg, ERRMSGSIZ, "%s is no V4L2 device\n", dev_name); return -1; } else { return errno_exit ("VIDIOC_QUERYCAP", errmsg); } } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { fprintf (stderr, "%s is no video capture device\n", dev_name); snprintf(errmsg, ERRMSGSIZ, "%s is no video capture device\n", dev_name); return -1; } switch (io) { case IO_METHOD_READ: if (!(cap.capabilities & V4L2_CAP_READWRITE)) { fprintf (stderr, "%s does not support read i/o\n", dev_name); snprintf(errmsg, ERRMSGSIZ, "%s does not support read i/o\n", dev_name); return -1; } break; case IO_METHOD_MMAP: case IO_METHOD_USERPTR: if (!(cap.capabilities & V4L2_CAP_STREAMING)) { fprintf (stderr, "%s does not support streaming i/o\n", dev_name); snprintf(errmsg, ERRMSGSIZ, "%s does not support streaming i/o\n", dev_name); return -1; } break; } /* Select video input, video standard and tune here. */ cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) { /* Errors ignored. */ } crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop.c = cropcap.defrect; /* reset to default */ if (-1 == xioctl (fd, VIDIOC_S_CROP, &crop)) { switch (errno) { case EINVAL: /* Cropping not supported. */ break; default: /* Errors ignored. */ break; } } CLEAR (fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == xioctl (fd, VIDIOC_G_FMT, &fmt)) return errno_exit ("VIDIOC_G_FMT", errmsg); fmt.fmt.pix.width = (width == -1) ? fmt.fmt.pix.width : width; fmt.fmt.pix.height = (height == -1) ? fmt.fmt.pix.height : height; fmt.fmt.pix.pixelformat = (pixelFormat == -1) ? fmt.fmt.pix.pixelformat : pixelFormat; //fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt)) return errno_exit ("VIDIOC_S_FMT", errmsg); /* Note VIDIOC_S_FMT may change width and height. */ /* Buggy driver paranoia. */ min = fmt.fmt.pix.width * 2; if (fmt.fmt.pix.bytesperline < min) fmt.fmt.pix.bytesperline = min; min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height; if (fmt.fmt.pix.sizeimage < min) fmt.fmt.pix.sizeimage = min; /* Let's get the actual size */ CLEAR(fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == xioctl (fd, VIDIOC_G_FMT, &fmt)) return errno_exit ("VIDIOC_G_FMT", errmsg); cerr << "width: " << fmt.fmt.pix.width << " - height: " << fmt.fmt.pix.height << endl; switch (pixelFormat) { case V4L2_PIX_FMT_YUV420: cerr << "pixel format: V4L2_PIX_FMT_YUV420" << endl; break; case V4L2_PIX_FMT_YUYV: cerr << "pixel format: V4L2_PIX_FMT_YUYV" << endl; break; case V4L2_PIX_FMT_RGB24: cerr << "pixel format: V4L2_PIX_FMT_RGB24" << endl; break; case V4L2_PIX_FMT_SBGGR8: cerr << "pixel format: V4L2_PIX_FMT_SBGGR8" << endl; break; } findMinMax(); allocBuffers(); switch (io) { case IO_METHOD_READ: init_read (fmt.fmt.pix.sizeimage); break; case IO_METHOD_MMAP: return init_mmap(errmsg); break; case IO_METHOD_USERPTR: init_userp (fmt.fmt.pix.sizeimage); break; } return 0; } void V4L2_Base::close_device(void) { char errmsg[ERRMSGSIZ]; if (-1 == close (fd)) errno_exit ("close", errmsg); fd = -1; } int V4L2_Base::open_device(const char *devpath, char *errmsg) { struct stat st; strncpy(dev_name, devpath, 64); if (-1 == stat (dev_name, &st)) { fprintf (stderr, "Cannot identify '%s': %d, %s\n", dev_name, errno, strerror (errno)); snprintf(errmsg, ERRMSGSIZ, "Cannot identify '%s': %d, %s\n", dev_name, errno, strerror (errno)); return -1; } if (!S_ISCHR (st.st_mode)) { fprintf (stderr, "%s is no device\n", dev_name); snprintf(errmsg, ERRMSGSIZ, "%s is no device\n", dev_name); return -1; } fd = open (dev_name, O_RDWR /* required */ | O_NONBLOCK, 0); if (-1 == fd) { fprintf (stderr, "Cannot open '%s': %d, %s\n", dev_name, errno, strerror (errno)); snprintf(errmsg, ERRMSGSIZ, "Cannot open '%s': %d, %s\n", dev_name, errno, strerror (errno)); return -1; } return 0; } int V4L2_Base::getWidth() { return fmt.fmt.pix.width; } int V4L2_Base::getHeight() { return fmt.fmt.pix.height; } void V4L2_Base::setFPS(int fps) { frameRate = 15;//fps; } int V4L2_Base::getFPS() { return 15; } char * V4L2_Base::getDeviceName() { return ((char *) cap.card); } void V4L2_Base::allocBuffers() { delete (YBuf); YBuf = NULL; delete (UBuf); UBuf = NULL; delete (VBuf); VBuf = NULL; delete (colorBuffer); colorBuffer = NULL; delete (rgb24_buffer); rgb24_buffer = NULL; YBuf= new unsigned char[ fmt.fmt.pix.width * fmt.fmt.pix.height]; UBuf= new unsigned char[ fmt.fmt.pix.width * fmt.fmt.pix.height]; VBuf= new unsigned char[ fmt.fmt.pix.width * fmt.fmt.pix.height]; colorBuffer = new unsigned char[fmt.fmt.pix.width * fmt.fmt.pix.height * 4]; if (fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_SBGGR8) rgb24_buffer = new unsigned char[fmt.fmt.pix.width * fmt.fmt.pix.height * 3]; } void V4L2_Base::getMaxMinSize(int & x_max, int & y_max, int & x_min, int & y_min) { x_max = xmax; y_max = ymax; x_min = xmin; y_min = ymin; } int V4L2_Base::setSize(int x, int y) { char errmsg[ERRMSGSIZ]; int oldW, oldH; oldW = fmt.fmt.pix.width; oldH = fmt.fmt.pix.height; fmt.fmt.pix.width = x; fmt.fmt.pix.height = y; if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt)) { fmt.fmt.pix.width = oldW; fmt.fmt.pix.height = oldH; return errno_exit ("VIDIOC_S_FMT", errmsg); } /* PWC bug? It seems that setting the "wrong" width and height will mess something in the driver. Only 160x120, 320x280, and 640x480 are accepted. If I try to set it for example to 300x200, it wii get set to 320x280, which is fine, but then the video information is messed up for some reason. */ xioctl (fd, VIDIOC_S_FMT, &fmt); allocBuffers(); return 0; } void V4L2_Base::setContrast(int val) { /*picture_.contrast=val; updatePictureSettings();*/ } int V4L2_Base::getContrast() { return 255;//picture_.contrast; } void V4L2_Base::setBrightness(int val) { /*picture_.brightness=val; updatePictureSettings();*/ } int V4L2_Base::getBrightness() { return 255;//picture_.brightness; } void V4L2_Base::setColor(int val) { /*picture_.colour=val; updatePictureSettings();*/ } int V4L2_Base::getColor() { return 255; //picture_.colour; } void V4L2_Base::setHue(int val) { /*picture_.hue=val; updatePictureSettings();*/ } int V4L2_Base::getHue() { return 255;//picture_.hue; } void V4L2_Base::setWhiteness(int val) { /*picture_.whiteness=val; updatePictureSettings();*/ } int V4L2_Base::getWhiteness() { return 255;//picture_.whiteness; } void V4L2_Base::setPictureSettings() { /*if (ioctl(device_, VIDIOCSPICT, &picture_) ) { cerr << "updatePictureSettings" << endl; } ioctl(device_, VIDIOCGPICT, &picture_);*/ } void V4L2_Base::getPictureSettings() { /*if (ioctl(device_, VIDIOCGPICT, &picture_) ) { cerr << "refreshPictureSettings" << endl; }*/ } unsigned char * V4L2_Base::getY() { if (fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_SBGGR8) RGB2YUV(fmt.fmt.pix.width, fmt.fmt.pix.height, rgb24_buffer, YBuf, UBuf, VBuf, 0); return YBuf; } unsigned char * V4L2_Base::getU() { return UBuf; } unsigned char * V4L2_Base::getV() { return VBuf; } unsigned char * V4L2_Base::getColorBuffer() { //cerr << "in get color buffer " << endl; switch (fmt.fmt.pix.pixelformat) { case V4L2_PIX_FMT_YUV420: ccvt_420p_bgr32(fmt.fmt.pix.width, fmt.fmt.pix.height, buffers[0].start, (void*)colorBuffer); break; case V4L2_PIX_FMT_YUYV: ccvt_yuyv_bgr32(fmt.fmt.pix.width, fmt.fmt.pix.height, buffers[0].start, (void*)colorBuffer); break; case V4L2_PIX_FMT_RGB24: ccvt_rgb24_bgr32(fmt.fmt.pix.width, fmt.fmt.pix.height, buffers[0].start, (void*)colorBuffer); break; case V4L2_PIX_FMT_SBGGR8: ccvt_rgb24_bgr32(fmt.fmt.pix.width, fmt.fmt.pix.height, rgb24_buffer, (void*)colorBuffer); break; default: break; } return colorBuffer; } void V4L2_Base::registerCallback(WPF *fp, void *ud) { callback = fp; uptr = ud; } void V4L2_Base::findMinMax() { char errmsg[ERRMSGSIZ]; struct v4l2_format tryfmt; CLEAR(tryfmt); xmin = xmax = fmt.fmt.pix.width; ymin = ymax = fmt.fmt.pix.height; tryfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; tryfmt.fmt.pix.width = 10; tryfmt.fmt.pix.height = 10; tryfmt.fmt.pix.pixelformat = fmt.fmt.pix.pixelformat; tryfmt.fmt.pix.field = fmt.fmt.pix.field; if (-1 == xioctl (fd, VIDIOC_TRY_FMT, &tryfmt)) { errno_exit ("VIDIOC_TRY_FMT 1", errmsg); return; } xmin = tryfmt.fmt.pix.width; ymin = tryfmt.fmt.pix.height; tryfmt.fmt.pix.width = 1600; tryfmt.fmt.pix.height = 1200; if (-1 == xioctl (fd, VIDIOC_TRY_FMT, &tryfmt)) { errno_exit ("VIDIOC_TRY_FMT 2", errmsg); return; } xmax = tryfmt.fmt.pix.width; ymax = tryfmt.fmt.pix.height; cerr << "Min X: " << xmin << " - Max X: " << xmax << " - Min Y: " << ymin << " - Max Y: " << ymax << endl; } void V4L2_Base::enumerate_ctrl (void) { char errmsg[ERRMSGSIZ]; CLEAR(queryctrl); for (queryctrl.id = V4L2_CID_BASE; queryctrl.id < V4L2_CID_LASTP1; queryctrl.id++) { if (0 == xioctl (fd, VIDIOC_QUERYCTRL, &queryctrl)) { cerr << "Control " << queryctrl.name << endl; if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) continue; cerr << "Control " << queryctrl.name << endl; if (queryctrl.type == V4L2_CTRL_TYPE_MENU) enumerate_menu (); } else { if (errno == EINVAL) continue; errno_exit("VIDIOC_QUERYCTRL", errmsg); return; } } for (queryctrl.id = V4L2_CID_PRIVATE_BASE; ; queryctrl.id++) { if (0 == xioctl (fd, VIDIOC_QUERYCTRL, &queryctrl)) { cerr << "Private Control " << queryctrl.name << endl; if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) continue; if (queryctrl.type == V4L2_CTRL_TYPE_MENU) enumerate_menu (); } else { if (errno == EINVAL) break; errno_exit ("VIDIOC_QUERYCTRL", errmsg); return; } } } void V4L2_Base::enumerate_menu (void) { char errmsg[ERRMSGSIZ]; cerr << " Menu items:" << endl; CLEAR(querymenu); querymenu.id = queryctrl.id; for (querymenu.index = queryctrl.minimum; querymenu.index <= queryctrl.maximum; querymenu.index++) { if (0 == xioctl (fd, VIDIOC_QUERYMENU, &querymenu)) { cerr << " " << querymenu.name << endl; } else { errno_exit("VIDIOC_QUERYMENU", errmsg); return; } } } int V4L2_Base::query_ctrl(unsigned int ctrl_id, double & ctrl_min, double & ctrl_max, double & ctrl_step, double & ctrl_value, char *errmsg) { struct v4l2_control control; CLEAR(queryctrl); queryctrl.id = ctrl_id; if (-1 == ioctl (fd, VIDIOC_QUERYCTRL, &queryctrl)) { if (errno != EINVAL) return errno_exit ("VIDIOC_QUERYCTRL", errmsg); else { cerr << "#" << ctrl_id << " is not supported" << endl; snprintf(errmsg, ERRMSGSIZ, "# %d is not supported", ctrl_id); return -1; } } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { cerr << "#" << ctrl_id << " is disabled" << endl; snprintf(errmsg, ERRMSGSIZ, "# %d is disabled", ctrl_id); return -1; } ctrl_min = queryctrl.minimum; ctrl_max = queryctrl.maximum; ctrl_step = queryctrl.step; ctrl_value = queryctrl.default_value; /* Get current value */ CLEAR(control); control.id = ctrl_id; if (0 == xioctl(fd, VIDIOC_G_CTRL, &control)) ctrl_value = control.value; cerr << queryctrl.name << " -- min: " << ctrl_min << " max: " << ctrl_max << " step: " << ctrl_step << " value: " << ctrl_value << endl; return 0; } int V4L2_Base::queryINTControls(INumberVectorProperty *nvp) { struct v4l2_control control; char errmsg[ERRMSGSIZ]; CLEAR(queryctrl); INumber *numbers = NULL; unsigned int *num_ctrls = NULL; int nnum=0; for (queryctrl.id = V4L2_CID_BASE; queryctrl.id < V4L2_CID_LASTP1; queryctrl.id++) { if (0 == ioctl (fd, VIDIOC_QUERYCTRL, &queryctrl)) { if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { cerr << queryctrl.name << " is disabled." << endl; continue; } if (queryctrl.type == V4L2_CTRL_TYPE_INTEGER) { numbers = (numbers == NULL) ? (INumber *) malloc (sizeof(INumber)) : (INumber *) realloc (numbers, (nnum+1) * sizeof (INumber)); num_ctrls = (num_ctrls == NULL) ? (unsigned int *) malloc (sizeof (unsigned int)) : (unsigned int *) realloc (num_ctrls, (nnum+1) * sizeof (unsigned int)); strncpy(numbers[nnum].name, ((char *) queryctrl.name) , MAXINDINAME); strncpy(numbers[nnum].label, ((char *) queryctrl.name), MAXINDILABEL); strncpy(numbers[nnum].format, "%0.f", MAXINDIFORMAT); numbers[nnum].min = queryctrl.minimum; numbers[nnum].max = queryctrl.maximum; numbers[nnum].step = queryctrl.step; numbers[nnum].value = queryctrl.default_value; /* Get current value if possible */ CLEAR(control); control.id = queryctrl.id; if (0 == xioctl(fd, VIDIOC_G_CTRL, &control)) numbers[nnum].value = control.value; /* Store ID info in INumber. This is the first time ever I make use of aux0!! */ num_ctrls[nnum] = queryctrl.id; cerr << queryctrl.name << " -- min: " << queryctrl.minimum << " max: " << queryctrl.maximum << " step: " << queryctrl.step << " value: " << numbers[nnum].value << endl; nnum++; } } else if (errno != EINVAL) { if(numbers) free(numbers); return errno_exit ("VIDIOC_QUERYCTRL", errmsg); } } for (queryctrl.id = V4L2_CID_PRIVATE_BASE; ; queryctrl.id++) { if (0 == ioctl (fd, VIDIOC_QUERYCTRL, &queryctrl)) { if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { cerr << queryctrl.name << " is disabled." << endl; continue; } if (queryctrl.type == V4L2_CTRL_TYPE_INTEGER) { numbers = (numbers == NULL) ? (INumber *) malloc (sizeof(INumber)) : (INumber *) realloc (numbers, (nnum+1) * sizeof (INumber)); num_ctrls = (num_ctrls == NULL) ? (unsigned int *) malloc (sizeof (unsigned int)) : (unsigned int *) realloc (num_ctrls, (nnum+1) * sizeof (unsigned int)); strncpy(numbers[nnum].name, ((char *) queryctrl.name) , MAXINDINAME); strncpy(numbers[nnum].label, ((char *) queryctrl.name), MAXINDILABEL); strncpy(numbers[nnum].format, "%0.f", MAXINDIFORMAT); numbers[nnum].min = queryctrl.minimum; numbers[nnum].max = queryctrl.maximum; numbers[nnum].step = queryctrl.step; numbers[nnum].value = queryctrl.default_value; /* Get current value if possible */ CLEAR(control); control.id = queryctrl.id; if (0 == xioctl(fd, VIDIOC_G_CTRL, &control)) numbers[nnum].value = control.value; /* Store ID info in INumber. This is the first time ever I make use of aux0!! */ num_ctrls[nnum] = queryctrl.id; nnum++; } } else break; } /* Store numbers in aux0 */ for (int i=0; i < nnum; i++) numbers[i].aux0 = &num_ctrls[i]; nvp->np = numbers; nvp->nnp = nnum; return nnum; } int V4L2_Base::setINTControl(unsigned int ctrl_id, double new_value, char *errmsg) { struct v4l2_control control; CLEAR(control); cerr << "The id is " << ctrl_id << " new value is " << new_value << endl; control.id = ctrl_id; control.value = (int) new_value; if (-1 == xioctl(fd, VIDIOC_S_CTRL, &control)) return errno_exit ("VIDIOC_S_CTRL", errmsg); return 0; } indi-0.5/src/webcam/v4l1_base.cpp0000644000175000017500000003021210605175707014430 0ustar jrjr/* Copyright (C) 2005 by Jasem Mutlaq Email: mutlaqja@ikarustech.com Some code based on qastrocam This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include "ccvt.h" #include "v4l1_base.h" #include "../eventloop.h" #include "../indidevapi.h" #define ERRMSGSIZ 1024 using namespace std; V4L1_Base::V4L1_Base() { frameRate=10; fd=-1; //usingTimer = false; //frameUpdate = true; //selectCallBackID = -1; //timerCallBackID = -1; YBuf = NULL; UBuf = NULL; VBuf = NULL; colorBuffer= NULL; buffer_start=NULL; } V4L1_Base::~V4L1_Base() { delete (YBuf); delete (UBuf); delete (VBuf); delete (colorBuffer); } int V4L1_Base::connectCam(const char * devpath, char *errmsg) { options= (haveBrightness|haveContrast|haveHue|haveColor|haveWhiteness); buffer_start=NULL; frameRate=10; fd=-1; //cerr << "In connect Cam with device " << devpath << endl; if (-1 == (fd=open(devpath, O_RDWR | O_NONBLOCK, 0))) { if (-1 == (fd=open(devpath, O_RDONLY | O_NONBLOCK, 0))) { strncpy(errmsg, strerror(errno), ERRMSGSIZ); cerr << strerror(errno); return -1; } } cerr << "Device opened" << endl; if (fd != -1) { if (-1 == ioctl(fd,VIDIOCGCAP,&capability)) { cerr << "Error: ioctl (VIDIOCGCAP)" << endl; strncpy(errmsg, "ioctl (VIDIOCGCAP)", ERRMSGSIZ); return -1; } if (-1 == ioctl (fd, VIDIOCGWIN, &window)) { cerr << "Error ioctl (VIDIOCGWIN)" << endl; strncpy(errmsg, "ioctl (VIDIOCGWIN)", ERRMSGSIZ); return -1; } if (-1 == ioctl (fd, VIDIOCGPICT, &picture_format)) { cerr << "Error: ioctl (VIDIOCGPICT)" << endl; strncpy(errmsg, "ioctl (VIDIOCGPICT)", ERRMSGSIZ); return -1; } init(0); } cerr << "initial size w:" << window.width << " -- h: " << window.height << endl; /*if (options & ioUseSelect) { selectCallBackID = addCallback(fd, V4L1_Base::staticUpdateFrame, this); cerr << "Using select to wait new frames." << endl; } else { usingTimer = true; timerCallBackID = addTimer(1000/frameRate, V4L1_Base::staticCallFrame, this); cerr << "Using timer to wait new frames.\n"; } */ if (mmapInit() < 0) { strncpy(errmsg, "mmapInit() failed", ERRMSGSIZ); return -1; } cerr << "All successful, returning\n"; return fd; } void V4L1_Base::disconnectCam() { delete YBuf; delete UBuf; delete VBuf; YBuf = UBuf = VBuf = NULL; if (selectCallBackID != -1) rmCallback(selectCallBackID); //if (usingTimer && timerCallBackID != -1) //rmTimer(timerCallBackID); if (munmap (buffer_start, mmap_buffer.size) < 0) fprintf(stderr, "munmap: %s\n", strerror(errno)); if (close(fd) < 0) fprintf(stderr, "close(fd): %s\n", strerror(errno)); fprintf(stderr, "Disconnect cam\n"); } void V4L1_Base::newFrame() { switch (picture_format.palette) { case VIDEO_PALETTE_GREY: memcpy(YBuf,mmapFrame(),window.width * window.height); break; case VIDEO_PALETTE_YUV420P: memcpy(YBuf,mmapFrame(), window.width * window.height); memcpy(UBuf, mmapFrame()+ window.width * window.height, (window.width/2) * (window.height/2)); memcpy(VBuf, mmapFrame()+ window.width * window.height+(window.width/2) * (window.height/2), (window.width/2) * (window.height/2)); break; case VIDEO_PALETTE_YUYV: ccvt_yuyv_420p(window.width,window.height, mmapFrame(), YBuf, UBuf, VBuf); break; case VIDEO_PALETTE_RGB24: RGB2YUV(window.width, window.height, mmapFrame(), YBuf, UBuf, VBuf, 0); break; default: cerr << "invalid palette " <newFrame(); } int V4L1_Base::start_capturing(char * /*errmsg*/) { mmapCapture(); mmapSync(); selectCallBackID = IEAddCallback(fd, updateFrame, this); //newFrame(); return 0; } int V4L1_Base::stop_capturing(char * /*errmsg*/) { IERmCallback(selectCallBackID); selectCallBackID = -1; return 0; } int V4L1_Base::getWidth() { return window.width; } int V4L1_Base::getHeight() { return window.height; } void V4L1_Base::setFPS(int fps) { frameRate = fps; } int V4L1_Base::getFPS() { return frameRate; } char * V4L1_Base::getDeviceName() { return capability.name; } void V4L1_Base::init(int preferedPalette) { if (preferedPalette) { picture_format.palette=preferedPalette; if (0 == ioctl(fd, VIDIOCSPICT, &picture_format)) cerr << "found preferedPalette " << preferedPalette << endl; else { preferedPalette=0; cerr << "preferedPalette " << preferedPalette << " invalid, trying to find one." << endl; } } if (preferedPalette == 0) { do { /* trying VIDEO_PALETTE_YUV420P (Planar) */ picture_format.palette=VIDEO_PALETTE_YUV420P; picture_format.depth=12; if (0 == ioctl(fd, VIDIOCSPICT, &picture_format)) { cerr << "found palette VIDEO_PALETTE_YUV420P" << endl; break; } cerr << "VIDEO_PALETTE_YUV420P not supported." << endl; /* trying VIDEO_PALETTE_YUV420 (interlaced) */ picture_format.palette=VIDEO_PALETTE_YUV420; picture_format.depth=12; if ( 0== ioctl(fd, VIDIOCSPICT, &picture_format)) { cerr << "found palette VIDEO_PALETTE_YUV420" << endl; break; } cerr << "VIDEO_PALETTE_YUV420 not supported." << endl; /* trying VIDEO_PALETTE_RGB24 */ picture_format.palette=VIDEO_PALETTE_RGB24; picture_format.depth=24; if ( 0== ioctl(fd, VIDIOCSPICT, &picture_format)) { cerr << "found palette VIDEO_PALETTE_RGB24" << endl; break; } cerr << "VIDEO_PALETTE_RGB24 not supported." << endl; /* trying VIDEO_PALETTE_GREY */ picture_format.palette=VIDEO_PALETTE_GREY; picture_format.depth=8; if ( 0== ioctl(fd, VIDIOCSPICT, &picture_format)) { cerr << "found palette VIDEO_PALETTE_GREY" << endl; break; } cerr << "VIDEO_PALETTE_GREY not supported." << endl; cerr << "could not find a supported palette." << endl; exit(1); } while (false); } allocBuffers(); } void V4L1_Base::allocBuffers() { delete YBuf; delete UBuf; delete VBuf; delete colorBuffer; YBuf= new unsigned char[window.width * window.height]; UBuf= new unsigned char[window.width * window.height]; VBuf= new unsigned char[window.width * window.height]; colorBuffer = new unsigned char[window.width * window.height * 4]; } void V4L1_Base::checkSize(int & x, int & y) { if (x >= capability.maxwidth && y >= capability.maxheight) { x=capability.maxwidth; y=capability.maxheight; } else if (x>=352 && y >=288) { x=352;y=288; } else if (x>=320 && y >= 240) { x=320;y=240; } else if (x>=176 && y >=144) { x=176;y=144; } else if (x>=160 && y >=120 ) { x=160;y=120; } else { x=capability.minwidth; y=capability.minheight; } } void V4L1_Base::getMaxMinSize(int & xmax, int & ymax, int & xmin, int & ymin) { xmax = capability.maxwidth; ymax = capability.maxheight; xmin = capability.minwidth; ymin = capability.minheight; } bool V4L1_Base::setSize(int x, int y) { int oldX, oldY; checkSize(x,y); oldX = window.width; oldY = window.height; window.width=x; window.height=y; cerr << "New size is x=" << window.width << " " << "y=" << window.height < empty_file.cpp indi-0.5/src/webcam/Makefile.in0000644000175000017500000004240410610536734014214 0ustar jrjr# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/webcam DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) @HAVE_V4L2_FALSE@am__DEPENDENCIES_1 = libwebcam_v4l1_linux.la @HAVE_V4L2_TRUE@am__DEPENDENCIES_1 = libwebcam_v4l2_linux.la libwebcam_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_libwebcam_la_OBJECTS = empty_file.lo libwebcam_la_OBJECTS = $(am_libwebcam_la_OBJECTS) libwebcam_v4l1_linux_la_LIBADD = am_libwebcam_v4l1_linux_la_OBJECTS = PPort.lo port.lo v4l1_base.lo \ v4l1_pwc.lo ccvt_c2.lo ccvt_misc.lo libwebcam_v4l1_linux_la_OBJECTS = \ $(am_libwebcam_v4l1_linux_la_OBJECTS) @HAVE_V4L2_FALSE@am_libwebcam_v4l1_linux_la_rpath = libwebcam_v4l2_linux_la_LIBADD = am_libwebcam_v4l2_linux_la_OBJECTS = PPort.lo port.lo v4l2_base.lo \ ccvt_c2.lo ccvt_misc.lo libwebcam_v4l2_linux_la_OBJECTS = \ $(am_libwebcam_v4l2_linux_la_OBJECTS) @HAVE_V4L2_TRUE@am_libwebcam_v4l2_linux_la_rpath = DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libwebcam_la_SOURCES) $(libwebcam_v4l1_linux_la_SOURCES) \ $(libwebcam_v4l2_linux_la_SOURCES) DIST_SOURCES = $(libwebcam_la_SOURCES) \ $(libwebcam_v4l1_linux_la_SOURCES) \ $(libwebcam_v4l2_linux_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMDEP_FALSE = @AMDEP_FALSE@ AMDEP_TRUE = @AMDEP_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BSD_FALSE = @BSD_FALSE@ BSD_TRUE = @BSD_TRUE@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_SUBDIR = @EXTRA_SUBDIR@ F77 = @F77@ FFLAGS = @FFLAGS@ GREP = @GREP@ HAVE_LIBSBIGUDRV_FALSE = @HAVE_LIBSBIGUDRV_FALSE@ HAVE_LIBSBIGUDRV_TRUE = @HAVE_LIBSBIGUDRV_TRUE@ HAVE_LIBUSB_FALSE = @HAVE_LIBUSB_FALSE@ HAVE_LIBUSB_TRUE = @HAVE_LIBUSB_TRUE@ HAVE_V4L2_FALSE = @HAVE_V4L2_FALSE@ HAVE_V4L2_TRUE = @HAVE_V4L2_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBCFITSIO = @LIBCFITSIO@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSBIGUDRV = @LIBSBIGUDRV@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LINUX_FALSE = @LINUX_FALSE@ LINUX_TRUE = @LINUX_TRUE@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ NULL_FALSE = @NULL_FALSE@ NULL_TRUE = @NULL_TRUE@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_F77 = @ac_ct_F77@ am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ @HAVE_V4L2_FALSE@libwebcam_linux = libwebcam_v4l1_linux.la @HAVE_V4L2_TRUE@libwebcam_linux = libwebcam_v4l2_linux.la noinst_LTLIBRARIES = libwebcam.la $(libwebcam_linux) libwebcam_v4l1_linux_la_SOURCES = PPort.cpp port.cpp v4l1_base.cpp v4l1_pwc.cpp ccvt_c2.c ccvt_misc.c libwebcam_v4l2_linux_la_SOURCES = PPort.cpp port.cpp v4l2_base.cpp ccvt_c2.c ccvt_misc.c libwebcam_la_SOURCES = empty_file.cpp libwebcam_la_LIBADD = $(libwebcam_linux) all: all-am .SUFFIXES: .SUFFIXES: .c .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/webcam/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --gnu src/webcam/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libwebcam.la: $(libwebcam_la_OBJECTS) $(libwebcam_la_DEPENDENCIES) $(CXXLINK) $(libwebcam_la_LDFLAGS) $(libwebcam_la_OBJECTS) $(libwebcam_la_LIBADD) $(LIBS) libwebcam_v4l1_linux.la: $(libwebcam_v4l1_linux_la_OBJECTS) $(libwebcam_v4l1_linux_la_DEPENDENCIES) $(CXXLINK) $(am_libwebcam_v4l1_linux_la_rpath) $(libwebcam_v4l1_linux_la_LDFLAGS) $(libwebcam_v4l1_linux_la_OBJECTS) $(libwebcam_v4l1_linux_la_LIBADD) $(LIBS) libwebcam_v4l2_linux.la: $(libwebcam_v4l2_linux_la_OBJECTS) $(libwebcam_v4l2_linux_la_DEPENDENCIES) $(CXXLINK) $(am_libwebcam_v4l2_linux_la_rpath) $(libwebcam_v4l2_linux_la_LDFLAGS) $(libwebcam_v4l2_linux_la_OBJECTS) $(libwebcam_v4l2_linux_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PPort.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ccvt_c2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ccvt_misc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/empty_file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/port.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v4l1_base.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v4l1_pwc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v4l2_base.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< .cpp.o: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool uninstall-info-am: ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ list='$(DISTFILES)'; for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ esac; \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ dir="/$$dir"; \ $(mkdir_p) "$(distdir)$$dir"; \ else \ dir=''; \ fi; \ if test -d $$d/$$file; then \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-exec-am: install-info: install-info-am install-man: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-info-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-exec \ install-exec-am install-info install-info-am install-man \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-info-am empty_file.cpp: echo > empty_file.cpp # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: indi-0.5/src/webcam/videodev.h0000644000175000017500000003107610605175707014133 0ustar jrjr/* Copyright 2006 Bill Dirks Justin Schoeman et al. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __LINUX_VIDEODEV_H #define __LINUX_VIDEODEV_H #define VID_TYPE_CAPTURE 1 /* Can capture */ #define VID_TYPE_TUNER 2 /* Can tune */ #define VID_TYPE_TELETEXT 4 /* Does teletext */ #define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ #define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ #define VID_TYPE_CLIPPING 32 /* Can clip */ #define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ #define VID_TYPE_SCALES 128 /* Scalable */ #define VID_TYPE_MONOCHROME 256 /* Monochrome only */ #define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ #define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ #define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ #define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ #define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ struct video_capability { char name[32]; int type; int channels; /* Num channels */ int audios; /* Num audio devices */ int maxwidth; /* Supported width */ int maxheight; /* And height */ int minwidth; /* Supported width */ int minheight; /* And height */ }; struct video_channel { int channel; char name[32]; int tuners; unsigned int flags; #define VIDEO_VC_TUNER 1 /* Channel has a tuner */ #define VIDEO_VC_AUDIO 2 /* Channel has audio */ unsigned short type; #define VIDEO_TYPE_TV 1 #define VIDEO_TYPE_CAMERA 2 unsigned short norm; /* Norm set by channel */ }; struct video_tuner { int tuner; char name[32]; unsigned long rangelow, rangehigh; /* Tuner range */ unsigned int flags; #define VIDEO_TUNER_PAL 1 #define VIDEO_TUNER_NTSC 2 #define VIDEO_TUNER_SECAM 4 #define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */ #define VIDEO_TUNER_NORM 16 /* Tuner can set norm */ #define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */ #define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */ #define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */ unsigned short mode; /* PAL/NTSC/SECAM/OTHER */ #define VIDEO_MODE_PAL 0 #define VIDEO_MODE_NTSC 1 #define VIDEO_MODE_SECAM 2 #define VIDEO_MODE_AUTO 3 unsigned short signal; /* Signal strength 16bit scale */ }; struct video_picture { unsigned short brightness; unsigned short hue; unsigned short colour; unsigned short contrast; unsigned short whiteness; /* Black and white only */ unsigned short depth; /* Capture depth */ unsigned short palette; /* Palette in use */ #define VIDEO_PALETTE_GREY 1 /* Linear greyscale */ #define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */ #define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */ #define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */ #define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */ #define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */ #define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */ #define VIDEO_PALETTE_YUYV 8 #define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */ #define VIDEO_PALETTE_YUV420 10 #define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */ #define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */ #define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */ #define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */ #define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */ #define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */ #define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */ #define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */ }; struct video_audio { int audio; /* Audio channel */ unsigned short volume; /* If settable */ unsigned short bass, treble; unsigned int flags; #define VIDEO_AUDIO_MUTE 1 #define VIDEO_AUDIO_MUTABLE 2 #define VIDEO_AUDIO_VOLUME 4 #define VIDEO_AUDIO_BASS 8 #define VIDEO_AUDIO_TREBLE 16 #define VIDEO_AUDIO_BALANCE 32 char name[16]; #define VIDEO_SOUND_MONO 1 #define VIDEO_SOUND_STEREO 2 #define VIDEO_SOUND_LANG1 4 #define VIDEO_SOUND_LANG2 8 unsigned short mode; unsigned short balance; /* Stereo balance */ unsigned short step; /* Step actual volume uses */ }; struct video_clip { int x,y; int width, height; struct video_clip *next; /* For user use/driver use only */ }; struct video_window { unsigned int x,y; /* Position of window */ unsigned int width,height; /* Its size */ unsigned int chromakey; unsigned int flags; struct video_clip *clips; /* Set only */ int clipcount; #define VIDEO_WINDOW_INTERLACE 1 #define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */ #define VIDEO_CLIP_BITMAP -1 /* bitmap is 1024x625, a '1' bit represents a clipped pixel */ #define VIDEO_CLIPMAP_SIZE (128 * 625) }; struct video_capture { unsigned int x,y; /* Offsets into image */ unsigned int width, height; /* Area to capture */ unsigned short decimation; /* Decimation divider */ unsigned short flags; /* Flags for capture */ #define VIDEO_CAPTURE_ODD 0 /* Temporal */ #define VIDEO_CAPTURE_EVEN 1 }; struct video_buffer { void *base; int height,width; int depth; int bytesperline; }; struct video_mmap { unsigned int frame; /* Frame (0 - n) for double buffer */ int height,width; unsigned int format; /* should be VIDEO_PALETTE_* */ }; struct video_key { unsigned char key[8]; unsigned int flags; }; #define VIDEO_MAX_FRAME 32 struct video_mbuf { int size; /* Total memory to map */ int frames; /* Frames */ int offsets[VIDEO_MAX_FRAME]; }; #define VIDEO_NO_UNIT (-1) struct video_unit { int video; /* Video minor */ int vbi; /* VBI minor */ int radio; /* Radio minor */ int audio; /* Audio minor */ int teletext; /* Teletext minor */ }; struct vbi_format { unsigned int sampling_rate; /* in Hz */ unsigned int samples_per_line; unsigned int sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */ int start[2]; /* starting line for each frame */ unsigned int count[2]; /* count of lines for each frame */ unsigned int flags; #define VBI_UNSYNC 1 /* can distingues between top/bottom field */ #define VBI_INTERLACED 2 /* lines are interlaced */ }; /* video_info is biased towards hardware mpeg encode/decode */ /* but it could apply generically to any hardware compressor/decompressor */ struct video_info { unsigned int frame_count; /* frames output since decode/encode began */ unsigned int h_size; /* current unscaled horizontal size */ unsigned int v_size; /* current unscaled veritcal size */ unsigned int smpte_timecode; /* current SMPTE timecode (for current GOP) */ unsigned int picture_type; /* current picture type */ unsigned int temporal_reference; /* current temporal reference */ unsigned char user_data[256]; /* user data last found in compressed stream */ /* user_data[0] contains user data flags, user_data[1] has count */ }; /* generic structure for setting playback modes */ struct video_play_mode { int mode; int p1; int p2; }; /* for loading microcode / fpga programming */ struct video_code { char loadwhat[16]; /* name or tag of file being passed */ int datasize; unsigned char *data; }; #define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */ #define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */ #define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */ #define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */ #define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */ #define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */ #define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */ #define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */ #define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */ #define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */ #define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */ #define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */ #define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */ #define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */ #define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */ #define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */ #define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */ #define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */ #define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */ #define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */ #define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */ #define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */ #define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */ #define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */ #define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */ #define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */ #define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */ #define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */ #define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */ #define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */ /* VIDIOCSWRITEMODE */ #define VID_WRITE_MPEG_AUD 0 #define VID_WRITE_MPEG_VID 1 #define VID_WRITE_OSD 2 #define VID_WRITE_TTX 3 #define VID_WRITE_CC 4 #define VID_WRITE_MJPEG 5 /* VIDIOCSPLAYMODE */ #define VID_PLAY_VID_OUT_MODE 0 /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */ #define VID_PLAY_GENLOCK 1 /* p1: 0 = OFF, 1 = ON */ /* p2: GENLOCK FINE DELAY value */ #define VID_PLAY_NORMAL 2 #define VID_PLAY_PAUSE 3 #define VID_PLAY_SINGLE_FRAME 4 #define VID_PLAY_FAST_FORWARD 5 #define VID_PLAY_SLOW_MOTION 6 #define VID_PLAY_IMMEDIATE_NORMAL 7 #define VID_PLAY_SWITCH_CHANNELS 8 #define VID_PLAY_FREEZE_FRAME 9 #define VID_PLAY_STILL_MODE 10 #define VID_PLAY_MASTER_MODE 11 /* p1: see below */ #define VID_PLAY_MASTER_NONE 1 #define VID_PLAY_MASTER_VIDEO 2 #define VID_PLAY_MASTER_AUDIO 3 #define VID_PLAY_ACTIVE_SCANLINES 12 /* p1 = first active; p2 = last active */ #define VID_PLAY_RESET 13 #define VID_PLAY_END_MARK 14 #define VID_HARDWARE_BT848 1 #define VID_HARDWARE_QCAM_BW 2 #define VID_HARDWARE_PMS 3 #define VID_HARDWARE_QCAM_C 4 #define VID_HARDWARE_PSEUDO 5 #define VID_HARDWARE_SAA5249 6 #define VID_HARDWARE_AZTECH 7 #define VID_HARDWARE_SF16MI 8 #define VID_HARDWARE_RTRACK 9 #define VID_HARDWARE_ZOLTRIX 10 #define VID_HARDWARE_SAA7146 11 #define VID_HARDWARE_VIDEUM 12 /* Reserved for Winnov videum */ #define VID_HARDWARE_RTRACK2 13 #define VID_HARDWARE_PERMEDIA2 14 /* Reserved for Permedia2 */ #define VID_HARDWARE_RIVA128 15 /* Reserved for RIVA 128 */ #define VID_HARDWARE_PLANB 16 /* PowerMac motherboard video-in */ #define VID_HARDWARE_BROADWAY 17 /* Broadway project */ #define VID_HARDWARE_GEMTEK 18 #define VID_HARDWARE_TYPHOON 19 #define VID_HARDWARE_VINO 20 /* SGI Indy Vino */ #define VID_HARDWARE_CADET 21 /* Cadet radio */ #define VID_HARDWARE_TRUST 22 /* Trust FM Radio */ #define VID_HARDWARE_TERRATEC 23 /* TerraTec ActiveRadio */ #define VID_HARDWARE_CPIA 24 #define VID_HARDWARE_ZR36120 25 /* Zoran ZR36120/ZR36125 */ #define VID_HARDWARE_ZR36067 26 /* Zoran ZR36067/36060 */ #define VID_HARDWARE_OV511 27 #define VID_HARDWARE_ZR356700 28 /* Zoran 36700 series */ #define VID_HARDWARE_W9966 29 #define VID_HARDWARE_SE401 30 /* SE401 USB webcams */ #define VID_HARDWARE_PWC 31 /* Philips webcams */ #define VID_HARDWARE_MEYE 32 /* Sony Vaio MotionEye cameras */ #define VID_HARDWARE_CPIA2 33 #define VID_HARDWARE_VICAM 34 #define VID_HARDWARE_SF16FMR2 35 #define VID_HARDWARE_W9968CF 36 #endif /* __LINUX_VIDEODEV_H */ /* * Local variables: * c-basic-offset: 8 * End: */ indi-0.5/src/webcam/videodev2.h0000644000175000017500000007313510605175707014217 0ustar jrjr/* Copyright 2006 Bill Dirks Justin Schoeman et al. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __LINUX_VIDEODEV2_H #define __LINUX_VIDEODEV2_H /* * Video for Linux Two * * Header file for v4l or V4L2 drivers and applications, for * Linux kernels 2.2.x or 2.4.x. * * See http://bytesex.org/v4l/ for API specs and other * v4l2 documentation. * * Author: Bill Dirks * Justin Schoeman * et al. */ /* * M I S C E L L A N E O U S */ /* Four-character-code (FOURCC) */ #define v4l2_fourcc(a,b,c,d)\ (((unsigned int)(a)<<0)|((unsigned int)(b)<<8)|((unsigned int)(c)<<16)|((unsigned int)(d)<<24)) /* * E N U M S */ enum v4l2_field { V4L2_FIELD_ANY = 0, /* driver can choose from none, top, bottom, interlaced depending on whatever it thinks is approximate ... */ V4L2_FIELD_NONE = 1, /* this device has no fields ... */ V4L2_FIELD_TOP = 2, /* top field only */ V4L2_FIELD_BOTTOM = 3, /* bottom field only */ V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */ V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one buffer, top-bottom order */ V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */ V4L2_FIELD_ALTERNATE = 7 /* both fields alternating into separate buffers */ }; #define V4L2_FIELD_HAS_TOP(field) \ ((field) == V4L2_FIELD_TOP ||\ (field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) #define V4L2_FIELD_HAS_BOTTOM(field) \ ((field) == V4L2_FIELD_BOTTOM ||\ (field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) #define V4L2_FIELD_HAS_BOTH(field) \ ((field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) enum v4l2_buf_type { V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, V4L2_BUF_TYPE_VBI_CAPTURE = 4, V4L2_BUF_TYPE_VBI_OUTPUT = 5, V4L2_BUF_TYPE_PRIVATE = 0x80 }; enum v4l2_ctrl_type { V4L2_CTRL_TYPE_INTEGER = 1, V4L2_CTRL_TYPE_BOOLEAN = 2, V4L2_CTRL_TYPE_MENU = 3, V4L2_CTRL_TYPE_BUTTON = 4 }; enum v4l2_tuner_type { V4L2_TUNER_RADIO = 1, V4L2_TUNER_ANALOG_TV = 2 }; enum v4l2_memory { V4L2_MEMORY_MMAP = 1, V4L2_MEMORY_USERPTR = 2, V4L2_MEMORY_OVERLAY = 3 }; /* see also http://vektor.theorem.ca/graphics/ycbcr/ */ enum v4l2_colorspace { /* ITU-R 601 -- broadcast NTSC/PAL */ V4L2_COLORSPACE_SMPTE170M = 1, /* 1125-Line (US) HDTV */ V4L2_COLORSPACE_SMPTE240M = 2, /* HD and modern captures. */ V4L2_COLORSPACE_REC709 = 3, /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */ V4L2_COLORSPACE_BT878 = 4, /* These should be useful. Assume 601 extents. */ V4L2_COLORSPACE_470_SYSTEM_M = 5, V4L2_COLORSPACE_470_SYSTEM_BG = 6, /* I know there will be cameras that send this. So, this is * unspecified chromaticities and full 0-255 on each of the * Y'CbCr components */ V4L2_COLORSPACE_JPEG = 7, /* For RGB colourspaces, this is probably a good start. */ V4L2_COLORSPACE_SRGB = 8 }; enum v4l2_priority { V4L2_PRIORITY_UNSET = 0, /* not initialized */ V4L2_PRIORITY_BACKGROUND = 1, V4L2_PRIORITY_INTERACTIVE = 2, V4L2_PRIORITY_RECORD = 3, V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE }; struct v4l2_rect { int left; int top; int width; int height; }; struct v4l2_fract { unsigned int numerator; unsigned int denominator; }; /* * D R I V E R C A P A B I L I T I E S */ struct v4l2_capability { unsigned char driver[16]; /* i.e. "bttv" */ unsigned char card[32]; /* i.e. "Hauppauge WinTV" */ unsigned char bus_info[32]; /* "PCI:" + pci_name(pci_dev) */ unsigned int version; /* should use KERNEL_VERSION() */ unsigned int capabilities; /* Device capabilities */ unsigned int reserved[4]; }; /* Values for 'capabilities' field */ #define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ #define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ #define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ #define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a VBI capture device */ #define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a VBI output device */ #define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ #define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ #define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ #define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ #define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ #define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ #define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ /* * V I D E O I M A G E F O R M A T */ struct v4l2_pix_format { unsigned int width; unsigned int height; unsigned int pixelformat; enum v4l2_field field; unsigned int bytesperline; /* for padding, zero if unused */ unsigned int sizeimage; enum v4l2_colorspace colorspace; unsigned int priv; /* private data, depends on pixelformat */ }; /* Pixel format FOURCC depth Description */ #define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R','G','B','1') /* 8 RGB-3-3-2 */ #define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R','G','B','O') /* 16 RGB-5-5-5 */ #define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R','G','B','P') /* 16 RGB-5-6-5 */ #define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q') /* 16 RGB-5-5-5 BE */ #define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R') /* 16 RGB-5-6-5 BE */ #define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B','G','R','3') /* 24 BGR-8-8-8 */ #define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R','G','B','3') /* 24 RGB-8-8-8 */ #define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */ #define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */ #define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y') /* 8 Greyscale */ #define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */ #define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */ #define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y','U','Y','V') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_UYVY v4l2_fourcc('U','Y','V','Y') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P') /* 16 YVU422 planar */ #define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P') /* 16 YVU411 planar */ #define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y','4','1','P') /* 12 YUV 4:1:1 */ /* two planes -- one Y, one Cr + Cb interleaved */ #define V4L2_PIX_FMT_NV12 v4l2_fourcc('N','V','1','2') /* 12 Y/CbCr 4:2:0 */ #define V4L2_PIX_FMT_NV21 v4l2_fourcc('N','V','2','1') /* 12 Y/CrCb 4:2:0 */ /* The following formats are not defined in the V4L2 specification */ #define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y','U','V','9') /* 9 YUV 4:1:0 */ #define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y','U','1','2') /* 12 YUV 4:2:0 */ #define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y','Y','U','V') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_HI240 v4l2_fourcc('H','I','2','4') /* 8 8-bit color */ /* see http://www.siliconimaging.com/RGB%20Bayer.htm */ #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1') /* 8 BGBG.. GRGR.. */ /* compressed formats */ #define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G') /* Motion-JPEG */ #define V4L2_PIX_FMT_JPEG v4l2_fourcc('J','P','E','G') /* JFIF JPEG */ #define V4L2_PIX_FMT_DV v4l2_fourcc('d','v','s','d') /* 1394 */ #define V4L2_PIX_FMT_MPEG v4l2_fourcc('M','P','E','G') /* MPEG */ /* Vendor-specific formats */ #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */ #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S','9','1','0') /* SN9C10x compression */ #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1') /* pwc older webcam */ #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2') /* pwc newer webcam */ /* * F O R M A T E N U M E R A T I O N */ struct v4l2_fmtdesc { unsigned int index; /* Format number */ enum v4l2_buf_type type; /* buffer type */ unsigned int flags; unsigned char description[32]; /* Description string */ unsigned int pixelformat; /* Format fourcc */ unsigned int reserved[4]; }; #define V4L2_FMT_FLAG_COMPRESSED 0x0001 /* * T I M E C O D E */ struct v4l2_timecode { unsigned int type; unsigned int flags; unsigned char frames; unsigned char seconds; unsigned char minutes; unsigned char hours; unsigned char userbits[4]; }; /* Type */ #define V4L2_TC_TYPE_24FPS 1 #define V4L2_TC_TYPE_25FPS 2 #define V4L2_TC_TYPE_30FPS 3 #define V4L2_TC_TYPE_50FPS 4 #define V4L2_TC_TYPE_60FPS 5 /* Flags */ #define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ #define V4L2_TC_FLAG_COLORFRAME 0x0002 #define V4L2_TC_USERBITS_field 0x000C #define V4L2_TC_USERBITS_USERDEFINED 0x0000 #define V4L2_TC_USERBITS_8BITCHARS 0x0008 /* The above is based on SMPTE timecodes */ /* * C O M P R E S S I O N P A R A M E T E R S */ #if 0 /* ### generic compression settings don't work, there is too much * ### codec-specific stuff. Maybe reuse that for MPEG codec settings * ### later ... */ struct v4l2_compression { unsigned int quality; unsigned int keyframerate; unsigned int pframerate; unsigned int reserved[5]; /* what we'll need for MPEG, extracted from some postings on the v4l list (Gert Vervoort, PlasmaJohn). system stream: - type: elementary stream(ES), packatised elementary stream(s) (PES) program stream(PS), transport stream(TS) - system bitrate - PS packet size (DVD: 2048 bytes, VCD: 2324 bytes) - TS video PID - TS audio PID - TS PCR PID - TS system information tables (PAT, PMT, CAT, NIT and SIT) - (MPEG-1 systems stream vs. MPEG-2 program stream (TS not supported by MPEG-1 systems) audio: - type: MPEG (+Layer I,II,III), AC-3, LPCM - bitrate - sampling frequency (DVD: 48 Khz, VCD: 44.1 KHz, 32 kHz) - Trick Modes? (ff, rew) - Copyright - Inverse Telecine video: - picturesize (SIF, 1/2 D1, 2/3 D1, D1) and PAL/NTSC norm can be set through excisting V4L2 controls - noise reduction, parameters encoder specific? - MPEG video version: MPEG-1, MPEG-2 - GOP (Group Of Pictures) definition: - N: number of frames per GOP - M: distance between reference (I,P) frames - open/closed GOP - quantiser matrix: inter Q matrix (64 bytes) and intra Q matrix (64 bytes) - quantiser scale: linear or logarithmic - scanning: alternate or zigzag - bitrate mode: CBR (constant bitrate) or VBR (variable bitrate). - target video bitrate for CBR - target video bitrate for VBR - maximum video bitrate for VBR - min. quantiser value for VBR - max. quantiser value for VBR - adaptive quantisation value - return the number of bytes per GOP or bitrate for bitrate monitoring */ }; #endif struct v4l2_jpegcompression { int quality; int APPn; /* Number of APP segment to be written, * must be 0..15 */ int APP_len; /* Length of data in JPEG APPn segment */ char APP_data[60]; /* Data in the JPEG APPn segment. */ int COM_len; /* Length of data in JPEG COM segment */ char COM_data[60]; /* Data in JPEG COM segment */ unsigned int jpeg_markers; /* Which markers should go into the JPEG * output. Unless you exactly know what * you do, leave them untouched. * Inluding less markers will make the * resulting code smaller, but there will * be fewer aplications which can read it. * The presence of the APP and COM marker * is influenced by APP_len and COM_len * ONLY, not by this property! */ #define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ #define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ #define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ #define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ #define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will * always use APP0 */ }; /* * M E M O R Y - M A P P I N G B U F F E R S */ struct v4l2_requestbuffers { unsigned int count; enum v4l2_buf_type type; enum v4l2_memory memory; unsigned int reserved[2]; }; struct v4l2_buffer { unsigned int index; enum v4l2_buf_type type; unsigned int bytesused; unsigned int flags; enum v4l2_field field; struct timeval timestamp; struct v4l2_timecode timecode; unsigned int sequence; /* memory location */ enum v4l2_memory memory; union { unsigned int offset; unsigned long userptr; } m; unsigned int length; unsigned int input; unsigned int reserved; }; /* Flags for 'flags' field */ #define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */ #define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */ #define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */ #define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ #define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ #define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ #define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ #define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */ /* * O V E R L A Y P R E V I E W */ struct v4l2_framebuffer { unsigned int capability; unsigned int flags; /* FIXME: in theory we should pass something like PCI device + memory * region + offset instead of some physical address */ void* base; struct v4l2_pix_format fmt; }; /* Flags for the 'capability' field. Read only */ #define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 #define V4L2_FBUF_CAP_CHROMAKEY 0x0002 #define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004 #define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008 /* Flags for the 'flags' field. */ #define V4L2_FBUF_FLAG_PRIMARY 0x0001 #define V4L2_FBUF_FLAG_OVERLAY 0x0002 #define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 struct v4l2_clip { struct v4l2_rect c; struct v4l2_clip *next; }; struct v4l2_window { struct v4l2_rect w; enum v4l2_field field; unsigned int chromakey; struct v4l2_clip *clips; unsigned int clipcount; void *bitmap; }; /* * C A P T U R E P A R A M E T E R S */ struct v4l2_captureparm { unsigned int capability; /* Supported modes */ unsigned int capturemode; /* Current mode */ struct v4l2_fract timeperframe; /* Time per frame in .1us units */ unsigned int extendedmode; /* Driver-specific extensions */ unsigned int readbuffers; /* # of buffers for read */ unsigned int reserved[4]; }; /* Flags for 'capability' and 'capturemode' fields */ #define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ #define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ struct v4l2_outputparm { unsigned int capability; /* Supported modes */ unsigned int outputmode; /* Current mode */ struct v4l2_fract timeperframe; /* Time per frame in seconds */ unsigned int extendedmode; /* Driver-specific extensions */ unsigned int writebuffers; /* # of buffers for write */ unsigned int reserved[4]; }; /* * I N P U T I M A G E C R O P P I N G */ struct v4l2_cropcap { enum v4l2_buf_type type; struct v4l2_rect bounds; struct v4l2_rect defrect; struct v4l2_fract pixelaspect; }; struct v4l2_crop { enum v4l2_buf_type type; struct v4l2_rect c; }; /* * A N A L O G V I D E O S T A N D A R D */ typedef unsigned long long v4l2_std_id; /* one bit for each */ #define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001) #define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002) #define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004) #define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008) #define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010) #define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020) #define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040) #define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080) #define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100) #define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200) #define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400) #define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800) #define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) #define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) #define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) #define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) #define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000) #define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000) #define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000) #define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000) #define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000) /* ATSC/HDTV */ #define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) #define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) /* some common needed stuff */ #define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\ V4L2_STD_PAL_B1 |\ V4L2_STD_PAL_G) #define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\ V4L2_STD_PAL_D1 |\ V4L2_STD_PAL_K) #define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ V4L2_STD_PAL_DK |\ V4L2_STD_PAL_H |\ V4L2_STD_PAL_I) #define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ V4L2_STD_NTSC_M_JP) #define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ V4L2_STD_SECAM_K |\ V4L2_STD_SECAM_K1) #define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\ V4L2_STD_SECAM_G |\ V4L2_STD_SECAM_H |\ V4L2_STD_SECAM_DK |\ V4L2_STD_SECAM_L) #define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ V4L2_STD_PAL_60 |\ V4L2_STD_NTSC) #define V4L2_STD_625_50 (V4L2_STD_PAL |\ V4L2_STD_PAL_N |\ V4L2_STD_PAL_Nc |\ V4L2_STD_SECAM) #define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\ V4L2_STD_ATSC_16_VSB) #define V4L2_STD_UNKNOWN 0 #define V4L2_STD_ALL (V4L2_STD_525_60 |\ V4L2_STD_625_50) struct v4l2_standard { unsigned int index; v4l2_std_id id; unsigned char name[24]; struct v4l2_fract frameperiod; /* Frames, not fields */ unsigned int framelines; unsigned int reserved[4]; }; /* * V I D E O I N P U T S */ struct v4l2_input { unsigned int index; /* Which input */ unsigned char name[32]; /* Label */ unsigned int type; /* Type of input */ unsigned int audioset; /* Associated audios (bitfield) */ unsigned int tuner; /* Associated tuner */ v4l2_std_id std; unsigned int status; unsigned int reserved[4]; }; /* Values for the 'type' field */ #define V4L2_INPUT_TYPE_TUNER 1 #define V4L2_INPUT_TYPE_CAMERA 2 /* field 'status' - general */ #define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ #define V4L2_IN_ST_NO_SIGNAL 0x00000002 #define V4L2_IN_ST_NO_COLOR 0x00000004 /* field 'status' - analog */ #define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ #define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ /* field 'status' - digital */ #define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ #define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */ #define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */ /* field 'status' - VCR and set-top box */ #define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */ #define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ #define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ /* * V I D E O O U T P U T S */ struct v4l2_output { unsigned int index; /* Which output */ unsigned char name[32]; /* Label */ unsigned int type; /* Type of output */ unsigned int audioset; /* Associated audios (bitfield) */ unsigned int modulator; /* Associated modulator */ v4l2_std_id std; unsigned int reserved[4]; }; /* Values for the 'type' field */ #define V4L2_OUTPUT_TYPE_MODULATOR 1 #define V4L2_OUTPUT_TYPE_ANALOG 2 #define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 /* * C O N T R O L S */ struct v4l2_control { unsigned int id; int value; }; /* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ struct v4l2_queryctrl { unsigned int id; enum v4l2_ctrl_type type; unsigned char name[32]; /* Whatever */ int minimum; /* Note signedness */ int maximum; int step; int default_value; unsigned int flags; unsigned int reserved[2]; }; /* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ struct v4l2_querymenu { unsigned int id; unsigned int index; unsigned char name[32]; /* Whatever */ unsigned int reserved; }; /* Control flags */ #define V4L2_CTRL_FLAG_DISABLED 0x0001 #define V4L2_CTRL_FLAG_GRABBED 0x0002 /* Control IDs defined by V4L2 */ #define V4L2_CID_BASE 0x00980900 /* IDs reserved for driver specific controls */ #define V4L2_CID_PRIVATE_BASE 0x08000000 #define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) #define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) #define V4L2_CID_SATURATION (V4L2_CID_BASE+2) #define V4L2_CID_HUE (V4L2_CID_BASE+3) #define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) #define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) #define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) #define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) #define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) #define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) #define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) #define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) #define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) #define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) #define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) #define V4L2_CID_GAMMA (V4L2_CID_BASE+16) #define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* ? Not sure */ #define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) #define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) #define V4L2_CID_GAIN (V4L2_CID_BASE+19) #define V4L2_CID_HFLIP (V4L2_CID_BASE+20) #define V4L2_CID_VFLIP (V4L2_CID_BASE+21) #define V4L2_CID_HCENTER (V4L2_CID_BASE+22) #define V4L2_CID_VCENTER (V4L2_CID_BASE+23) #define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */ /* * T U N I N G */ struct v4l2_tuner { unsigned int index; unsigned char name[32]; enum v4l2_tuner_type type; unsigned int capability; unsigned int rangelow; unsigned int rangehigh; unsigned int rxsubchans; unsigned int audmode; int signal; int afc; unsigned int reserved[4]; }; struct v4l2_modulator { unsigned int index; unsigned char name[32]; unsigned int capability; unsigned int rangelow; unsigned int rangehigh; unsigned int txsubchans; unsigned int reserved[4]; }; /* Flags for the 'capability' field */ #define V4L2_TUNER_CAP_LOW 0x0001 #define V4L2_TUNER_CAP_NORM 0x0002 #define V4L2_TUNER_CAP_STEREO 0x0010 #define V4L2_TUNER_CAP_LANG2 0x0020 #define V4L2_TUNER_CAP_SAP 0x0020 #define V4L2_TUNER_CAP_LANG1 0x0040 /* Flags for the 'rxsubchans' field */ #define V4L2_TUNER_SUB_MONO 0x0001 #define V4L2_TUNER_SUB_STEREO 0x0002 #define V4L2_TUNER_SUB_LANG2 0x0004 #define V4L2_TUNER_SUB_SAP 0x0004 #define V4L2_TUNER_SUB_LANG1 0x0008 /* Values for the 'audmode' field */ #define V4L2_TUNER_MODE_MONO 0x0000 #define V4L2_TUNER_MODE_STEREO 0x0001 #define V4L2_TUNER_MODE_LANG2 0x0002 #define V4L2_TUNER_MODE_SAP 0x0002 #define V4L2_TUNER_MODE_LANG1 0x0003 struct v4l2_frequency { unsigned int tuner; enum v4l2_tuner_type type; unsigned int frequency; unsigned int reserved[8]; }; /* * A U D I O */ struct v4l2_audio { unsigned int index; unsigned char name[32]; unsigned int capability; unsigned int mode; unsigned int reserved[2]; }; /* Flags for the 'capability' field */ #define V4L2_AUDCAP_STEREO 0x00001 #define V4L2_AUDCAP_AVL 0x00002 /* Flags for the 'mode' field */ #define V4L2_AUDMODE_AVL 0x00001 struct v4l2_audioout { unsigned int index; unsigned char name[32]; unsigned int capability; unsigned int mode; unsigned int reserved[2]; }; /* * D A T A S E R V I C E S ( V B I ) * * Data services API by Michael Schimek */ struct v4l2_vbi_format { unsigned int sampling_rate; /* in 1 Hz */ unsigned int offset; unsigned int samples_per_line; unsigned int sample_format; /* V4L2_PIX_FMT_* */ int start[2]; unsigned int count[2]; unsigned int flags; /* V4L2_VBI_* */ unsigned int reserved[2]; /* must be zero */ }; /* VBI flags */ #define V4L2_VBI_UNSYNC (1<< 0) #define V4L2_VBI_INTERLACED (1<< 1) /* * A G G R E G A T E S T R U C T U R E S */ /* Stream data format */ struct v4l2_format { enum v4l2_buf_type type; union { struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE unsigned char raw_data[200]; // user-defined } fmt; }; /* Stream type-dependent parameters */ struct v4l2_streamparm { enum v4l2_buf_type type; union { struct v4l2_captureparm capture; struct v4l2_outputparm output; unsigned char raw_data[200]; /* user-defined */ } parm; }; /* * I O C T L C O D E S F O R V I D E O D E V I C E S * */ #define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability) #define VIDIOC_RESERVED _IO ('V', 1) #define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc) #define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format) #define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format) #if 0 #define VIDIOC_G_COMP _IOR ('V', 6, struct v4l2_compression) #define VIDIOC_S_COMP _IOW ('V', 7, struct v4l2_compression) #endif #define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers) #define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer) #define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer) #define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer) #define VIDIOC_OVERLAY _IOW ('V', 14, int) #define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer) #define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer) #define VIDIOC_STREAMON _IOW ('V', 18, int) #define VIDIOC_STREAMOFF _IOW ('V', 19, int) #define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm) #define VIDIOC_S_PARM _IOWR ('V', 22, struct v4l2_streamparm) #define VIDIOC_G_STD _IOR ('V', 23, v4l2_std_id) #define VIDIOC_S_STD _IOW ('V', 24, v4l2_std_id) #define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_standard) #define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input) #define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control) #define VIDIOC_S_CTRL _IOWR ('V', 28, struct v4l2_control) #define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner) #define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner) #define VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio) #define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio) #define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl) #define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu) #define VIDIOC_G_INPUT _IOR ('V', 38, int) #define VIDIOC_S_INPUT _IOWR ('V', 39, int) #define VIDIOC_G_OUTPUT _IOR ('V', 46, int) #define VIDIOC_S_OUTPUT _IOWR ('V', 47, int) #define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output) #define VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout) #define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout) #define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator) #define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator) #define VIDIOC_G_FREQUENCY _IOWR ('V', 56, struct v4l2_frequency) #define VIDIOC_S_FREQUENCY _IOW ('V', 57, struct v4l2_frequency) #define VIDIOC_CROPCAP _IOWR ('V', 58, struct v4l2_cropcap) #define VIDIOC_G_CROP _IOWR ('V', 59, struct v4l2_crop) #define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop) #define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression) #define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression) #define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id) #define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format) #define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio) #define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout) #define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority) #define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority) /* for compatibility, will go away some day */ #define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int) #define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm) #define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control) #define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio) #define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout) #define VIDIOC_CROPCAP_OLD _IOR ('V', 58, struct v4l2_cropcap) #define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ #endif /* __LINUX_VIDEODEV2_H */ /* * Local variables: * c-basic-offset: 8 * End: */ indi-0.5/src/webcam/ccvt_c2.c0000644000175000017500000000647310605175707013647 0ustar jrjr/* CCVT_C2: Convert an image from yuv colourspace to rgb Copyright (C) 2001 Tony Hague 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA For questions, remarks, patches, etc. for this program, the author can be reached at nemosoft@smcc.demon.nl. */ #include "ccvt.h" #include "ccvt_types.h" /* by suitable definition of PIXTYPE, can do yuv to rgb or bgr, with or without word alignment */ /* This doesn't exactly earn a prize in a programming beauty contest. */ #define WHOLE_FUNC2RGB(type) \ const unsigned char *y1, *y2, *u, *v; \ PIXTYPE_##type *l1, *l2; \ int r, g, b, cr, cg, cb, yp, j, i; \ \ if ((width & 1) || (height & 1)) \ return; \ \ l1 = (PIXTYPE_##type *)dst; \ l2 = l1 + width; \ y1 = (unsigned char *)src; \ y2 = y1 + width; \ u = (unsigned char *)src + width * height; \ v = u + (width * height) / 4; \ j = height / 2; \ while (j--) { \ i = width / 2; \ while (i--) { \ /* Since U & V are valid for 4 pixels, repeat code 4 \ times for different Y */ \ cb = ((*u-128) * 454)>>8; \ cr = ((*v-128) * 359)>>8; \ cg = ((*v-128) * 183 + (*u-128) * 88)>>8; \ \ yp = *(y1++); \ r = yp + cr; \ b = yp + cb; \ g = yp - cg; \ SAT(r); \ SAT(g); \ SAT(b); \ l1->b = b; \ l1->g = g; \ l1->r = r; \ l1++; \ \ yp = *(y1++); \ r = yp + cr; \ b = yp + cb; \ g = yp - cg; \ SAT(r); \ SAT(g); \ SAT(b); \ l1->b = b; \ l1->g = g; \ l1->r = r; \ l1++; \ \ yp = *(y2++); \ r = yp + cr; \ b = yp + cb; \ g = yp - cg; \ SAT(r); \ SAT(g); \ SAT(b); \ l2->b = b; \ l2->g = g; \ l2->r = r; \ l2++; \ \ yp = *(y2++); \ r = yp + cr; \ b = yp + cb; \ g = yp - cg; \ SAT(r); \ SAT(g); \ SAT(b); \ l2->b = b; \ l2->g = g; \ l2->r = r; \ l2++; \ \ u++; \ v++; \ } \ y1 = y2; \ y2 += width; \ l1 = l2; \ l2 += width; \ } void ccvt_420p_bgr32(int width, int height, const void *src, void *dst) { WHOLE_FUNC2RGB(bgr32) } void ccvt_420p_bgr24(int width, int height, const void *src, void *dst) { WHOLE_FUNC2RGB(bgr24) } void ccvt_420p_rgb32(int width, int height, const void *src, void *dst) { WHOLE_FUNC2RGB(rgb32) } void ccvt_420p_rgb24(int width, int height, const void *src, void *dst) { WHOLE_FUNC2RGB(rgb24) } indi-0.5/src/webcam/port.cpp0000644000175000017500000001256110605175707013643 0ustar jrjr/* libcqcam - shared Color Quickcam routines * Copyright (C) 1996-1998 by Patrick Reynolds * Email: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ // I/O ports wrapper code // This file might need tweaking if you're trying to port my code to other // x86 Unix platforms. Code is already available for Linux, FreeBSD, and // QNX; see the Makefile. // // QNX code by: Anders Arpteg // FreeBSD code by: Patrick Reynolds and Charles // Henrich //#include "config.h" #include #include #ifdef LOCKING #include #include #endif /* LOCKING */ #ifdef __linux__ #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__) #include #else #include #endif /* arm */ #elif defined(QNX) #include #elif defined(__FreeBSD__) #include #include #elif defined(BSDI) #include #elif defined(OPENBSD) #include #elif defined(LYNX) #include "lynx-io.h" #elif defined(SOLARIS) #include "solaris-io.h" #else #error Please define a platform in the Makefile #endif /* which OS */ #include "port.h" port_t::port_t(int iport) { port = -1; #ifdef LOCKING if (lock(iport) == -1) { #ifdef DEBUG fprintf(stderr, "port 0x%x already locked\n", iport); #endif /* DEBUG */ return; } #endif /* LOCKING */ #ifdef LINUX #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__) if ((devport = open("/dev/port", O_RDWR)) < 0) { perror("open /dev/port"); return; } #else if (ioperm(iport, 3, 1) == -1) { perror("ioperm()"); return; } #endif /* arm */ #elif defined(FREEBSD) if ((devio = fopen("/dev/io", "r+")) == NULL) { perror("fopen /dev/io"); return; } #elif defined(OPENBSD) if (i386_iopl(1) == -1) { perror("i386_iopl"); return; } #elif defined(LYNX) if (io_access() < 0) { perror("io_access"); return; } #elif defined(SOLARIS) if (openiop()) { perror("openiop"); return; } #endif /* which OS */ port = iport; port1 = port + 1; port2 = port + 2; control_reg = read_control(); } port_t::~port_t(void) { #ifdef LOCKING unlock(port); #endif /* LOCKING */ #ifdef LINUX #if defined(arm) || defined(__hppa__) || defined(__sparc__) || defined(__ppc__) || defined(__powerpc__) || defined(__s390__) || defined(__s390x__) || defined(__mips__) || defined(__mc68000__) if (devport >= 0) close(devport); #else if (port > 0 && geteuid() == 0) if (ioperm(port, 3, 0) != 0) // drop port permissions -- still must // be root perror("ioperm()"); #endif /* arm */ #elif defined(FREEBSD) if (devio != NULL) fclose(devio); #elif defined(SOLARIS) close(iopfd); #endif /* which OS */ } #ifdef LOCKING int port_t::lock(int portnum) { char lockfile[80]; sprintf(lockfile, "/tmp/LOCK.qcam.0x%x", portnum); while ((lock_fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == -1) { if (errno != EEXIST) { perror(lockfile); return -1; } struct stat stat_buf; if (lstat(lockfile, &stat_buf) < 0) continue; if (S_ISLNK(stat_buf.st_mode) || stat_buf.st_uid != 0) { if (unlink(lockfile)) { if (errno == ENOENT) continue; if (errno != EISDIR || (rmdir(lockfile) && errno != ENOENT)) { /* known problem: if lockfile exists and is a non-empty directory, we give up instead of doing an rm-r of it */ perror(lockfile); return -1; } } continue; } lock_fd = open(lockfile, O_WRONLY, 0600); if (lock_fd == -1) { perror(lockfile); return -1; } break; } static struct flock lock_info; lock_info.l_type = F_WRLCK; #ifdef LOCK_FAIL if (fcntl(lock_fd, F_SETLK, &lock_info) != 0) { #else if (fcntl(lock_fd, F_SETLKW, &lock_info) != 0) { #endif /* LOCK_FAIL */ if (errno != EAGAIN) perror("fcntl"); return -1; } chown(lockfile, getuid(), getgid()); #ifdef DEBUG fprintf(stderr, "Locked port 0x%x\n", portnum); #endif /* DEBUG */ return 0; } void port_t::unlock(int portnum) { if (portnum == -1) return; close(lock_fd); // this clears the lock char lockfile[80]; sprintf(lockfile, "/tmp/LOCK.qcam.0x%x", portnum); if (unlink(lockfile)) perror(lockfile); #ifdef DEBUG fprintf(stderr, "Unlocked port 0x%x\n", portnum); #endif /* DEBUG */ } #endif /* LOCKING */ indi-0.5/src/webcam/PPort.h0000644000175000017500000000512110605175707013362 0ustar jrjr/* Copyright (C) 2004 by Jasem Mutlaq This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _PPort_hpp_ #define _PPort_hpp_ class port_t; /** To access and share the parallel port between severa objects. */ class PPort { public: PPort(); PPort(int ioPort); ~PPort(); /** set the ioport associated to the // port. \return true if the binding was possible */ bool setPort(int ioPort); /** set a data bit of the // port. \return false if IO port not set, or bit not registered by ID. \param ID the identifier used to register the bit \param stat the stat wanted for the given bit \param bit the bit to set. They are numbered from 0 to 7. */ bool setBit(const void * ID,int bit,bool stat); /** register a bit for object ID. \param ID the identifier used to register the bit it should be the 'this' pointer. \param bit the bit of the // port to register \return false if the bit is already register with an other ID, or if the // port is not initialised. */ bool registerBit(const void * ID,int bit); /** release a bit. \param ID the identifier used to register the bit \param bit the bit to register. \return false if the bit was not registered by ID or if the if the // port is not initialised. */ bool unregisterBit(const void * ID,int bit); /** test if a bit is registerd. \param ID the identifier used to register the bit \param bit the bit to test. \return false if the bit was not registered by ID or if the if the // port is not initialised. */ bool isRegisterBit(const void * ID,int bit) const; /** set the bits off the // port according to previous call to setBit(). */ bool commit(); private: void reset(); unsigned char bitArray; const void * assignedBit[8]; port_t * currentPort; }; #endif indi-0.5/src/webcam/v4l1_pwc.cpp0000644000175000017500000003106010605175707014311 0ustar jrjr/* Phlips webcam driver for V4L 1 Copyright (C) 2005 by Jasem Mutlaq This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include "ccvt.h" #include "pwc-ioctl.h" #include "v4l1_pwc.h" #include "../eventloop.h" #define ERRMSG_SIZ 1024 extern int errno; using namespace std; V4L1_PWC::V4L1_PWC() { frameRate=15; fd=-1; streamActive = true; YBuf = NULL; UBuf = NULL; VBuf = NULL; colorBuffer= NULL; buffer_start=NULL; } V4L1_PWC::~V4L1_PWC() { } int V4L1_PWC::connectCam(const char * devpath, char *errmsg) { options= (ioNoBlock|ioUseSelect|haveBrightness|haveContrast|haveColor); struct pwc_probe probe; bool IsPhilips = false; frameRate=15; fd=-1; streamActive = true; buffer_start=NULL; if (-1 == (fd=open(devpath, O_RDONLY | ((options & ioNoBlock) ? O_NONBLOCK : 0)))) { strncpy(errmsg, strerror(errno), 1024); cerr << strerror(errno); return -1; } cerr << "Device opened" << endl; if (fd != -1) { if (-1 == ioctl(fd,VIDIOCGCAP,&capability)) { cerr << "Error: ioctl (VIDIOCGCAP)" << endl; strncpy(errmsg, "ioctl (VIDIOCGCAP)", 1024); return -1; } if (-1 == ioctl (fd, VIDIOCGWIN, &window)) { cerr << "Error: ioctl (VIDIOCGWIN)" << endl; strncpy(errmsg, "ioctl (VIDIOCGWIN)", 1024); return -1; } if (-1 == ioctl (fd, VIDIOCGPICT, &picture_format)) { cerr << "Error: ioctl (VIDIOCGPICT)" << endl; strncpy(errmsg, "ioctl (VIDIOCGPICT)", 1024); return -1; } init(0); } // Check to see if it's really a philips webcam if (ioctl(fd, VIDIOCPWCPROBE, &probe) == 0) { if (!strcmp(capability.name,probe.name)) { IsPhilips = true; type_=probe.type; } } if (IsPhilips) cerr << "Philips webcam type " << type_ << " detected" << endl; else { strncpy(errmsg, "No Philips webcam detected.", 1024); return -1; } cerr << "initial size w:" << window.width << " -- h: " << window.height << endl; mmapInit(); setWhiteBalanceMode(PWC_WB_AUTO, errmsg); multiplicateur_=1; skippedFrame_=0; lastGain_=getGain(); cerr << "All successful, returning\n"; return fd; } void V4L1_PWC::checkSize(int & x, int & y) { if (x>=capability.maxwidth && y >= capability.maxheight) { x=capability.maxwidth; y=capability.maxheight; } else if (x>=352 && y >=288 && type_<700) { x=352;y=288; } else if (x>=320 && y >= 240) { x=320;y=240; } else if (x>=176 && y >=144 && type_<700 ) { x=176;y=144; } else if (x>=160 && y >=120 ) { x=160;y=120; } else { x=capability.minwidth; y=capability.minheight; } } bool V4L1_PWC::setSize(int x, int y) { int oldX, oldY; char msg[ERRMSG_SIZ]; checkSize(x,y); oldX = window.width; oldY = window.height; window.width=x; window.height=y; if (ioctl (fd, VIDIOCSWIN, &window)) { snprintf(msg, ERRMSG_SIZ, "ioctl(VIDIOCSWIN) %s", strerror(errno)); cerr << msg << endl; window.width=oldX; window.height=oldY; return false; } ioctl (fd, VIDIOCGWIN, &window); cerr << "New size is x=" << window.width << " " << "y=" << window.height <>PWC_FPS_SHIFT); } int V4L1_PWC::getWhiteBalance() { char msg[ERRMSG_SIZ]; struct pwc_whitebalance tmp_whitebalance; tmp_whitebalance.mode = tmp_whitebalance.manual_red = tmp_whitebalance.manual_blue = tmp_whitebalance.read_red = tmp_whitebalance.read_blue = PWC_WB_AUTO; if (ioctl(fd, VIDIOCPWCGAWB, &tmp_whitebalance)) { snprintf(msg, ERRMSG_SIZ, "getWhiteBalance %s", strerror(errno)); cerr << msg << endl; } else { #if 0 cout << "mode="<show(); remoteCTRLWBblue_->show(); } } else { if (guiBuild()) { remoteCTRLWBred_->hide(); remoteCTRLWBblue_->hide(); } } }*/ } int V4L1_PWC::setWhiteBalance(char *errmsg) { struct pwc_whitebalance wb; wb.mode=whiteBalanceMode_; if (wb.mode == PWC_WB_MANUAL) { wb.manual_red=whiteBalanceRed_; wb.manual_blue=whiteBalanceBlue_; } if (ioctl(fd, VIDIOCPWCSAWB, &wb)) { snprintf(errmsg, ERRMSG_SIZ, "setWhiteBalance %s", strerror(errno)); return -1; } return 0; } int V4L1_PWC::setWhiteBalanceMode(int val, char *errmsg) { if (val == whiteBalanceMode_) return whiteBalanceMode_; if (val != PWC_WB_AUTO) { if ( val != PWC_WB_MANUAL) { whiteBalanceMode_=val; if (setWhiteBalance(errmsg) < 0) return -1; } //whiteBalanceMode_=PWC_WB_AUTO; whiteBalanceMode_= val; if (setWhiteBalance(errmsg) < 0) return -1; getWhiteBalance(); } /*if (guiBuild()) { if (val != PWC_WB_AUTO || ( liveWhiteBalance_ && (val ==PWC_WB_AUTO))) { remoteCTRLWBred_->show(); remoteCTRLWBblue_->show(); } else { remoteCTRLWBred_->hide(); remoteCTRLWBblue_->hide(); } }*/ whiteBalanceMode_=val; if (setWhiteBalance(errmsg) < 0) return -1; getWhiteBalance(); return 0; } int V4L1_PWC::setWhiteBalanceRed(int val, char *errmsg) { whiteBalanceMode_ = PWC_WB_MANUAL; whiteBalanceRed_=val; if (setWhiteBalance(errmsg) < 0) return -1; return 0; } int V4L1_PWC::setWhiteBalanceBlue(int val, char *errmsg) { whiteBalanceMode_ = PWC_WB_MANUAL; whiteBalanceBlue_=val; if (setWhiteBalance(errmsg) < 0) return -1; return 0; } indi-0.5/src/webcam/v4l2_base.h0000644000175000017500000000731610605175707014107 0ustar jrjr/* Copyright (C) 2005 by Jasem Mutlaq Based on V4L 2 Example http://v4l2spec.bytesex.org/spec-single/v4l2.html#CAPTURE-EXAMPLE This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef V4L2_BASE_H #define V4L2_BASE_H #include #include #include "videodev2.h" #include "../eventloop.h" #include "../indidevapi.h" #define VIDEO_COMPRESSION_LEVEL 4 class V4L2_Base { public: V4L2_Base(); virtual ~V4L2_Base(); typedef enum { IO_METHOD_READ, IO_METHOD_MMAP, IO_METHOD_USERPTR } io_method; struct buffer { void * start; size_t length; }; /* Connection */ virtual int connectCam(const char * devpath, char *errmsg, int pixelFormat = -1 , int width = -1, int height = -1); virtual void disconnectCam(); char * getDeviceName(); /* Image settings */ int getBrightness(); int getContrast(); int getColor(); int getHue(); int getWhiteness(); void setContrast(int val); void setBrightness(int val); void setColor(int val); void setHue(int val); void setWhiteness(int val); /* Updates */ void callFrame(void *p); void setPictureSettings(); void getPictureSettings(); /* Image Size */ int getWidth(); int getHeight(); virtual int setSize(int x, int y); virtual void getMaxMinSize(int & x_max, int & y_max, int & x_min, int & y_min); /* Frame rate */ void setFPS(int fps); int getFPS(); void allocBuffers(); unsigned char * getY(); unsigned char * getU(); unsigned char * getV(); unsigned char * getColorBuffer(); void registerCallback(WPF *fp, void *ud); int start_capturing(char *errmsg); int stop_capturing(char *errmsg); static void newFrame(int fd, void *p); void enumerate_ctrl (void); void enumerate_menu (void); int queryINTControls(INumberVectorProperty *nvp); int setINTControl(unsigned int ctrl_id, double new_value, char *errmsg); int query_ctrl(unsigned int ctrl_id, double & ctrl_min, double & ctrl_max, double & ctrl_step, double & ctrl_value, char *errmsg); protected: int xioctl(int fd, int request, void *arg); int read_frame(char *errsg); int uninit_device(char *errmsg); int open_device(const char *devpath, char *errmsg); int init_device(char *errmsg, int pixelFormat , int width, int height); int init_mmap(char *errmsg); int errno_exit(const char *s, char *errmsg); void close_device(void); void init_userp(unsigned int buffer_size); void init_read(unsigned int buffer_size); void findMinMax(); struct v4l2_capability cap; struct v4l2_cropcap cropcap; struct v4l2_crop crop; struct v4l2_format fmt; struct v4l2_queryctrl queryctrl; struct v4l2_querymenu querymenu; WPF *callback; void *uptr; char dev_name[64]; io_method io; int fd; struct buffer *buffers; unsigned int n_buffers; bool dropFrame; int frameRate; int xmax, xmin, ymax, ymin; int selectCallBackID; unsigned char * YBuf,*UBuf,*VBuf, *colorBuffer, *rgb24_buffer; }; #endif indi-0.5/src/webcam/vcvt.h0000644000175000017500000000454510605175707013311 0ustar jrjr/* (C) 2001 Nemosoft Unv. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* 'Viewport' conversion routines. These functions convert from one colour space to another, taking into account that the source image has a smaller size than the view, and is placed inside the view: +-------view.x------------+ | | | +---image.x---+ | | | | | | | | | | +-------------+ | | | +-------------------------+ The image should always be smaller than the view. The offset (top-left corner of the image) should be precomputed, so you can place the image anywhere in the view. The functions take these parameters: - width image width (in pixels) - height image height (in pixels) - plus view width (in pixels) *src pointer at start of image *dst pointer at offset (!) in view */ #ifndef VCVT_H #define VCVT_H #ifdef __cplusplus extern "C" { #endif /* Functions in vcvt_i386.S/vcvt_c.c */ /* 4:2:0 YUV interlaced to RGB/BGR */ void vcvt_420i_bgr24(int width, int height, int plus, void *src, void *dst); void vcvt_420i_rgb24(int width, int height, int plus, void *src, void *dst); void vcvt_420i_bgr32(int width, int height, int plus, void *src, void *dst); void vcvt_420i_rgb32(int width, int height, int plus, void *src, void *dst); /* Go from 420i to other yuv formats */ void vcvt_420i_420p(int width, int height, int plus, void *src, void *dsty, void *dstu, void *dstv); void vcvt_420i_yuyv(int width, int height, int plus, void *src, void *dst); #if 0 #endif #ifdef __cplusplus } #endif #endif indi-0.5/src/webcam/empty_file.cpp0000644000175000017500000000000110605175707014776 0ustar jrjr indi-0.5/src/webcam/PPort.cpp0000644000175000017500000000455610605175707013730 0ustar jrjr/* Copyright (C) 1996-1998 by Patrick Reynolds Email: This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "PPort.h" #include "port.h" #include #include #include using namespace std; #define TEST_VALIDITY {if (this==NULL) return false;} PPort::PPort() { reset(); } PPort::PPort(int ioPort) { reset(); setPort(ioPort); } PPort::~PPort() { delete currentPort; } void PPort::reset() { bitArray=0; for (int i=0;i<8;++i) { assignedBit[i]=NULL; } currentPort=NULL; } bool PPort::setPort(int ioPort) { TEST_VALIDITY; if (geteuid() != 0) { cerr << "must be setuid root control parallel port"<write_data(bitArray); return true; } else { return false; } } bool PPort::setBit(const void * ID,int bit,bool stat) { TEST_VALIDITY; if (ID != assignedBit[bit]) { return false; } if (stat) { bitArray |= (1< This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef V4L1_PWC_H #define V4L1_PWC_H #include #include #include "videodev.h" #include "v4l1_base.h" class V4L1_PWC : public V4L1_Base { public: V4L1_PWC(); ~V4L1_PWC(); int connectCam(const char * devpath, char *errmsg); /* Philips related, from QAstrocam */ int saveSettings(char *errmsg); void restoreSettings(); void restoreFactorySettings(); int setGain(int value, char *errmsg); int getGain(); int setExposure(int val, char *errmsg); void setCompression(int value); int getCompression(); int setNoiseRemoval(int value, char *errmsg); int getNoiseRemoval(); int setSharpness(int value, char *errmsg); int getSharpness(); int setBackLight(bool val, char *errmsg); bool getBackLight(); int setFlicker(bool val, char *errmsg); bool getFlicker(); void setGama(int value); int getGama(); int setFrameRate(int value, char *errmsg); int getFrameRate(); int setWhiteBalance(char *errmsg); int getWhiteBalance(); int setWhiteBalanceMode(int val, char *errmsg); int setWhiteBalanceRed(int val, char *errmsg); int setWhiteBalanceBlue(int val, char *errmsg); /* TODO consider the SC modded cam after this void setLongExposureTime(const QString& str); void setFrameRateMultiplicateur(int value);*/ /* Updates */ //void updateFrame(int d, void *p); /* Image Size */ void checkSize(int & x, int & y); bool setSize(int x, int y); private: int whiteBalanceMode_; int whiteBalanceRed_; int whiteBalanceBlue_; int lastGain_; int multiplicateur_; int skippedFrame_; int type_; }; #endif indi-0.5/src/webcam/ccvt_misc.c0000644000175000017500000002767310605175707014303 0ustar jrjr/* CCVT: ColourConVerT: simple library for converting colourspaces Copyright (C) 2002 Nemosoft Unv. Email:athomas@nemsoft.co.uk 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA For questions, remarks, patches, etc. for this program, the author can be reached at nemosoft@smcc.demon.nl. */ /* This file contains CCVT functions that aren't available in assembly yet (or are not worth programming) */ /* * $Log$ * Revision 1.2 2005/04/29 16:51:20 mutlaqja * Adding initial support for Video 4 Linux 2 drivers. This mean that KStars can probably control Meade Lunar Planetary Imager (LPI). V4L2 requires a fairly recent kernel (> 2.6.9) and many drivers don't fully support it yet. It will take sometime. KStars still supports V4L1 and will continue so until V4L1 is obselete. Please test KStars video drivers if you can. Any comments welcomed. * * CCMAIL: kstars-devel@kde.org * * Revision 1.1 2004/06/26 23:12:03 mutlaqja * Hopefully this will fix compile issues on 64bit archs, and FreeBSD, among others. The assembly code is replaced with a more portable, albeit slower C implementation. I imported the videodev.h header after cleaning it for user space. * * Anyone who has problems compiling this, please report the problem to kstars-devel@kde.org * * I noticed one odd thing after updating my kdelibs, the LEDs don't change color when state is changed. Try that by starting any INDI device, and hit connect, if the LED turns to yellow and back to grey then it works fine, otherwise, we've got a problem. * * CCMAIL: kstars-devel@kde.org * * Revision 1.7 2003/01/02 04:10:19 nemosoft * Adding ''upside down" conversion to rgb/bgr routines * * Revision 1.6 2002/12/03 23:29:11 nemosoft * *** empty log message *** * * Revision 1.5 2002/12/03 23:27:41 nemosoft * fixing log messages (gcc 3.2 complaining) * Revision 1.4 2002/12/03 22:29:07 nemosoft Fixing up FTP stuff and some video Revision 1.3 2002/11/03 22:46:25 nemosoft Adding various RGB to RGB functions. Adding proper copyright header too. */ #include "ccvt.h" #include "ccvt_types.h" #include static float RGBYUV02990[256], RGBYUV05870[256], RGBYUV01140[256]; static float RGBYUV01684[256], RGBYUV03316[256]; static float RGBYUV04187[256], RGBYUV00813[256]; void InitLookupTable(void); /* YUYV: two Y's and one U/V */ void ccvt_yuyv_rgb32(int width, int height, const void *src, void *dst) { width=width; height=height; src=src; dst=dst; } void ccvt_yuyv_bgr32(int width, int height, const void *src, void *dst) { const unsigned char *s; PIXTYPE_bgr32 *d; int l, c; int r, g, b, cr, cg, cb, y1, y2; l = height; s = src; d = dst; while (l--) { c = width >> 2; while (c--) { y1 = *s++; cb = ((*s - 128) * 454) >> 8; cg = (*s++ - 128) * 88; y2 = *s++; cr = ((*s - 128) * 359) >> 8; cg = (cg + (*s++ - 128) * 183) >> 8; r = y1 + cr; b = y1 + cb; g = y1 - cg; SAT(r); SAT(g); SAT(b); d->b = b; d->g = g; d->r = r; d++; r = y2 + cr; b = y2 + cb; g = y2 - cg; SAT(r); SAT(g); SAT(b); d->b = b; d->g = g; d->r = r; d++; } } } void ccvt_yuyv_420p(int width, int height, const void *src, void *dsty, void *dstu, void *dstv) { int n, l, j; const unsigned char *s1, *s2; unsigned char *dy, *du, *dv; dy = (unsigned char *)dsty; du = (unsigned char *)dstu; dv = (unsigned char *)dstv; s1 = (unsigned char *)src; s2 = s1; /* keep pointer */ n = width * height; for (; n > 0; n--) { *dy = *s1; dy++; s1 += 2; } /* Two options here: average U/V values, or skip every second row */ s1 = s2; /* restore pointer */ s1++; /* point to U */ for (l = 0; l < height; l += 2) { s2 = s1 + width * 2; /* odd line */ for (j = 0; j < width; j += 2) { *du = (*s1 + *s2) / 2; du++; s1 += 2; s2 += 2; *dv = (*s1 + *s2) / 2; dv++; s1 += 2; s2 += 2; } s1 = s2; } } void bayer2rgb24(unsigned char *dst, unsigned char *src, long int WIDTH, long int HEIGHT) { long int i; unsigned char *rawpt, *scanpt; long int size; rawpt = src; scanpt = dst; size = WIDTH*HEIGHT; for ( i = 0; i < size; i++ ) { if ( (i/WIDTH) % 2 == 0 ) { if ( (i % 2) == 0 ) { /* B */ if ( (i > WIDTH) && ((i % WIDTH) > 0) ) { *scanpt++ = (*(rawpt-WIDTH-1)+*(rawpt-WIDTH+1)+ *(rawpt+WIDTH-1)+*(rawpt+WIDTH+1))/4; /* R */ *scanpt++ = (*(rawpt-1)+*(rawpt+1)+ *(rawpt+WIDTH)+*(rawpt-WIDTH))/4; /* G */ *scanpt++ = *rawpt; /* B */ } else { /* first line or left column */ *scanpt++ = *(rawpt+WIDTH+1); /* R */ *scanpt++ = (*(rawpt+1)+*(rawpt+WIDTH))/2; /* G */ *scanpt++ = *rawpt; /* B */ } } else { /* (B)G */ if ( (i > WIDTH) && ((i % WIDTH) < (WIDTH-1)) ) { *scanpt++ = (*(rawpt+WIDTH)+*(rawpt-WIDTH))/2; /* R */ *scanpt++ = *rawpt; /* G */ *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2; /* B */ } else { /* first line or right column */ *scanpt++ = *(rawpt+WIDTH); /* R */ *scanpt++ = *rawpt; /* G */ *scanpt++ = *(rawpt-1); /* B */ } } } else { if ( (i % 2) == 0 ) { /* G(R) */ if ( (i < (WIDTH*(HEIGHT-1))) && ((i % WIDTH) > 0) ) { *scanpt++ = (*(rawpt-1)+*(rawpt+1))/2; /* R */ *scanpt++ = *rawpt; /* G */ *scanpt++ = (*(rawpt+WIDTH)+*(rawpt-WIDTH))/2; /* B */ } else { /* bottom line or left column */ *scanpt++ = *(rawpt+1); /* R */ *scanpt++ = *rawpt; /* G */ *scanpt++ = *(rawpt-WIDTH); /* B */ } } else { /* R */ if ( i < (WIDTH*(HEIGHT-1)) && ((i % WIDTH) < (WIDTH-1)) ) { *scanpt++ = *rawpt; /* R */ *scanpt++ = (*(rawpt-1)+*(rawpt+1)+ *(rawpt-WIDTH)+*(rawpt+WIDTH))/4; /* G */ *scanpt++ = (*(rawpt-WIDTH-1)+*(rawpt-WIDTH+1)+ *(rawpt+WIDTH-1)+*(rawpt+WIDTH+1))/4; /* B */ } else { /* bottom line or right column */ *scanpt++ = *rawpt; /* R */ *scanpt++ = (*(rawpt-1)+*(rawpt-WIDTH))/2; /* G */ *scanpt++ = *(rawpt-WIDTH-1); /* B */ } } } rawpt++; } } /************************************************************************ * * int RGB2YUV (int x_dim, int y_dim, void *bmp, YUV *yuv) * * Purpose : It takes a 24-bit RGB bitmap and convert it into * YUV (4:2:0) format * * Input : x_dim the x dimension of the bitmap * y_dim the y dimension of the bitmap * bmp pointer to the buffer of the bitmap * yuv pointer to the YUV structure * * Output : 0 OK * 1 wrong dimension * 2 memory allocation error * * Side Effect : * None * * Date : 09/28/2000 * * Contacts: * * Adam Li * * DivX Advance Research Center * ************************************************************************/ int RGB2YUV (int x_dim, int y_dim, void *bmp, void *y_out, void *u_out, void *v_out, int flip) { static int init_done = 0; long i, j, size; unsigned char *r, *g, *b; unsigned char *y, *u, *v; unsigned char *pu1, *pu2, *pv1, *pv2, *psu, *psv; unsigned char *y_buffer, *u_buffer, *v_buffer; unsigned char *sub_u_buf, *sub_v_buf; if (init_done == 0) { InitLookupTable(); init_done = 1; } /* check to see if x_dim and y_dim are divisible by 2*/ if ((x_dim % 2) || (y_dim % 2)) return 1; size = x_dim * y_dim; /* allocate memory*/ y_buffer = (unsigned char *)y_out; sub_u_buf = (unsigned char *)u_out; sub_v_buf = (unsigned char *)v_out; u_buffer = (unsigned char *)malloc(size * sizeof(unsigned char)); v_buffer = (unsigned char *)malloc(size * sizeof(unsigned char)); if (!(u_buffer && v_buffer)) { if (u_buffer) free(u_buffer); if (v_buffer) free(v_buffer); return 2; } b = (unsigned char *)bmp; y = y_buffer; u = u_buffer; v = v_buffer; /* convert RGB to YUV*/ if (!flip) { for (j = 0; j < y_dim; j ++) { y = y_buffer + (y_dim - j - 1) * x_dim; u = u_buffer + (y_dim - j - 1) * x_dim; v = v_buffer + (y_dim - j - 1) * x_dim; for (i = 0; i < x_dim; i ++) { g = b + 1; r = b + 2; *y = (unsigned char)( RGBYUV02990[*r] + RGBYUV05870[*g] + RGBYUV01140[*b]); *u = (unsigned char)(- RGBYUV01684[*r] - RGBYUV03316[*g] + (*b)/2 + 128); *v = (unsigned char)( (*r)/2 - RGBYUV04187[*g] - RGBYUV00813[*b] + 128); b += 3; y ++; u ++; v ++; } } } else { for (i = 0; i < size; i++) { g = b + 1; r = b + 2; *y = (unsigned char)( RGBYUV02990[*r] + RGBYUV05870[*g] + RGBYUV01140[*b]); *u = (unsigned char)(- RGBYUV01684[*r] - RGBYUV03316[*g] + (*b)/2 + 128); *v = (unsigned char)( (*r)/2 - RGBYUV04187[*g] - RGBYUV00813[*b] + 128); b += 3; y ++; u ++; v ++; } } /* subsample UV*/ for (j = 0; j < y_dim/2; j ++) { psu = sub_u_buf + j * x_dim / 2; psv = sub_v_buf + j * x_dim / 2; pu1 = u_buffer + 2 * j * x_dim; pu2 = u_buffer + (2 * j + 1) * x_dim; pv1 = v_buffer + 2 * j * x_dim; pv2 = v_buffer + (2 * j + 1) * x_dim; for (i = 0; i < x_dim/2; i ++) { *psu = (*pu1 + *(pu1+1) + *pu2 + *(pu2+1)) / 4; *psv = (*pv1 + *(pv1+1) + *pv2 + *(pv2+1)) / 4; psu ++; psv ++; pu1 += 2; pu2 += 2; pv1 += 2; pv2 += 2; } } free(u_buffer); free(v_buffer); return 0; } void InitLookupTable() { int i; for (i = 0; i < 256; i++) RGBYUV02990[i] = (float)0.2990 * i; for (i = 0; i < 256; i++) RGBYUV05870[i] = (float)0.5870 * i; for (i = 0; i < 256; i++) RGBYUV01140[i] = (float)0.1140 * i; for (i = 0; i < 256; i++) RGBYUV01684[i] = (float)0.1684 * i; for (i = 0; i < 256; i++) RGBYUV03316[i] = (float)0.3316 * i; for (i = 0; i < 256; i++) RGBYUV04187[i] = (float)0.4187 * i; for (i = 0; i < 256; i++) RGBYUV00813[i] = (float)0.0813 * i; } /* RGB/BGR to RGB/BGR */ #define RGBBGR_BODY24(TIN, TOUT) \ void ccvt_ ## TIN ## _ ## TOUT (int width, int height, const void *const src, void *dst) \ { \ const PIXTYPE_ ## TIN *in = src; \ PIXTYPE_ ## TOUT *out = dst; \ int l, c, stride = 0; \ \ stride = width; \ out += ((height - 1) * width); \ stride *= 2; \ for (l = 0; l < height; l++) { \ for (c = 0; c < width; c++) { \ out->r = in->r; \ out->g = in->g; \ out->b = in->b; \ in++; \ out++; \ } \ out -= stride; \ } \ } #define RGBBGR_BODY32(TIN, TOUT) \ void ccvt_ ## TIN ## _ ## TOUT (int width, int height, const void *const src, void *dst) \ { \ const PIXTYPE_ ## TIN *in = src; \ PIXTYPE_ ## TOUT *out = dst; \ int l, c, stride = 0; \ \ stride = width;\ out += ((height - 1) * width); \ stride *= 2; \ for (l = 0; l < height; l++) { \ for (c = 0; c < width; c++) { \ out->r = in->r; \ out->g = in->g; \ out->b = in->b; \ out->z = 0; \ in++; \ out++; \ } \ out -= stride; \ } \ } RGBBGR_BODY32(bgr24, bgr32) RGBBGR_BODY32(bgr24, rgb32) RGBBGR_BODY32(rgb24, bgr32) RGBBGR_BODY32(rgb24, rgb32) RGBBGR_BODY24(bgr32, bgr24) RGBBGR_BODY24(bgr32, rgb24) RGBBGR_BODY24(rgb32, bgr24) RGBBGR_BODY24(rgb32, rgb24) indi-0.5/src/lx200basic.h0000644000175000017500000000552510610474336012733 0ustar jrjr/* LX200 Basic Driver Copyright (C) 2005 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef LX200BASIC_H #define LX200BASIC_H #include "indidevapi.h" #include "indicom.h" #define POLLMS 1000 /* poll period, ms */ #define mydev "LX200 Basic" /* The device name */ class LX200Basic { public: LX200Basic(); ~LX200Basic(); void ISGetProperties (const char *dev); void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n); void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); void ISPoll (); void connectionLost(); void connectionResumed(); private: void initProperties(); /* Switches */ ISwitch PowerS[2]; ISwitch OnCoordSetS[3]; ISwitch AbortSlewS[1]; /* Texts */ IText PortT[1]; IText ObjectT[1]; /* Numbers */ INumber EqN[2]; INumber SlewPrecisionN[2]; INumber TrackPrecisionN[2]; /* Switch Vectors */ ISwitchVectorProperty PowerSP; ISwitchVectorProperty OnCoordSetSP; ISwitchVectorProperty AbortSlewSP; /* Number Vectors */ INumberVectorProperty EqNP; INumberVectorProperty SlewPrecisionNP; INumberVectorProperty TrackPrecisionNP; /* Text Vectors */ ITextVectorProperty PortTP; ITextVectorProperty ObjectTP; void getBasicData(); int checkPower(INumberVectorProperty *np); int checkPower(ISwitchVectorProperty *sp); int checkPower(ITextVectorProperty *tp); void handleError(ISwitchVectorProperty *svp, int err, const char *msg); void handleError(INumberVectorProperty *nvp, int err, const char *msg); void handleError(ITextVectorProperty *tvp, int err, const char *msg); bool isTelescopeOn(void); void connectTelescope(); void slewError(int slewCode); int handleCoordSet(); int getOnSwitch(ISwitchVectorProperty *sp); void correctFault(); void enableSimulation(bool enable); protected: double JD; double targetRA; double targetDEC; double lastRA; double lastDEC; bool simulation; bool fault; int fd; int currentSet; int lastSet; }; #endif indi-0.5/src/indicom.h0000644000175000017500000003226510610526754012511 0ustar jrjr/* INDI LIB Common routines used by all drivers Copyright (C) 2003 by Jason Harris (jharris@30doradus.org) Elwood C. Downey Jasem Mutlaq This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** \file indicom.h \brief Implementations for common driver routines. The INDI Common Routine Library provides astronomical, mathematical, and formatting routines employed by many INDI drivers. Currently, the library is composed of the following sections:
  • Math Functions
  • Ephemeris Functions
  • Formatting Functions
  • Conversion Functions
  • TTY Functions
\author Jason Harris \author Elwood C. Downey \author Jasem Mutlaq */ #ifndef INDICOM_H #define INDICOM_H #include #ifdef HAVE_CONFIG_H #include #endif #define J2000 2451545.0 #define ERRMSG_SIZE 1024 #define INDI_DEBUG extern const char * Direction[]; extern const char * SolarSystem[]; /* TTY Error Codes */ enum TTY_ERROR { TTY_OK=0, TTY_READ_ERROR=-1, TTY_WRITE_ERROR=-2, TTY_SELECT_ERROR=-3, TTY_TIME_OUT=-4, TTY_PORT_FAILURE=-5, TTY_PARAM_ERROR=-6, TTY_ERRNO = -7}; #ifdef __cplusplus extern "C" { #endif /** * \defgroup mathFunctions Math Functions: Functions to perform common math routines. */ /*@{*/ /** \brief Convert degrees to radians. \param num number in degrees. \return number in radians. */ double DegToRad( double num ); /** \brief Convert radians to degrees. \param num number in radians. \return number in degrees. */ double RadToDeg( double num ); /** \brief Get the sin and cosine of a number. The function attempts to use GNU sincos extension when possible. The sin and cosine values for \e Degrees are stored in the \e sina and \e cosa parameters. \param Degrees the number in degrees to return its sin and cosine. \param sina pointer to a double to hold the sin value. \param cosa pointer to a double to hold the cosine value. */ void SinCos( double Degrees, double *sina, double *cosa ); /*@}*/ /** * \defgroup ttyFunctions TTY Functions: Functions to perform common terminal access routines. */ /*@{*/ /** \brief read buffer from terminal \param fd file descriptor \param buf pointer to store data. Must be initilized and big enough to hold data. \param nbytes number of bytes to read. \param timeout number of seconds to wait for terminal before a timeout error is issued. \param nbytes_read the number of bytes read. \return On success, it returns TTY_OK, otherwise, a TTY_ERROR code. */ int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read); /** \brief read buffer from terminal with a delimiter \param fd file descriptor \param buf pointer to store data. Must be initilized and big enough to hold data. \param stop_char if the function encounters \e stop_char then it stops reading and returns the buffer. \param timeout number of seconds to wait for terminal before a timeout error is issued. \param nbytes_read the number of bytes read. \return On success, it returns TTY_OK, otherwise, a TTY_ERROR code. */ int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read); /** \brief Writes a buffer to fd. \param fd file descriptor \param buffer a null-terminated buffer to write to fd. \param nbytes number of bytes to write from \e buffer \param nbytes_written the number of bytes written \return On success, it returns TTY_OK, otherwise, a TTY_ERROR code. */ int tty_write(int fd, const char * buffer, int nbytes, int *nbytes_written); /** \brief Writes a null terminated string to fd. \param fd file descriptor \param buffer the buffer to write to fd. \param nbytes_written the number of bytes written \return On success, it returns TTY_OK, otherwise, a TTY_ERROR code. */ int tty_write_string(int fd, const char * buffer, int *nbytes_written); /** \brief Establishes a tty connection to a terminal device. \param device the device node. e.g. /dev/ttyS0 \param bit_rate bit rate \param word_size number of data bits, 7 or 8, USE 8 DATA BITS with modbus \param parity 0=no parity, 1=parity EVEN, 2=parity ODD \param stop_bits number of stop bits : 1 or 2 \param fd \e fd is set to the file descriptor value on success. \return On success, it returns TTY_OK, otherwise, a TTY_ERROR code. \author Wildi Markus */ int tty_connect(const char *device, int bit_rate, int word_size, int parity, int stop_bits, int *fd); /** \brief Closes a tty connection and flushes the bus. \param fd the file descriptor to close. \return On success, it returns TTY_OK, otherwise, a TTY_ERROR code. */ int tty_disconnect(int fd); /** \brief Retrieve the tty error message \param err_code the error code return by any TTY function. \param err_msg an initialized buffer to hold the error message. \param err_msg_len length in bytes of \e err_msg */ void tty_error_msg(int err_code, char *err_msg, int err_msg_len); int tty_timeout(int fd, int timeout); /*@}*/ /** * \defgroup ephemerisFunctions Ephemeris Functions: Functions to perform common ephemeris routines. The ephemeris functions are date-dependent. Call updateAstroValues() to update orbital values used in many algorithms before using any ephemeris function. You only need to call updateAstroValues() again if you need to update the orbital values for a different date. */ /*@{*/ /** \brief Returns the obliquity of orbit. */ double obliquity(); /** \brief Returns the constant of aberration (20.49 arcsec). */ double constAberr(); /** \brief Returns the mean solar anomaly. */ double sunMeanAnomaly(); /** \brief Returns the mean solar longitude. */ double sunMeanLongitude(); /** \brief Returns the true solar anomaly. */ double sunTrueAnomaly(); /** \brief Returns the true solar longitude. */ double sunTrueLongitude(); /** \brief Returns the longitude of the Earth's perihelion point. */ double earthPerihelionLongitude(); /** \brief Returns eccentricity of Earth's orbit.*/ double earthEccentricity(); /** \brief Returns the change in obliquity due to the nutation of Earth's orbit. */ double dObliq(); /** \brief Returns the change in Ecliptic Longitude due to nutation. */ double dEcLong(); /** \brief Returns Julian centuries since J2000*/ double julianCenturies(); /** \brief Returns element of P1 precession array at position [i1][i2] */ double p1( int i1, int i2 ); /** \brief Returns element of P2 precession array at position [i1][i2] */ double p2( int i1, int i2 ); /** \brief Update all orbital values for the given date as an argument. Any subsecquent functions will use values affected by this date until changed. \param jd Julian date */ void updateAstroValues( double jd ); /** \brief Calculates the declination on the celestial sphere at 0 degrees altitude given the siderial time and latitude. \param latitude Current latitude. \param SDTime Current sideral time. \return Returns declinatation at 0 degrees altitude for the given parameters. */ double calculateDec(double latitude, double SDTime); /** \brief Calculates the right ascension on the celestial sphere at 0 degrees azimuth given the siderial time. \param SDTime Current sidereal time. \return Returns right ascension at 0 degrees azimith for the given parameters. */ double calculateRA(double SDTime); /** \brief Calculates the angular distance between two points on the celestial sphere. \param fromRA Right ascension of starting point in degrees. \param fromDEC Declination of starting point in degrees. \param toRA Right ascension of ending point in degrees. \param toDEC Declination of ending point in degrees. \return Angular separation in degrees. */ double angularDistance(double fromRA, double fromDEC, double toRA, double toDEC); /** \brief Nutate a given RA and Dec. \param RA a pointer to a double containing the Right ascension in degrees to nutate. The function stores the processed Right ascension back in this variable. \param Dec a pointer to a double containing the delination in degrees to nutate. The function stores the processed delination back in this variable. */ void nutate(double *RA, double *Dec); /** \brief Aberrate a given RA and Dec. \param RA a pointer to a double containing the Right ascension in degrees to aberrate. The function stores the processed Right ascension back in this variable. \param Dec a pointer to a double containing the delination in degrees to aberrate. The function stores the processed delination back in this variable. */ void aberrate(double *RA, double *Dec); /** \brief Precess the given RA and Dec from any epoch to any epoch. \param jd0 starting epoch. \param jdf final epoch. \param RA a pointer to a double containing the Right ascension in degrees to precess. The function stores the processed Right ascension back in this variable. \param Dec a pointer to a double containing the delination in degrees to precess. The function stores the processed delination back in this variable. */ void precessFromAnyEpoch(double jd0, double jdf, double *RA, double *Dec); /** \brief Calculate the apparent coordiantes for RA and Dec from any epoch to any epoch. \param jd0 starting epoch. \param jdf final epoch. \param RA a pointer to a double containing the Right ascension in hours. The function stores the processed Right ascension back in this variable. \param Dec a pointer to a double containing the delination in degrees. The function stores the processed delination back in this variable. */ void apparentCoord(double jd0, double jdf, double *RA, double *Dec); /*@}*/ /** * \defgroup convertFunctions Formatting Functions: Functions to perform handy formatting and conversion routines. */ /*@{*/ /** \brief Converts a sexagesimal number to a string. sprint the variable a in sexagesimal format into out[]. \param out a pointer to store the sexagesimal number. \param a the sexagesimal number to convert. \param w the number of spaces in the whole part. \param fracbase is the number of pieces a whole is to broken into; valid options:\n \li 360000: \:mm:ss.ss \li 36000: \:mm:ss.s \li 3600: \:mm:ss \li 600: \:mm.m \li 60: \:mm \return number of characters written to out, not counting final null terminator. */ int fs_sexa (char *out, double a, int w, int fracbase); /** \brief convert sexagesimal string str AxBxC to double. x can be anything non-numeric. Any missing A, B or C will be assumed 0. Optional - and + can be anywhere. \param str0 string containing sexagesimal number. \param dp pointer to a double to store the sexagesimal number. \return return 0 if ok, -1 if can't find a thing. */ int f_scansexa (const char *str0, double *dp); /** \brief Extract ISO 8601 time and store it in a tm struct. \param timestr a string containing date and time in ISO 8601 format. \param utm a pointer to a \e tm structure to store the extracted time and date. \return 0 on success, -1 on failure. */ int extractISOTime(char *timestr, struct tm *utm); /** \brief Converts Universal Time to Julian Date. \param utm a pointer to a structure holding the universal time and date. \return The Julian date fot the passed universal time. */ double UTtoJD(struct tm *utm); /** \brief Return the degree, minute, and second components of a sexagesimal number. \param value sexagesimal number to decompose. \param d a pointer to double to store the degrees field. \param m a pointer to a double to store the minutes field. \param s a pointer to a double to store the seconds field. */ /** \brief Converts Julian Date to Greenwich Sidereal Time. \param jd The Julian date \return GMST in degrees */ double JDtoGMST( double jd ); void getSexComponents(double value, int *d, int *m, int *s); /** \brief Fill buffer with properly formatted INumber string. \param buf to store the formatted string. \param format format in sprintf style. \param value the number to format. \return length of string. */ int numberFormat (char *buf, const char *format, double value); /** \brief Fill buffer with properly formatted INumber string. \param buf to store the formatted string. \param format format in sprintf style. \param value the number to format. \return length of string. */ int numberFormat (char *buf, const char *format, double value); /** \brief Create an ISO 8601 formatted time stamp. The format is YYYY-MM-DDTHH:MM:SS \return The formatted time stamp. */ const char *timestamp (void); /*@}*/ #ifdef __cplusplus } #endif #endif indi-0.5/src/lx200generic.cpp0000644000175000017500000015064310610474326013622 0ustar jrjr#if 0 LX200 Generic Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include #include #include #include #include #include "indicom.h" #include "lx200driver.h" #include "lx200gps.h" #include "lx200classic.h" LX200Generic *telescope = NULL; int MaxReticleFlashRate = 3; /* There is _one_ binary for all LX200 drivers, but each binary is renamed ** to its device name (i.e. lx200gps, lx200_16..etc). The main function will ** fetch from std args the binary name and ISInit will create the apporpiate ** device afterwards. If the binary name does not match any known devices, ** we simply create a generic device */ extern char* me; #define COMM_GROUP "Communication" #define BASIC_GROUP "Main Control" #define MOVE_GROUP "Movement Control" #define DATETIME_GROUP "Date/Time" #define SITE_GROUP "Site Management" #define FOCUS_GROUP "Focus Control" #define LX200_SLEW 0 #define LX200_TRACK 1 #define LX200_SYNC 2 #define LX200_PARK 3 /* Simulation Parameters */ #define SLEWRATE 1 /* slew rate, degrees/s */ #define SIDRATE 0.004178 /* sidereal rate, degrees/s */ static void ISPoll(void *); static void retryConnection(void *); /*INDI controls */ static ISwitch PowerS[] = {{"CONNECT" , "Connect" , ISS_OFF, 0, 0},{"DISCONNECT", "Disconnect", ISS_ON, 0, 0}}; static ISwitch AlignmentS [] = {{"Polar", "", ISS_ON, 0, 0}, {"AltAz", "", ISS_OFF, 0, 0}, {"Land", "", ISS_OFF, 0, 0}}; static ISwitch SitesS[] = {{"Site 1", "", ISS_ON, 0, 0}, {"Site 2", "", ISS_OFF, 0, 0}, {"Site 3", "", ISS_OFF, 0, 0}, {"Site 4", "", ISS_OFF, 0 ,0}}; static ISwitch SlewModeS[] = {{"Max", "", ISS_ON, 0, 0}, {"Find", "", ISS_OFF, 0, 0}, {"Centering", "", ISS_OFF, 0, 0}, {"Guide", "", ISS_OFF, 0 , 0}}; static ISwitch OnCoordSetS[] = {{"SLEW", "Slew", ISS_ON, 0, 0 }, {"TRACK", "Track", ISS_OFF, 0, 0}, {"SYNC", "Sync", ISS_OFF, 0 , 0}}; static ISwitch TrackModeS[] = {{ "Default", "", ISS_ON, 0, 0} , { "Lunar", "", ISS_OFF, 0, 0}, {"Manual", "", ISS_OFF, 0, 0}}; static ISwitch abortSlewS[] = {{"ABORT", "Abort", ISS_OFF, 0, 0 }}; static ISwitch ParkS[] = { {"PARK", "Park", ISS_OFF, 0, 0} }; ISwitch FocusMotionS[] = { {"IN", "Focus in", ISS_OFF, 0, 0}, {"OUT", "Focus out", ISS_OFF, 0, 0}}; ISwitchVectorProperty FocusMotionSw = {mydev, "FOCUS_MOTION", "Motion", FOCUS_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, FocusMotionS, NARRAY(FocusMotionS), "", 0}; INumber FocusTimerN[] = { {"TIMER", "Timer (ms)", "%g", 0., 10000., 1000., 50., 0, 0, 0 }}; INumberVectorProperty FocusTimerNP = { mydev, "FOCUS_TIMER", "Focus Timer", FOCUS_GROUP, IP_RW, 0, IPS_IDLE, FocusTimerN, NARRAY(FocusTimerN), "", 0}; /* equatorial position */ INumber eq[] = { {"RA", "RA H:M:S", "%10.6m", 0., 24., 0., 0., 0, 0, 0}, {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}, }; INumberVectorProperty eqNum = { mydev, "EQUATORIAL_EOD_COORD", "Equatorial JNow", BASIC_GROUP, IP_RW, 0, IPS_IDLE, eq, NARRAY(eq), "", 0}; /* Fundamental group */ ISwitchVectorProperty PowerSP = { mydev, "CONNECTION" , "Connection", COMM_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, PowerS, NARRAY(PowerS), "", 0}; static IText PortT[] = {{"PORT", "Port", 0, 0, 0, 0}}; static ITextVectorProperty Port = { mydev, "DEVICE_PORT", "Ports", COMM_GROUP, IP_RW, 0, IPS_IDLE, PortT, NARRAY(PortT), "", 0}; /* Basic data group */ static ISwitchVectorProperty AlignmentSw = { mydev, "Alignment", "", COMM_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, AlignmentS, NARRAY(AlignmentS), "", 0}; /* Movement group */ static ISwitchVectorProperty OnCoordSetSw = { mydev, "ON_COORD_SET", "On Set", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, OnCoordSetS, NARRAY(OnCoordSetS), "", 0}; static ISwitchVectorProperty abortSlewSw = { mydev, "ABORT_MOTION", "Abort Slew/Track", BASIC_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, abortSlewS, NARRAY(abortSlewS), "", 0}; ISwitchVectorProperty ParkSP = {mydev, "PARK", "Park Scope", BASIC_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE, ParkS, NARRAY(ParkS), "", 0 }; static ISwitchVectorProperty SlewModeSw = { mydev, "Slew rate", "", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, SlewModeS, NARRAY(SlewModeS), "", 0}; static ISwitchVectorProperty TrackModeSw = { mydev, "Tracking Mode", "", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, TrackModeS, NARRAY(TrackModeS), "", 0}; static INumber TrackFreq[] = {{ "trackFreq", "Freq", "%g", 56.4, 60.1, 0.1, 60.1, 0, 0, 0}}; static INumberVectorProperty TrackingFreq= { mydev, "Tracking Frequency", "", MOVE_GROUP, IP_RW, 0, IPS_IDLE, TrackFreq, NARRAY(TrackFreq), "", 0}; /* Movement (Arrow keys on handset). North/South */ static ISwitch MovementNSS[] = {{"N", "North", ISS_OFF, 0, 0}, {"S", "South", ISS_OFF, 0, 0}}; static ISwitchVectorProperty MovementNSSP = { mydev, "MOVEMENT_NS", "North/South", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, MovementNSS, NARRAY(MovementNSS), "", 0}; /* Movement (Arrow keys on handset). West/East */ static ISwitch MovementWES[] = {{"W", "West", ISS_OFF, 0, 0}, {"E", "East", ISS_OFF, 0, 0}}; static ISwitchVectorProperty MovementWESP = { mydev, "MOVEMENT_WE", "West/East", MOVE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, MovementWES, NARRAY(MovementWES), "", 0}; static ISwitch FocusModeS[] = { {"FOCUS_HALT", "Halt", ISS_ON, 0, 0}, {"FOCUS_SLOW", "Slow", ISS_OFF, 0, 0}, {"FOCUS_FAST", "Fast", ISS_OFF, 0, 0}}; static ISwitchVectorProperty FocusModeSP = {mydev, "FOCUS_MODE", "Mode", FOCUS_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, FocusModeS, NARRAY(FocusModeS), "", 0}; /* Data & Time */ static IText UTC[] = {{"UTC", "UTC", 0, 0, 0, 0}}; ITextVectorProperty Time = { mydev, "TIME_UTC", "UTC Time", DATETIME_GROUP, IP_RW, 0, IPS_IDLE, UTC, NARRAY(UTC), "", 0}; /* DST Corrected UTC Offfset */ static INumber UTCOffsetN[] = {{"OFFSET", "Offset", "%0.3g" , -12.,12.,0.5,0., 0, 0, 0}}; INumberVectorProperty UTCOffsetNP = { mydev, "UTC_OFFSET", "UTC Offset", DATETIME_GROUP, IP_RW, 0, IPS_IDLE, UTCOffsetN , NARRAY(UTCOffsetN), "", 0}; /* Sidereal Time */ static INumber STime[] = {{"LST", "Sidereal time", "%10.6m" , 0.,24.,0.,0., 0, 0, 0}}; INumberVectorProperty SDTime = { mydev, "TIME_LST", "Sidereal Time", DATETIME_GROUP, IP_RW, 0, IPS_IDLE, STime, NARRAY(STime), "", 0}; /* Tracking precision */ INumber trackingPrecisionN[] = { {"TrackRA", "RA (arcmin)", "%g", 0., 60., 1., 3.0, 0, 0, 0}, {"TrackDEC", "Dec (arcmin)", "%g", 0., 60., 1., 3.0, 0, 0, 0}, }; static INumberVectorProperty trackingPrecisionNP = {mydev, "Tracking Precision", "", MOVE_GROUP, IP_RW, 0, IPS_IDLE, trackingPrecisionN, NARRAY(trackingPrecisionN), "", 0}; /* Slew precision */ INumber slewPrecisionN[] = { {"SlewRA", "RA (arcmin)", "%g", 0., 60., 1., 3.0, 0, 0, 0}, {"SlewDEC", "Dec (arcmin)", "%g", 0., 60., 1., 3.0, 0, 0, 0}, }; static INumberVectorProperty slewPrecisionNP = {mydev, "Slew Precision", "", MOVE_GROUP, IP_RW, 0, IPS_IDLE, slewPrecisionN, NARRAY(slewPrecisionN), "", 0}; /* Site management */ static ISwitchVectorProperty SitesSw = { mydev, "Sites", "", SITE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, SitesS, NARRAY(SitesS), "", 0}; /* geographic location */ static INumber geo[] = { {"LAT", "Lat. D:M:S +N", "%10.6m", -90., 90., 0., 0., 0, 0, 0}, {"LONG", "Long. D:M:S +E", "%10.6m", 0., 360., 0., 0., 0, 0, 0}, }; static INumberVectorProperty geoNum = { mydev, "GEOGRAPHIC_COORD", "Geographic Location", SITE_GROUP, IP_RW, 0., IPS_IDLE, geo, NARRAY(geo), "", 0}; static IText SiteNameT[] = {{"SiteName", "", 0, 0, 0, 0}}; static ITextVectorProperty SiteName = { mydev, "Site Name", "", SITE_GROUP, IP_RW, 0 , IPS_IDLE, SiteNameT, NARRAY(SiteNameT), "", 0}; void changeLX200GenericDeviceName(const char * newName) { strcpy(PowerSP.device , newName); strcpy(Port.device , newName); strcpy(AlignmentSw.device, newName); // BASIC_GROUP strcpy(eqNum.device, newName); strcpy(OnCoordSetSw.device , newName ); strcpy(abortSlewSw.device , newName ); strcpy(ParkSP.device, newName); // MOVE_GROUP strcpy(SlewModeSw.device , newName ); strcpy(TrackModeSw.device , newName ); strcpy(TrackingFreq.device , newName ); strcpy(MovementNSSP.device , newName ); strcpy(MovementWESP.device , newName ); strcpy(trackingPrecisionNP.device, newName); strcpy(slewPrecisionNP.device, newName); // FOCUS_GROUP strcpy(FocusModeSP.device , newName ); strcpy(FocusMotionSw.device , newName ); strcpy(FocusTimerNP.device, newName); // DATETIME_GROUP strcpy(Time.device , newName ); strcpy(UTCOffsetNP.device , newName ); strcpy(SDTime.device , newName ); // SITE_GROUP strcpy(SitesSw.device , newName ); strcpy(SiteName.device , newName ); strcpy(geoNum.device , newName ); } void changeAllDeviceNames(const char *newName) { changeLX200GenericDeviceName(newName); changeLX200AutostarDeviceName(newName); changeLX200_16DeviceName(newName); changeLX200ClassicDeviceName(newName); changeLX200GPSDeviceName(newName); } /* send client definitions of all properties */ void ISInit() { static int isInit=0; if (isInit) return; isInit = 1; IUSaveText(&PortT[0], "/dev/ttyS0"); IUSaveText(&UTC[0], "YYYY-MM-DDTHH:MM:SS"); // We need to check if UTCOffset has been set by user or not UTCOffsetN[0].aux0 = (int *) malloc(sizeof(int)); *((int *) UTCOffsetN[0].aux0) = 0; if (strstr(me, "lx200classic")) { fprintf(stderr , "initilizaing from LX200 classic device...\n"); // 1. mydev = device_name changeAllDeviceNames("LX200 Classic"); // 2. device = sub_class telescope = new LX200Classic(); telescope->setCurrentDeviceName("LX200 Classic"); MaxReticleFlashRate = 3; } else if (strstr(me, "lx200gps")) { fprintf(stderr , "initilizaing from LX200 GPS device...\n"); // 1. mydev = device_name changeAllDeviceNames("LX200 GPS"); // 2. device = sub_class telescope = new LX200GPS(); telescope->setCurrentDeviceName("LX200 GPS"); MaxReticleFlashRate = 9; } else if (strstr(me, "lx200_16")) { IDLog("Initilizaing from LX200 16 device...\n"); // 1. mydev = device_name changeAllDeviceNames("LX200 16"); // 2. device = sub_class telescope = new LX200_16(); telescope->setCurrentDeviceName("LX200 16"); MaxReticleFlashRate = 3; } else if (strstr(me, "lx200autostar")) { fprintf(stderr , "initilizaing from autostar device...\n"); // 1. change device name changeAllDeviceNames("LX200 Autostar"); // 2. device = sub_class telescope = new LX200Autostar(); telescope->setCurrentDeviceName("LX200 Autostar"); MaxReticleFlashRate = 9; } // be nice and give them a generic device else { telescope = new LX200Generic(); telescope->setCurrentDeviceName("LX200 Generic"); } } void ISGetProperties (const char *dev) { ISInit(); telescope->ISGetProperties(dev); IEAddTimer (POLLMS, ISPoll, NULL);} void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { ISInit(); telescope->ISNewSwitch(dev, name, states, names, n);} void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { ISInit(); telescope->ISNewText(dev, name, texts, names, n);} void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { ISInit(); telescope->ISNewNumber(dev, name, values, names, n);} void ISPoll (void *p) { telescope->ISPoll(); IEAddTimer (POLLMS, ISPoll, NULL); p=p;} void ISNewBLOB (const char */*dev*/, const char */*name*/, int */*sizes[]*/, char **/*blobs[]*/, char **/*formats[]*/, char **/*names[]*/, int /*n*/) {} /************************************************** *** LX200 Generic Implementation ***************************************************/ LX200Generic::LX200Generic() { currentSiteNum = 1; trackingMode = LX200_TRACK_DEFAULT; lastSet = -1; fault = false; simulation = false; targetRA = 0; targetDEC = 0; currentRA = 0; currentDEC = 0; currentSet = 0; fd = -1; // Children call parent routines, this is the default IDLog("initilizaing from generic LX200 device...\n"); IDLog("Driver Version: 2006-09-17\n"); //enableSimulation(true); } LX200Generic::~LX200Generic() { } void LX200Generic::setCurrentDeviceName(const char * devName) { strcpy(thisDevice, devName); } void LX200Generic::ISGetProperties(const char *dev) { if (dev && strcmp (thisDevice, dev)) return; // COMM_GROUP IDDefSwitch (&PowerSP, NULL); IDDefText (&Port, NULL); IDDefSwitch (&AlignmentSw, NULL); // BASIC_GROUP IDDefNumber (&eqNum, NULL); IDDefSwitch (&OnCoordSetSw, NULL); IDDefSwitch (&abortSlewSw, NULL); IDDefSwitch (&ParkSP, NULL); // MOVE_GROUP IDDefNumber (&TrackingFreq, NULL); IDDefSwitch (&SlewModeSw, NULL); IDDefSwitch (&TrackModeSw, NULL); IDDefSwitch (&MovementNSSP, NULL); IDDefSwitch (&MovementWESP, NULL); IDDefNumber (&trackingPrecisionNP, NULL); IDDefNumber (&slewPrecisionNP, NULL); // FOCUS_GROUP IDDefSwitch(&FocusModeSP, NULL); IDDefSwitch(&FocusMotionSw, NULL); IDDefNumber(&FocusTimerNP, NULL); // DATETIME_GROUP IDDefText (&Time, NULL); IDDefNumber(&UTCOffsetNP, NULL); IDDefNumber (&SDTime, NULL); // SITE_GROUP IDDefSwitch (&SitesSw, NULL); IDDefText (&SiteName, NULL); IDDefNumber (&geoNum, NULL); /* Send the basic data to the new client if the previous client(s) are already connected. */ if (PowerSP.s == IPS_OK) getBasicData(); } void LX200Generic::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { int err; IText *tp; // ignore if not ours // if (strcmp (dev, thisDevice)) return; // suppress warning n=n; if (!strcmp(name, Port.name) ) { Port.s = IPS_OK; tp = IUFindText( &Port, names[0] ); if (!tp) return; tp->text = new char[strlen(texts[0])+1]; strcpy(tp->text, texts[0]); IDSetText (&Port, NULL); return; } if (!strcmp (name, SiteName.name) ) { if (checkPower(&SiteName)) return; if ( ( err = setSiteName(fd, texts[0], currentSiteNum) < 0) ) { handleError(&SiteName, err, "Setting site name"); return; } SiteName.s = IPS_OK; tp = IUFindText(&SiteName, names[0]); tp->text = new char[strlen(texts[0])+1]; strcpy(tp->text, texts[0]); IDSetText(&SiteName , "Site name updated"); return; } if (!strcmp (name, Time.name)) { if (checkPower(&Time)) return; struct tm utm; struct tm ltm; time_t time_epoch; if (*((int *) UTCOffsetN[0].aux0) == 0) { Time.s = IPS_IDLE; IDSetText(&Time, "You must set the UTC Offset property first."); return; } if (extractISOTime(texts[0], &utm) < 0) { Time.s = IPS_IDLE; IDSetText(&Time , "Time invalid"); return; } // update JD JD = UTtoJD(&utm); IDLog("New JD is %f\n", (float) JD); // Get epoch since given UTC (we're assuming it's LOCAL for now, then we'll subtract UTC to get local) // Since mktime only returns epoch given a local calender time time_epoch = mktime(&utm); // Add UTC Offset to get local time. The offset is assumed to be DST corrected. time_epoch += (int) (UTCOffsetN[0].value * 60.0 * 60.0); // Now let's get the local time localtime_r(&time_epoch, <m); ltm.tm_mon +=1; ltm.tm_year += 1900; // Set Local Time if ( ( err = setLocalTime(fd, ltm.tm_hour, ltm.tm_min, ltm.tm_sec) < 0) ) { handleError(&Time, err, "Setting local time"); return; } // GPS needs UTC date? // TODO Test This! // Make it calender representation utm.tm_mon += 1; utm.tm_year += 1900; if (!strcmp(dev, "LX200 GPS")) { if ( ( err = setCalenderDate(fd, utm.tm_mday, utm.tm_mon, utm.tm_year) < 0) ) { handleError(&Time, err, "Setting UTC date."); return; } } else { if ( ( err = setCalenderDate(fd, ltm.tm_mday, ltm.tm_mon, ltm.tm_year) < 0) ) { handleError(&Time, err, "Setting local date."); return; } } // Everything Ok, save time value if (IUUpdateTexts(&Time, texts, names, n) < 0) return; Time.s = IPS_OK; IDSetText(&Time , "Time updated to %s, updating planetary data...", texts[0]); // Also update telescope's sidereal time getSDTime(fd, &STime[0].value); IDSetNumber(&SDTime, NULL); } } void LX200Generic::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { int h =0, m =0, s=0, err; double newRA =0, newDEC =0; // ignore if not ours // if (strcmp (dev, thisDevice)) return; // Tracking Precision if (!strcmp (name, trackingPrecisionNP.name)) { if (!IUUpdateNumbers(&trackingPrecisionNP, values, names, n)) { trackingPrecisionNP.s = IPS_OK; IDSetNumber(&trackingPrecisionNP, NULL); return; } trackingPrecisionNP.s = IPS_ALERT; IDSetNumber(&trackingPrecisionNP, "unknown error while setting tracking precision"); return; } // Slew Precision if (!strcmp(name, slewPrecisionNP.name)) { IUUpdateNumbers(&slewPrecisionNP, values, names, n); { slewPrecisionNP.s = IPS_OK; IDSetNumber(&slewPrecisionNP, NULL); return; } slewPrecisionNP.s = IPS_ALERT; IDSetNumber(&slewPrecisionNP, "unknown error while setting slew precision"); return; } // DST Correct UTC Offset if (!strcmp (name, UTCOffsetNP.name)) { if (strcmp(names[0], UTCOffsetN[0].name)) { UTCOffsetNP.s = IPS_ALERT; IDSetNumber( &UTCOffsetNP , "Unknown element %s for property %s.", names[0], UTCOffsetNP.label); return; } if ( ( err = setUTCOffset(fd, (values[0] * -1.0)) < 0) ) { UTCOffsetNP.s = IPS_ALERT; IDSetNumber( &UTCOffsetNP , "Setting UTC Offset failed."); return; } *((int *) UTCOffsetN[0].aux0) = 1; IUUpdateNumbers(&UTCOffsetNP, values, names, n); UTCOffsetNP.s = IPS_OK; IDSetNumber(&UTCOffsetNP, NULL); return; } if (!strcmp (name, eqNum.name)) { int i=0, nset=0; if (checkPower(&eqNum)) return; for (nset = i = 0; i < n; i++) { INumber *eqp = IUFindNumber (&eqNum, names[i]); if (eqp == &eq[0]) { newRA = values[i]; nset += newRA >= 0 && newRA <= 24.0; } else if (eqp == &eq[1]) { newDEC = values[i]; nset += newDEC >= -90.0 && newDEC <= 90.0; } } if (nset == 2) { /*eqNum.s = IPS_BUSY;*/ char RAStr[32], DecStr[32]; fs_sexa(RAStr, newRA, 2, 3600); fs_sexa(DecStr, newDEC, 2, 3600); #ifdef INDI_DEBUG IDLog("We received JNOW RA %g - DEC %g\n", newRA, newDEC); IDLog("We received JNOW RA %s - DEC %s\n", RAStr, DecStr); #endif if (!simulation) if ( (err = setObjectRA(fd, newRA)) < 0 || ( err = setObjectDEC(fd, newDEC)) < 0) { handleError(&eqNum, err, "Setting RA/DEC"); return; } /*eqNum.s = IPS_BUSY;*/ targetRA = newRA; targetDEC = newDEC; if (MovementNSSP.s == IPS_BUSY || MovementWESP.s == IPS_BUSY) { IUResetSwitches(&MovementNSSP); IUResetSwitches(&MovementWESP); MovementNSSP.s = MovementWESP.s = IPS_IDLE; IDSetSwitch(&MovementNSSP, NULL); IDSetSwitch(&MovementWESP, NULL); } if (handleCoordSet()) { eqNum.s = IPS_IDLE; IDSetNumber(&eqNum, NULL); } } // end nset else { eqNum.s = IPS_IDLE; IDSetNumber(&eqNum, "RA or Dec missing or invalid"); } return; } /* end eqNum */ if ( !strcmp (name, SDTime.name) ) { if (checkPower(&SDTime)) return; if (values[0] < 0.0 || values[0] > 24.0) { SDTime.s = IPS_IDLE; IDSetNumber(&SDTime , "Time invalid"); return; } getSexComponents(values[0], &h, &m, &s); IDLog("Siderial Time is %02d:%02d:%02d\n", h, m, s); if ( ( err = setSDTime(fd, h, m, s) < 0) ) { handleError(&SDTime, err, "Setting siderial time"); return; } SDTime.np[0].value = values[0]; SDTime.s = IPS_OK; IDSetNumber(&SDTime , "Sidereal time updated to %02d:%02d:%02d", h, m, s); return; } if (!strcmp (name, geoNum.name)) { // new geographic coords double newLong = 0, newLat = 0; int i, nset; char msg[128]; if (checkPower(&geoNum)) return; for (nset = i = 0; i < n; i++) { INumber *geop = IUFindNumber (&geoNum, names[i]); if (geop == &geo[0]) { newLat = values[i]; nset += newLat >= -90.0 && newLat <= 90.0; } else if (geop == &geo[1]) { newLong = values[i]; nset += newLong >= 0.0 && newLong < 360.0; } } if (nset == 2) { char l[32], L[32]; geoNum.s = IPS_OK; fs_sexa (l, newLat, 3, 3600); fs_sexa (L, newLong, 4, 3600); if ( ( err = setSiteLongitude(fd, 360.0 - newLong) < 0) ) { handleError(&geoNum, err, "Setting site coordinates"); return; } setSiteLatitude(fd, newLat); geoNum.np[0].value = newLat; geoNum.np[1].value = newLong; snprintf (msg, sizeof(msg), "Site location updated to Lat %.32s - Long %.32s", l, L); } else { geoNum.s = IPS_IDLE; strcpy(msg, "Lat or Long missing or invalid"); } IDSetNumber (&geoNum, "%s", msg); return; } if ( !strcmp (name, TrackingFreq.name) ) { if (checkPower(&TrackingFreq)) return; IDLog("Trying to set track freq of: %f\n", values[0]); if ( ( err = setTrackFreq(fd, values[0])) < 0) { handleError(&TrackingFreq, err, "Setting tracking frequency"); return; } TrackingFreq.s = IPS_OK; TrackingFreq.np[0].value = values[0]; IDSetNumber(&TrackingFreq, "Tracking frequency set to %04.1f", values[0]); if (trackingMode != LX200_TRACK_MANUAL) { trackingMode = LX200_TRACK_MANUAL; TrackModeS[0].s = ISS_OFF; TrackModeS[1].s = ISS_OFF; TrackModeS[2].s = ISS_ON; TrackModeSw.s = IPS_OK; selectTrackingMode(fd, trackingMode); IDSetSwitch(&TrackModeSw, NULL); } return; } if (!strcmp(name, FocusTimerNP.name)) { if (checkPower(&FocusTimerNP)) return; // Don't update if busy if (FocusTimerNP.s == IPS_BUSY) return; IUUpdateNumbers(&FocusTimerNP, values, names, n); FocusTimerNP.s = IPS_OK; IDSetNumber(&FocusTimerNP, NULL); IDLog("Setting focus timer to %g\n", FocusTimerN[0].value); return; } } void LX200Generic::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { int index; int dd, mm, err; // suppress warning names = names; //IDLog("in new Switch with Device= %s and Property= %s and #%d items\n", dev, name,n); //IDLog("SolarSw name is %s\n", SolarSw.name); //IDLog("The device name is %s\n", dev); // ignore if not ours // if (strcmp (thisDevice, dev)) return; // FIRST Switch ALWAYS for power if (!strcmp (name, PowerSP.name)) { if (IUUpdateSwitches(&PowerSP, states, names, n) < 0) return; connectTelescope(); return; } // Coord set if (!strcmp(name, OnCoordSetSw.name)) { if (checkPower(&OnCoordSetSw)) return; if (IUUpdateSwitches(&OnCoordSetSw, states, names, n) < 0) return; currentSet = getOnSwitch(&OnCoordSetSw); OnCoordSetSw.s = IPS_OK; IDSetSwitch(&OnCoordSetSw, NULL); } // Parking if (!strcmp(name, ParkSP.name)) { if (checkPower(&ParkSP)) return; ParkSP.s = IPS_IDLE; if ( (err = getSDTime(fd, &STime[0].value)) < 0) { handleError(&ParkSP, err, "Get siderial time"); return; } if (AlignmentS[0].s == ISS_ON) { targetRA = STime[0].value; targetDEC = 0; setObjectRA(fd, targetRA); setObjectDEC(fd, targetDEC); } else if (AlignmentS[1].s == ISS_ON) { targetRA = calculateRA(STime[0].value); targetDEC = calculateDec(geo[0].value, STime[0].value); setObjectRA(fd, targetRA); setObjectDEC(fd, targetDEC); IDLog("Parking the scope in AltAz (0,0) which corresponds to (RA,DEC) of (%g,%g)\n", targetRA, targetDEC); IDLog("Current Sidereal time is: %g\n", STime[0].value); IDSetNumber(&SDTime, NULL); } else { IDSetSwitch(&ParkSP, "You can only park the telescope in Polar or AltAz modes."); return; } IDSetNumber(&SDTime, NULL); currentSet = LX200_PARK; handleCoordSet(); } // Abort Slew if (!strcmp (name, abortSlewSw.name)) { if (checkPower(&abortSlewSw)) { abortSlewSw.s = IPS_IDLE; IDSetSwitch(&abortSlewSw, NULL); return; } IUResetSwitches(&abortSlewSw); abortSlew(fd); if (eqNum.s == IPS_BUSY) { abortSlewSw.s = IPS_OK; eqNum.s = IPS_IDLE; IDSetSwitch(&abortSlewSw, "Slew aborted."); IDSetNumber(&eqNum, NULL); } else if (MovementNSSP.s == IPS_BUSY || MovementWESP.s == IPS_BUSY) { MovementNSSP.s = MovementWESP.s = IPS_IDLE; abortSlewSw.s = IPS_OK; eqNum.s = IPS_IDLE; IUResetSwitches(&MovementNSSP); IUResetSwitches(&MovementWESP); IUResetSwitches(&abortSlewSw); IDSetSwitch(&abortSlewSw, "Slew aborted."); IDSetSwitch(&MovementNSSP, NULL); IDSetSwitch(&MovementWESP, NULL); IDSetNumber(&eqNum, NULL); } else { abortSlewSw.s = IPS_IDLE; IDSetSwitch(&abortSlewSw, NULL); } return; } // Alignment if (!strcmp (name, AlignmentSw.name)) { if (checkPower(&AlignmentSw)) return; if (IUUpdateSwitches(&AlignmentSw, states, names, n) < 0) return; index = getOnSwitch(&AlignmentSw); if ( ( err = setAlignmentMode(fd, index) < 0) ) { handleError(&AlignmentSw, err, "Setting alignment"); return; } AlignmentSw.s = IPS_OK; IDSetSwitch (&AlignmentSw, NULL); return; } // Sites if (!strcmp (name, SitesSw.name)) { if (checkPower(&SitesSw)) return; if (IUUpdateSwitches(&SitesSw, states, names, n) < 0) return; currentSiteNum = getOnSwitch(&SitesSw) + 1; if ( ( err = selectSite(fd, currentSiteNum) < 0) ) { handleError(&SitesSw, err, "Selecting sites"); return; } if ( ( err = getSiteLatitude(fd, &dd, &mm) < 0)) { handleError(&SitesSw, err, "Selecting sites"); return; } if (dd > 0) geoNum.np[0].value = dd + mm / 60.0; else geoNum.np[0].value = dd - mm / 60.0; if ( ( err = getSiteLongitude(fd, &dd, &mm) < 0)) { handleError(&SitesSw, err, "Selecting sites"); return; } if (dd > 0) geoNum.np[1].value = 360.0 - (dd + mm / 60.0); else geoNum.np[1].value = (dd - mm / 60.0) * -1.0; getSiteName(fd, SiteName.tp[0].text, currentSiteNum); IDLog("Selecting site %d\n", currentSiteNum); geoNum.s = SiteName.s = SitesSw.s = IPS_OK; IDSetNumber (&geoNum, NULL); IDSetText (&SiteName, NULL); IDSetSwitch (&SitesSw, NULL); return; } // Focus Motion if (!strcmp (name, FocusMotionSw.name)) { if (checkPower(&FocusMotionSw)) return; // If mode is "halt" if (FocusModeS[0].s == ISS_ON) { FocusMotionSw.s = IPS_IDLE; IDSetSwitch(&FocusMotionSw, NULL); return; } if (IUUpdateSwitches(&FocusMotionSw, states, names, n) < 0) return; index = getOnSwitch(&FocusMotionSw); if ( ( err = setFocuserMotion(fd, index) < 0) ) { handleError(&FocusMotionSw, err, "Setting focuser speed"); return; } FocusMotionSw.s = IPS_BUSY; // with a timer if (FocusTimerN[0].value > 0) { FocusTimerNP.s = IPS_BUSY; IEAddTimer(50, LX200Generic::updateFocusTimer, this); } IDSetSwitch(&FocusMotionSw, NULL); return; } // Slew mode if (!strcmp (name, SlewModeSw.name)) { if (checkPower(&SlewModeSw)) return; if (IUUpdateSwitches(&SlewModeSw, states, names, n) < 0) return; index = getOnSwitch(&SlewModeSw); if ( ( err = setSlewMode(fd, index) < 0) ) { handleError(&SlewModeSw, err, "Setting slew mode"); return; } SlewModeSw.s = IPS_OK; IDSetSwitch(&SlewModeSw, NULL); return; } // Movement (North/South) if (!strcmp (name, MovementNSSP.name)) { if (checkPower(&MovementNSSP)) return; int last_move=-1; int current_move = -1; // -1 means all off previously last_move = getOnSwitch(&MovementNSSP); if (IUUpdateSwitches(&MovementNSSP, states, names, n) < 0) return; current_move = getOnSwitch(&MovementNSSP); // Previosuly active switch clicked again, so let's stop. if (current_move == last_move) { HaltMovement(fd, (current_move == 0) ? LX200_NORTH : LX200_SOUTH); IUResetSwitches(&MovementNSSP); MovementNSSP.s = IPS_IDLE; IDSetSwitch(&MovementNSSP, NULL); return; } #ifdef INDI_DEBUG IDLog("Current Move: %d - Previous Move: %d\n", current_move, last_move); #endif // 0 (North) or 1 (South) last_move = current_move; // Correction for LX200 Driver: North 0 - South 3 current_move = (current_move == 0) ? LX200_NORTH : LX200_SOUTH; if ( ( err = MoveTo(fd, current_move) < 0) ) { handleError(&MovementNSSP, err, "Setting motion direction"); return; } MovementNSSP.s = IPS_BUSY; IDSetSwitch(&MovementNSSP, "Moving toward %s", (current_move == LX200_NORTH) ? "North" : "South"); return; } // Movement (West/East) if (!strcmp (name, MovementWESP.name)) { if (checkPower(&MovementWESP)) return; int last_move=-1; int current_move = -1; // -1 means all off previously last_move = getOnSwitch(&MovementWESP); if (IUUpdateSwitches(&MovementWESP, states, names, n) < 0) return; current_move = getOnSwitch(&MovementWESP); // Previosuly active switch clicked again, so let's stop. if (current_move == last_move) { HaltMovement(fd, (current_move ==0) ? LX200_WEST : LX200_EAST); IUResetSwitches(&MovementWESP); MovementWESP.s = IPS_IDLE; IDSetSwitch(&MovementWESP, NULL); return; } #ifdef INDI_DEBUG IDLog("Current Move: %d - Previous Move: %d\n", current_move, last_move); #endif // 0 (West) or 1 (East) last_move = current_move; // Correction for LX200 Driver: West 1 - East 2 current_move = (current_move == 0) ? LX200_WEST : LX200_EAST; if ( ( err = MoveTo(fd, current_move) < 0) ) { handleError(&MovementWESP, err, "Setting motion direction"); return; } MovementWESP.s = IPS_BUSY; IDSetSwitch(&MovementWESP, "Moving toward %s", (current_move == LX200_WEST) ? "West" : "East"); return; } // Tracking mode if (!strcmp (name, TrackModeSw.name)) { if (checkPower(&TrackModeSw)) return; IUResetSwitches(&TrackModeSw); IUUpdateSwitches(&TrackModeSw, states, names, n); trackingMode = getOnSwitch(&TrackModeSw); if ( ( err = selectTrackingMode(fd, trackingMode) < 0) ) { handleError(&TrackModeSw, err, "Setting tracking mode."); return; } getTrackFreq(fd, &TrackFreq[0].value); TrackModeSw.s = IPS_OK; IDSetNumber(&TrackingFreq, NULL); IDSetSwitch(&TrackModeSw, NULL); return; } // Focus speed if (!strcmp (name, FocusModeSP.name)) { if (checkPower(&FocusModeSP)) return; IUResetSwitches(&FocusModeSP); IUUpdateSwitches(&FocusModeSP, states, names, n); index = getOnSwitch(&FocusModeSP); /* disable timer and motion */ if (index == 0) { IUResetSwitches(&FocusMotionSw); FocusMotionSw.s = IPS_IDLE; FocusTimerNP.s = IPS_IDLE; IDSetSwitch(&FocusMotionSw, NULL); IDSetNumber(&FocusTimerNP, NULL); } setFocuserSpeedMode(fd, index); FocusModeSP.s = IPS_OK; IDSetSwitch(&FocusModeSP, NULL); return; } } void LX200Generic::handleError(ISwitchVectorProperty *svp, int err, const char *msg) { svp->s = IPS_ALERT; /* First check to see if the telescope is connected */ if (check_lx200_connection(fd)) { /* The telescope is off locally */ PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_BUSY; IDSetSwitch(&PowerSP, "Telescope is not responding to commands, will retry in 10 seconds."); IDSetSwitch(svp, NULL); IEAddTimer(10000, retryConnection, &fd); return; } /* If the error is a time out, then the device doesn't support this property or busy*/ if (err == -2) { svp->s = IPS_ALERT; IDSetSwitch(svp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg); } else /* Changing property failed, user should retry. */ IDSetSwitch( svp , "%s failed.", msg); fault = true; } void LX200Generic::handleError(INumberVectorProperty *nvp, int err, const char *msg) { nvp->s = IPS_ALERT; /* First check to see if the telescope is connected */ if (check_lx200_connection(fd)) { /* The telescope is off locally */ PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_BUSY; IDSetSwitch(&PowerSP, "Telescope is not responding to commands, will retry in 10 seconds."); IDSetNumber(nvp, NULL); IEAddTimer(10000, retryConnection, &fd); return; } /* If the error is a time out, then the device doesn't support this property */ if (err == -2) { nvp->s = IPS_ALERT; IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg); } else /* Changing property failed, user should retry. */ IDSetNumber( nvp , "%s failed.", msg); fault = true; } void LX200Generic::handleError(ITextVectorProperty *tvp, int err, const char *msg) { tvp->s = IPS_ALERT; /* First check to see if the telescope is connected */ if (check_lx200_connection(fd)) { /* The telescope is off locally */ PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_BUSY; IDSetSwitch(&PowerSP, "Telescope is not responding to commands, will retry in 10 seconds."); IDSetText(tvp, NULL); IEAddTimer(10000, retryConnection, &fd); return; } /* If the error is a time out, then the device doesn't support this property */ if (err == -2) { tvp->s = IPS_ALERT; IDSetText(tvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg); } else /* Changing property failed, user should retry. */ IDSetText( tvp , "%s failed.", msg); fault = true; } void LX200Generic::correctFault() { fault = false; IDMessage(thisDevice, "Telescope is online."); } bool LX200Generic::isTelescopeOn(void) { if (simulation) return true; return (PowerSP.sp[0].s == ISS_ON); } static void retryConnection(void * p) { int fd = *( (int *) p); if (check_lx200_connection(fd)) { PowerSP.s = IPS_IDLE; IDSetSwitch(&PowerSP, "The connection to the telescope is lost."); return; } PowerS[0].s = ISS_ON; PowerS[1].s = ISS_OFF; PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "The connection to the telescope has been resumed."); } void LX200Generic::updateFocusTimer(void *p) { int err=0; switch (FocusTimerNP.s) { case IPS_IDLE: break; case IPS_BUSY: IDLog("Focus Timer Value is %g\n", FocusTimerN[0].value); FocusTimerN[0].value-=50; if (FocusTimerN[0].value <= 0) { IDLog("Focus Timer Expired\n"); if ( ( err = setFocuserSpeedMode(telescope->fd, 0) < 0) ) { telescope->handleError(&FocusModeSP, err, "setting focuser mode"); IDLog("Error setting focuser mode\n"); return; } FocusMotionSw.s = IPS_IDLE; FocusTimerNP.s = IPS_OK; FocusModeSP.s = IPS_OK; IUResetSwitches(&FocusMotionSw); IUResetSwitches(&FocusModeSP); FocusModeS[0].s = ISS_ON; IDSetSwitch(&FocusModeSP, NULL); IDSetSwitch(&FocusMotionSw, NULL); } IDSetNumber(&FocusTimerNP, NULL); if (FocusTimerN[0].value > 0) IEAddTimer(50, LX200Generic::updateFocusTimer, p); break; case IPS_OK: break; case IPS_ALERT: break; } } void LX200Generic::ISPoll() { double dx, dy; /*static int okCounter = 3;*/ int err=0; if (!isTelescopeOn()) return; if (simulation) { mountSim(); return; } switch (eqNum.s) { case IPS_IDLE: if ( fabs (currentRA - lastRA) > 0.01 || fabs (currentDEC - lastDEC) > 0.01) { eqNum.np[0].value = lastRA = currentRA; eqNum.np[1].value = lastDEC = currentDEC; IDSetNumber (&eqNum, NULL); } break; case IPS_BUSY: getLX200RA(fd, ¤tRA); getLX200DEC(fd, ¤tDEC); dx = targetRA - currentRA; dy = targetDEC - currentDEC; /*IDLog("targetRA is %g, currentRA is %g\n", targetRA, currentRA); IDLog("targetDEC is %g, currentDEC is %g\n*************************\n", targetDEC, currentDEC);*/ eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; // Wait until acknowledged or within threshold if ( fabs(dx) <= (slewPrecisionN[0].value/(60.0*15.0)) && fabs(dy) <= (slewPrecisionN[1].value/60.0)) { /* Don't set current to target. This might leave residual cumulative error currentRA = targetRA; currentDEC = targetDEC; */ eqNum.np[0].value = lastRA = currentRA; eqNum.np[1].value = lastDEC = currentDEC; IUResetSwitches(&OnCoordSetSw); OnCoordSetSw.s = IPS_OK; eqNum.s = IPS_OK; IDSetNumber (&eqNum, NULL); switch (currentSet) { case LX200_SLEW: OnCoordSetSw.sp[0].s = ISS_ON; IDSetSwitch (&OnCoordSetSw, "Slew is complete."); break; case LX200_TRACK: OnCoordSetSw.sp[1].s = ISS_ON; IDSetSwitch (&OnCoordSetSw, "Slew is complete. Tracking..."); break; case LX200_SYNC: break; case LX200_PARK: if (setSlewMode(fd, LX200_SLEW_GUIDE) < 0) { handleError(&eqNum, err, "Setting slew mode"); return; } IUResetSwitches(&SlewModeSw); SlewModeS[LX200_SLEW_GUIDE].s = ISS_ON; IDSetSwitch(&SlewModeSw, NULL); MoveTo(fd, LX200_EAST); IUResetSwitches(&MovementWESP); MovementWES[1].s = ISS_ON; MovementWESP.s = IPS_BUSY; IDSetSwitch(&MovementWESP, NULL); ParkSP.s = IPS_OK; IDSetSwitch (&ParkSP, "Park is complete. Turn off the telescope now."); break; } } else { eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; IDSetNumber (&eqNum, NULL); } break; case IPS_OK: if ( (err = getLX200RA(fd, ¤tRA)) < 0 || (err = getLX200DEC(fd, ¤tDEC)) < 0) { handleError(&eqNum, err, "Getting RA/DEC"); return; } if (fault) correctFault(); if ( (currentRA != lastRA) || (currentDEC != lastDEC)) { eqNum.np[0].value = lastRA = currentRA; eqNum.np[1].value = lastDEC = currentDEC; IDSetNumber (&eqNum, NULL); } break; case IPS_ALERT: break; } switch (MovementNSSP.s) { case IPS_IDLE: break; case IPS_BUSY: getLX200RA(fd, ¤tRA); getLX200DEC(fd, ¤tDEC); eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; IDSetNumber (&eqNum, NULL); break; case IPS_OK: break; case IPS_ALERT: break; } switch (MovementWESP.s) { case IPS_IDLE: break; case IPS_BUSY: getLX200RA(fd, ¤tRA); getLX200DEC(fd, ¤tDEC); eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; IDSetNumber (&eqNum, NULL); break; case IPS_OK: break; case IPS_ALERT: break; } } void LX200Generic::mountSim () { static struct timeval ltv; struct timeval tv; double dt, da, dx; int nlocked; /* update elapsed time since last poll, don't presume exactly POLLMS */ gettimeofday (&tv, NULL); if (ltv.tv_sec == 0 && ltv.tv_usec == 0) ltv = tv; dt = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec)/1e6; ltv = tv; da = SLEWRATE*dt; /* Process per current state. We check the state of EQUATORIAL_COORDS and act acoordingly */ switch (eqNum.s) { /* #1 State is idle, update telesocpe at sidereal rate */ case IPS_IDLE: /* RA moves at sidereal, Dec stands still */ currentRA += (SIDRATE*dt/15.); IDSetNumber(&eqNum, NULL); eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; break; case IPS_BUSY: /* slewing - nail it when both within one pulse @ SLEWRATE */ nlocked = 0; dx = targetRA - currentRA; if (fabs(dx) <= da) { currentRA = targetRA; nlocked++; } else if (dx > 0) currentRA += da/15.; else currentRA -= da/15.; dx = targetDEC - currentDEC; if (fabs(dx) <= da) { currentDEC = targetDEC; nlocked++; } else if (dx > 0) currentDEC += da; else currentDEC -= da; eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; if (nlocked == 2) { eqNum.s = IPS_OK; IDSetNumber(&eqNum, "Now tracking"); } else IDSetNumber(&eqNum, NULL); break; case IPS_OK: /* tracking */ eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; IDSetNumber(&eqNum, NULL); break; case IPS_ALERT: break; } } void LX200Generic::getBasicData() { int err; struct tm *timep; time_t ut; time (&ut); timep = gmtime (&ut); strftime (Time.tp[0].text, strlen(Time.tp[0].text), "%Y-%m-%dT%H:%M:%S", timep); IDLog("PC UTC time is %s\n", Time.tp[0].text); getAlignment(); checkLX200Format(fd); if ( (err = getTimeFormat(fd, &timeFormat)) < 0) IDMessage(thisDevice, "Failed to retrieve time format from device."); else { timeFormat = (timeFormat == 24) ? LX200_24 : LX200_AM; // We always do 24 hours if (timeFormat != LX200_24) toggleTimeFormat(fd); } getLX200RA(fd, &targetRA); getLX200DEC(fd, &targetDEC); eqNum.np[0].value = targetRA; eqNum.np[1].value = targetDEC; IDSetNumber (&eqNum, NULL); SiteNameT[0].text = new char[64]; if ( (err = getSiteName(fd, SiteNameT[0].text, currentSiteNum)) < 0) IDMessage(thisDevice, "Failed to get site name from device"); else IDSetText (&SiteName, NULL); if ( (err = getTrackFreq(fd, &TrackFreq[0].value)) < 0) IDMessage(thisDevice, "Failed to get tracking frequency from device."); else IDSetNumber (&TrackingFreq, NULL); /*updateLocation(); updateTime();*/ } int LX200Generic::handleCoordSet() { int err; char syncString[256]; char RAStr[32], DecStr[32]; double dx, dy; //IDLog("In Handle Coord Set()\n"); switch (currentSet) { // Slew case LX200_SLEW: lastSet = LX200_SLEW; if (eqNum.s == IPS_BUSY) { IDLog("Aboring Slew\n"); abortSlew(fd); // sleep for 100 mseconds usleep(100000); } if (!simulation) if ((err = Slew(fd))) { slewError(err); return (-1); } eqNum.s = IPS_BUSY; fs_sexa(RAStr, targetRA, 2, 3600); fs_sexa(DecStr, targetDEC, 2, 3600); IDSetNumber(&eqNum, "Slewing to JNow RA %s - DEC %s", RAStr, DecStr); IDLog("Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr); break; // Track case LX200_TRACK: //IDLog("We're in LX200_TRACK\n"); if (eqNum.s == IPS_BUSY) { IDLog("Aboring Slew\n"); abortSlew(fd); // sleep for 200 mseconds usleep(200000); } dx = fabs ( targetRA - currentRA ); dy = fabs (targetDEC - currentDEC); if (dx >= (trackingPrecisionN[0].value/(60.0*15.0)) || (dy >= trackingPrecisionN[1].value/60.0)) { /*IDLog("Exceeded Tracking threshold, will attempt to slew to the new target.\n"); IDLog("targetRA is %g, currentRA is %g\n", targetRA, currentRA); IDLog("targetDEC is %g, currentDEC is %g\n*************************\n", targetDEC, currentDEC);*/ if (!simulation) if ((err = Slew(fd))) { slewError(err); return (-1); } fs_sexa(RAStr, targetRA, 2, 3600); fs_sexa(DecStr, targetDEC, 2, 3600); eqNum.s = IPS_BUSY; IDSetNumber(&eqNum, "Slewing to JNow RA %s - DEC %s", RAStr, DecStr); IDLog("Slewing to JNow RA %s - DEC %s\n", RAStr, DecStr); } else { IDLog("Tracking called, but tracking threshold not reached yet.\n"); eqNum.s = IPS_OK; eqNum.np[0].value = currentRA; eqNum.np[1].value = currentDEC; if (lastSet != LX200_TRACK) IDSetNumber(&eqNum, "Tracking..."); else IDSetNumber(&eqNum, NULL); } lastSet = LX200_TRACK; break; // Sync case LX200_SYNC: lastSet = LX200_SYNC; eqNum.s = IPS_IDLE; if (!simulation) if ( ( err = Sync(fd, syncString) < 0) ) { IDSetNumber( &eqNum , "Synchronization failed."); return (-1); } eqNum.s = IPS_OK; IDLog("Synchronization successful %s\n", syncString); IDSetNumber(&eqNum, "Synchronization successful."); break; // PARK // Set RA to LST and DEC to 0 degrees, slew, then change to 'guide' slew after slew is complete. case LX200_PARK: if (eqNum.s == IPS_BUSY) { abortSlew(fd); // sleep for 200 mseconds usleep(200000); } if ((err = Slew(fd))) { slewError(err); return (-1); } ParkSP.s = IPS_BUSY; eqNum.s = IPS_BUSY; IDSetNumber(&eqNum, NULL); IDSetSwitch(&ParkSP, "The telescope is slewing to park position. Turn off the telescope after park is complete."); break; } return (0); } int LX200Generic::getOnSwitch(ISwitchVectorProperty *sp) { for (int i=0; i < sp->nsp ; i++) if (sp->sp[i].s == ISS_ON) return i; return -1; } int LX200Generic::checkPower(ISwitchVectorProperty *sp) { if (simulation) return 0; if (PowerSP.s != IPS_OK) { if (!strcmp(sp->label, "")) IDMessage (thisDevice, "Cannot change property %s while the telescope is offline.", sp->name); else IDMessage (thisDevice, "Cannot change property %s while the telescope is offline.", sp->label); sp->s = IPS_IDLE; IDSetSwitch(sp, NULL); return -1; } return 0; } int LX200Generic::checkPower(INumberVectorProperty *np) { if (simulation) return 0; if (PowerSP.s != IPS_OK) { if (!strcmp(np->label, "")) IDMessage (thisDevice, "Cannot change property %s while the telescope is offline.", np->name); else IDMessage (thisDevice, "Cannot change property %s while the telescope is offline.", np->label); np->s = IPS_IDLE; IDSetNumber(np, NULL); return -1; } return 0; } int LX200Generic::checkPower(ITextVectorProperty *tp) { if (simulation) return 0; if (PowerSP.s != IPS_OK) { if (!strcmp(tp->label, "")) IDMessage (thisDevice, "Cannot change property %s while the telescope is offline.", tp->name); else IDMessage (thisDevice, "Cannot change property %s while the telescope is offline.", tp->label); tp->s = IPS_IDLE; IDSetText(tp, NULL); return -1; } return 0; } void LX200Generic::connectTelescope() { switch (PowerSP.sp[0].s) { case ISS_ON: if (simulation) { PowerSP.s = IPS_OK; IDSetSwitch (&PowerSP, "Simulated telescope is online."); //updateTime(); return; } if (tty_connect(Port.tp[0].text, 9600, 8, 0, 1, &fd) != TTY_OK) { PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch (&PowerSP, "Error connecting to port %s. Make sure you have BOTH write and read permission to your port.\n", Port.tp[0].text); return; } if (check_lx200_connection(fd)) { PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch (&PowerSP, "Error connecting to Telescope. Telescope is offline."); return; } #ifdef INDI_DEBUG IDLog("Telescope test successfful.\n"); #endif *((int *) UTCOffsetN[0].aux0) = 0; PowerSP.s = IPS_OK; IDSetSwitch (&PowerSP, "Telescope is online. Retrieving basic data..."); getBasicData(); break; case ISS_OFF: PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_IDLE; IDSetSwitch (&PowerSP, "Telescope is offline."); IDLog("Telescope is offline."); tty_disconnect(fd); break; } } void LX200Generic::slewError(int slewCode) { OnCoordSetSw.s = IPS_IDLE; ParkSP.s = IPS_IDLE; IDSetSwitch(&ParkSP, NULL); if (slewCode == 1) IDSetSwitch (&OnCoordSetSw, "Object below horizon."); else if (slewCode == 2) IDSetSwitch (&OnCoordSetSw, "Object below the minimum elevation limit."); else IDSetSwitch (&OnCoordSetSw, "Slew failed."); } void LX200Generic::getAlignment() { if (PowerSP.s != IPS_OK) return; signed char align = ACK(fd); if (align < 0) { IDSetSwitch (&AlignmentSw, "Failed to get telescope alignment."); return; } AlignmentS[0].s = ISS_OFF; AlignmentS[1].s = ISS_OFF; AlignmentS[2].s = ISS_OFF; switch (align) { case 'P': AlignmentS[0].s = ISS_ON; break; case 'A': AlignmentS[1].s = ISS_ON; break; case 'L': AlignmentS[2].s = ISS_ON; break; } AlignmentSw.s = IPS_OK; IDSetSwitch (&AlignmentSw, NULL); IDLog("ACK success %c\n", align); } void LX200Generic::enableSimulation(bool enable) { simulation = enable; if (simulation) IDLog("Warning: Simulation is activated.\n"); else IDLog("Simulation is disabled.\n"); } void LX200Generic::updateTime() { char cdate[32]; double ctime; int h, m, s, lx200_utc_offset=0; int day, month, year, result; struct tm ltm; struct tm utm; time_t time_epoch; if (simulation) { sprintf(UTC[0].text, "%d-%02d-%02dT%02d:%02d:%02d", 1979, 6, 25, 3, 30, 30); IDLog("Telescope ISO date and time: %s\n", UTC[0].text); IDSetText(&Time, NULL); return; } getUTCOffset(fd, &lx200_utc_offset); // LX200 UTC Offset is defined at the number of hours added to LOCAL TIME to get UTC. This is contrary to the normal definition. UTCOffsetN[0].value = lx200_utc_offset*-1; // We got a valid value for UTCOffset now *((int *) UTCOffsetN[0].aux0) = 1; #ifdef INDI_DEBUG IDLog("Telescope UTC Offset: %g\n", UTCOffsetN[0].value); #endif getLocalTime24(fd, &ctime); getSexComponents(ctime, &h, &m, &s); if ( (result = getSDTime(fd, &STime[0].value)) < 0) IDMessage(thisDevice, "Failed to retrieve siderial time from device."); getCalenderDate(fd, cdate); result = sscanf(cdate, "%d/%d/%d", &year, &month, &day); if (result != 3) return; // Let's fill in the local time ltm.tm_sec = s; ltm.tm_min = m; ltm.tm_hour = h; ltm.tm_mday = day; ltm.tm_mon = month - 1; ltm.tm_year = year - 1900; // Get time epoch time_epoch = mktime(<m); // Convert to UTC time_epoch -= (int) (UTCOffsetN[0].value * 60.0 * 60.0); // Get UTC (we're using localtime_r, but since we shifted time_epoch above by UTCOffset, we should be getting the real UTC time) localtime_r(&time_epoch, &utm); /* Format it into ISO 8601 */ strftime(cdate, 32, "%Y-%m-%dT%H:%M:%S", &utm); IUSaveText(&UTC[0], cdate); #ifdef INDI_DEBUG IDLog("Telescope Local Time: %02d:%02d:%02d\n", h, m , s); IDLog("Telescope SD Time is: %g\n", STime[0].value); IDLog("Telescope UTC Time: %s\n", UTC[0].text); #endif // Let's send everything to the client IDSetText(&Time, NULL); IDSetNumber(&SDTime, NULL); IDSetNumber(&UTCOffsetNP, NULL); } void LX200Generic::updateLocation() { int dd = 0, mm = 0, err = 0; if ( (err = getSiteLatitude(fd, &dd, &mm)) < 0) IDMessage(thisDevice, "Failed to get site latitude from device."); else { if (dd > 0) geoNum.np[0].value = dd + mm/60.0; else geoNum.np[0].value = dd - mm/60.0; IDLog("Autostar Latitude: %d:%d\n", dd, mm); IDLog("INDI Latitude: %g\n", geoNum.np[0].value); } if ( (err = getSiteLongitude(fd, &dd, &mm)) < 0) IDMessage(thisDevice, "Failed to get site longitude from device."); else { if (dd > 0) geoNum.np[1].value = 360.0 - (dd + mm/60.0); else geoNum.np[1].value = (dd - mm/60.0) * -1.0; IDLog("Autostar Longitude: %d:%d\n", dd, mm); IDLog("INDI Longitude: %g\n", geoNum.np[1].value); } IDSetNumber (&geoNum, NULL); } indi-0.5/src/apogee/0000755000175000017500000000000011017761434012144 5ustar jrjrindi-0.5/src/apogee/ApnCamTable.cpp0000644000175000017500000001103410610474646014762 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnCamTable.cpp // #include #include "ApnCamTable.h" #define ALTA_MODEL_PREFIX "Alta-" void ApnCamModelLookup( unsigned short CamId, unsigned short Interface, char *szCamModel ) { char szModelNumber[20]; bool Error; Error = false; switch( CamId ) { case APN_ALTA_KAF0401E_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAF0401E_CAM_SZ ); break; case APN_ALTA_KAF1602E_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAF1602E_CAM_SZ ); break; case APN_ALTA_KAF0261E_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAF0261E_CAM_SZ ); break; case APN_ALTA_KAF1301E_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAF1301E_CAM_SZ ); break; case APN_ALTA_KAF1401E_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAF1401E_CAM_SZ ); break; case APN_ALTA_KAF1001E_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAF1001E_CAM_SZ ); break; case APN_ALTA_KAF3200E_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAF3200E_CAM_SZ ); break; case APN_ALTA_KAF4202_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAF4202_CAM_SZ ); break; case APN_ALTA_KAF6303E_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAF6303E_CAM_SZ ); break; case APN_ALTA_KAF16801E_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAF16801E_CAM_SZ ); break; case APN_ALTA_CCD4710LS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD4710LS_CAM_SZ ); break; case APN_ALTA_CCD4710HS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD4710HS_CAM_SZ ); break; case APN_ALTA_TH7899_CAM_ID: strcpy( szModelNumber, APN_ALTA_TH7899_CAM_SZ ); break; case APN_ALTA_CCD4240LS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD4240LS_CAM_SZ ); break; case APN_ALTA_CCD4240HS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD4240HS_CAM_SZ ); break; case APN_ALTA_CCD5710LS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD5710LS_CAM_SZ ); break; case APN_ALTA_CCD5710HS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD5710HS_CAM_SZ ); break; case APN_ALTA_CCD3011LS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD3011LS_CAM_SZ ); break; case APN_ALTA_CCD3011HS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD3011HS_CAM_SZ ); break; case APN_ALTA_CCD5520LS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD5520LS_CAM_SZ ); break; case APN_ALTA_CCD5520HS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD5520HS_CAM_SZ ); break; case APN_ALTA_CCD4720LS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD4720LS_CAM_SZ ); break; case APN_ALTA_CCD4720HS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD4720HS_CAM_SZ ); break; case APN_ALTA_CCD7700LS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD7700LS_CAM_SZ ); break; case APN_ALTA_CCD7700HS_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD7700HS_CAM_SZ ); break; case APN_ALTA_KAI2001M_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAI2001M_CAM_SZ ); break; case APN_ALTA_KAI2001MC_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAI2001MC_CAM_SZ ); break; case APN_ALTA_KAI4020_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAI4020_CAM_SZ ); break; case APN_ALTA_KAI11000_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAI11000_CAM_SZ ); break; case APN_ALTA_KAI11000C_CAM_ID: strcpy( szModelNumber, APN_ALTA_KAI11000C_CAM_SZ ); break; case APN_ALTA_CCD4710LS2_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD4710LS2_CAM_SZ ); break; case APN_ALTA_CCD4710LS3_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD4710LS3_CAM_SZ ); break; case APN_ALTA_CCD4710LS4_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD4710LS4_CAM_SZ ); break; case APN_ALTA_CCD4710LS5_CAM_ID: strcpy( szModelNumber, APN_ALTA_CCD4710LS5_CAM_SZ ); break; default: Error = true; break; } if ( Error ) { strcpy( szCamModel, "Unknown" ); } else { strcpy( szCamModel, ALTA_MODEL_PREFIX ); if ( Interface == 0 ) // Network Interface strcat( szCamModel, "E" ); if ( Interface == 1 ) // USB 2.0 Interface strcat( szCamModel, "U" ); strcat( szCamModel, szModelNumber ); } } indi-0.5/src/apogee/ApnCamera_Linux.cpp0000644000175000017500000001054510610474646015667 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnCamera.cpp: extras from the CCameraIO class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ApnCamera.h" #include "ApnCamTable.h" //#include "tcl.h" //#include "ccd.h" // Determine if camera is present // True if camera is present, false otherwise. bool CApnCamera::read_Present() { // OutputDebugString( "read_Present()" ); USHORT ApStatus; USHORT DatumA; USHORT DatumB; char szMsg[80]; DatumA = 0x0; DatumB = 0x0; ApStatus = 0; Write( FPGA_REG_SCRATCH, 0x8086 ); Read( FPGA_REG_SCRATCH, DatumA ); Write( FPGA_REG_SCRATCH, 0x1F2F ); Read( FPGA_REG_SCRATCH, DatumB ); if ( (DatumA != 0x8086) || (DatumB != 0x1F2F) ) { // OutputDebugString( "read_Present FAILED." ); sprintf( szMsg, "read_Present FAILED. DatumA: 0x%X DatumB: 0x%X", DatumA, DatumB ); // OutputDebugString( szMsg ); return false; } // OutputDebugString( "read_Present SUCCESS" ); return true; } bool CApnCamera::sensorInfo() { strcpy(m_Sensor,m_ApnSensorInfo->m_Sensor); strcpy(m_CameraModel,m_ApnSensorInfo->m_CameraModel); m_CameraId = m_ApnSensorInfo->m_CameraId; m_InterlineCCD = m_ApnSensorInfo->m_InterlineCCD; m_SupportsSerialA = m_ApnSensorInfo->m_SupportsSerialA; m_SupportsSerialB = m_ApnSensorInfo->m_SupportsSerialB; m_SensorTypeCCD =m_ApnSensorInfo->m_SensorTypeCCD; m_TotalColumns =m_ApnSensorInfo->m_TotalColumns; m_ImagingColumns= m_ApnSensorInfo->m_ImagingColumns; m_ClampColumns= m_ApnSensorInfo->m_ClampColumns; m_PreRoiSkipColumns =m_ApnSensorInfo->m_PreRoiSkipColumns; m_PostRoiSkipColumns= m_ApnSensorInfo->m_PostRoiSkipColumns; m_OverscanColumns =m_ApnSensorInfo->m_OverscanColumns; m_TotalRows =m_ApnSensorInfo->m_TotalRows; m_ImagingRows =m_ApnSensorInfo->m_ImagingRows; m_UnderscanRows= m_ApnSensorInfo->m_UnderscanRows; m_OverscanRows =m_ApnSensorInfo->m_OverscanRows; m_VFlushBinning =m_ApnSensorInfo->m_VFlushBinning; m_HFlushDisable =m_ApnSensorInfo->m_HFlushDisable; m_ShutterCloseDelay= m_ApnSensorInfo->m_ShutterCloseDelay; m_PixelSizeX = m_ApnSensorInfo->m_PixelSizeX; m_PixelSizeY = m_ApnSensorInfo->m_PixelSizeY; m_Color = m_ApnSensorInfo->m_Color; // m_ReportedGainTwelveBit = m_ApnSensorInfo->m_ReportedGainTwelveBit; m_ReportedGainSixteenBit= m_ApnSensorInfo->m_ReportedGainSixteenBit; m_MinSuggestedExpTime = m_ApnSensorInfo->m_MinSuggestedExpTime; // m_TempRegRate =m_ApnSensorInfo->m_TempRegRate; m_TempRampRateOne =m_ApnSensorInfo->m_TempRampRateOne; m_TempRampRateTwo =m_ApnSensorInfo->m_TempRampRateTwo; m_DefaultGainTwelveBit =m_ApnSensorInfo->m_DefaultGainTwelveBit; m_DefaultOffsetTwelveBit= m_ApnSensorInfo->m_DefaultOffsetTwelveBit; m_DefaultRVoltage =m_ApnSensorInfo->m_DefaultRVoltage; return true; } #if 0 bool CApnCamera::BufferImage(char *bufferName ) { unsigned short *pImageData; bool status; short cols,rows,hbin,vbin; unsigned short xSize, ySize; unsigned long count; cols = m_pvtExposurePixelsH; rows = m_pvtExposurePixelsV; /* ALTA code has already applied binning calculations*/ hbin = 1; vbin = 1; pImageData = (unsigned short *)CCD_locate_buffer(bufferName, 2 , cols, rows, hbin, vbin ); if (pImageData == NULL) { return 0; } status = GetImageData(pImageData, xSize, ySize, count); return status; } bool CApnCamera::BufferDriftScan(char *bufferName, int delay, int rowCount, int nblock , int npipe) { unsigned short *pImageData, *ptr; bool status; int irow; short cols,rows,hbin,vbin; cols = m_pvtExposurePixelsH; rows = rowCount; hbin = m_RoiBinningH; vbin = 1; return 1; } #endif indi-0.5/src/apogee/ApnCamera.cpp0000644000175000017500000013223110610474646014505 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnCamera.cpp: implementation of the CApnCamera class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ApnCamera.h" #include "ApnCamTable.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CApnCamera::CApnCamera() { m_ApnSensorInfo = NULL; } CApnCamera::~CApnCamera() { if ( m_ApnSensorInfo != NULL ) { delete m_ApnSensorInfo; m_ApnSensorInfo = NULL; } CloseDriver(); } bool CApnCamera::Expose( double Duration, bool Light ) { ULONG ExpTime; unsigned short BitsPerPixel(0); unsigned short UnbinnedRoiX; unsigned short UnbinnedRoiY; unsigned short PreRoiSkip, PostRoiSkip; unsigned short PreRoiRows, PostRoiRows; unsigned short PreRoiVBinning, PostRoiVBinning; unsigned short RoiRegBuffer[12]; unsigned short RoiRegData[12]; unsigned short TotalHPixels; unsigned short TotalVPixels; while ( read_ImagingStatus() != Apn_Status_Flushing ) { Sleep( 20 ); } // Validate the "Duration" parameter if ( Duration < APN_EXPOSURE_TIME_MIN ) Duration = APN_EXPOSURE_TIME_MIN; // Validate the ROI params UnbinnedRoiX = m_RoiPixelsH * m_RoiBinningH; PreRoiSkip = m_RoiStartX; PostRoiSkip = m_ApnSensorInfo->m_TotalColumns - m_ApnSensorInfo->m_ClampColumns - PreRoiSkip - UnbinnedRoiX; TotalHPixels = UnbinnedRoiX + PreRoiSkip + PostRoiSkip + m_ApnSensorInfo->m_ClampColumns; if ( TotalHPixels != m_ApnSensorInfo->m_TotalColumns ) return false; UnbinnedRoiY = m_RoiPixelsV * m_RoiBinningV; PreRoiRows = m_ApnSensorInfo->m_UnderscanRows + m_RoiStartY; PostRoiRows = m_ApnSensorInfo->m_TotalRows - PreRoiRows - UnbinnedRoiY; TotalVPixels = UnbinnedRoiY + PreRoiRows + PostRoiRows; if ( TotalVPixels != m_ApnSensorInfo->m_TotalRows ) return false; // Calculate the exposure time to program to the camera ExpTime = ((unsigned long)(Duration / APN_TIMER_RESOLUTION)) + APN_TIMER_OFFSET_COUNT; Write( FPGA_REG_TIMER_LOWER, (unsigned short)(ExpTime & 0xFFFF)); ExpTime = ExpTime >> 16; Write( FPGA_REG_TIMER_UPPER, (unsigned short)(ExpTime & 0xFFFF)); m_pvtExposurePixelsV = m_RoiPixelsV; m_pvtExposurePixelsH = m_RoiPixelsH; if ( m_DataBits == Apn_Resolution_SixteenBit ) { BitsPerPixel = 16; } else if ( m_DataBits == Apn_Resolution_TwelveBit ) { BitsPerPixel = 12; } if ( PreStartExpose( BitsPerPixel ) != 0 ) { return false; } // Calculate the vertical parameters PreRoiVBinning = m_ApnSensorInfo->m_RowOffsetBinning; PostRoiVBinning = 1; // For interline CCDs, set "Fast Dump" mode if the particular array is NOT digitized if ( m_ApnSensorInfo->m_InterlineCCD ) { // use the fast dump feature to get rid of the data quickly. // one row, binning to the original row count // note that we only are not digitized in arrays 1 and 3 PreRoiVBinning = PreRoiRows; PostRoiVBinning = PostRoiRows; PreRoiVBinning |= FPGA_BIT_ARRAY_FASTDUMP; PostRoiVBinning |= FPGA_BIT_ARRAY_FASTDUMP; PreRoiRows = 1; PostRoiRows = 1; } // Set up the geometry for a full frame device if ( m_ApnSensorInfo->m_EnableSingleRowOffset ) { PreRoiVBinning += PreRoiRows; PostRoiVBinning = PostRoiRows; PreRoiVBinning |= FPGA_BIT_ARRAY_FASTDUMP; PostRoiVBinning |= FPGA_BIT_ARRAY_FASTDUMP; PreRoiRows = 1; PostRoiRows = 1; } // Issue the reset RoiRegBuffer[0] = FPGA_REG_COMMAND_B; RoiRegData[0] = FPGA_BIT_CMD_RESET; // Program the horizontal settings RoiRegBuffer[1] = FPGA_REG_PREROI_SKIP_COUNT; RoiRegData[1] = PreRoiSkip; RoiRegBuffer[2] = FPGA_REG_ROI_COUNT; // Number of ROI pixels. Adjust the 12bit operation here to account for an extra // 10 pixel shift as a result of the A/D conversion. if ( m_DataBits == Apn_Resolution_SixteenBit ) { RoiRegData[2] = m_pvtExposurePixelsH + 1; } else if ( m_DataBits == Apn_Resolution_TwelveBit ) { RoiRegData[2] = m_pvtExposurePixelsH + 10; } RoiRegBuffer[3] = FPGA_REG_POSTROI_SKIP_COUNT; RoiRegData[3] = PostRoiSkip; // Program the vertical settings RoiRegBuffer[4] = FPGA_REG_A1_ROW_COUNT; RoiRegData[4] = PreRoiRows; RoiRegBuffer[5] = FPGA_REG_A1_VBINNING; RoiRegData[5] = PreRoiVBinning; RoiRegBuffer[6] = FPGA_REG_A2_ROW_COUNT; RoiRegData[6] = m_RoiPixelsV; RoiRegBuffer[7] = FPGA_REG_A2_VBINNING; RoiRegData[7] = (m_RoiBinningV | FPGA_BIT_ARRAY_DIGITIZE); RoiRegBuffer[8] = FPGA_REG_A3_ROW_COUNT; RoiRegData[8] = PostRoiRows; RoiRegBuffer[9] = FPGA_REG_A3_VBINNING; RoiRegData[9] = PostRoiVBinning; // Issue the reset RoiRegBuffer[10] = FPGA_REG_COMMAND_B; RoiRegData[10] = FPGA_BIT_CMD_RESET; switch ( m_pvtCameraMode ) { case Apn_CameraMode_Normal: if ( Light ) { RoiRegBuffer[11] = FPGA_REG_COMMAND_A; RoiRegData[11] = FPGA_BIT_CMD_EXPOSE; } else { RoiRegBuffer[11] = FPGA_REG_COMMAND_A; RoiRegData[11] = FPGA_BIT_CMD_DARK; } break; case Apn_CameraMode_TDI: RoiRegBuffer[11] = FPGA_REG_COMMAND_A; RoiRegData[11] = FPGA_BIT_CMD_TDI; break; case Apn_CameraMode_Test: if ( Light ) { RoiRegBuffer[11] = FPGA_REG_COMMAND_A; RoiRegData[11] = FPGA_BIT_CMD_EXPOSE; } else { RoiRegBuffer[11] = FPGA_REG_COMMAND_A; RoiRegData[11] = FPGA_BIT_CMD_DARK; } break; case Apn_CameraMode_ExternalTrigger: RoiRegBuffer[11] = FPGA_REG_COMMAND_A; RoiRegData[11] = FPGA_BIT_CMD_TRIGGER_EXPOSE; break; case Apn_CameraMode_ExternalShutter: break; } // Send the instruction sequence to the camera WriteMultiMRMD( RoiRegBuffer, RoiRegData, 12 ); m_pvtImageInProgress = true; m_pvtImageReady = false; return true; } bool CApnCamera::ResetSystem() { // Reset the camera engine Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); // Start flushing Write( FPGA_REG_COMMAND_A, FPGA_BIT_CMD_FLUSH ); return true; } bool CApnCamera::PauseTimer( bool PauseState ) { unsigned short RegVal; bool CurrentState; Read( FPGA_REG_OP_A, RegVal ); CurrentState = ( RegVal & FPGA_BIT_PAUSE_TIMER ) == FPGA_BIT_PAUSE_TIMER; if ( CurrentState != PauseState ) { if ( PauseState ) { RegVal |= FPGA_BIT_PAUSE_TIMER; } else { RegVal &= ~FPGA_BIT_PAUSE_TIMER; } Write ( FPGA_REG_OP_A, RegVal ); } return true; } bool CApnCamera::StopExposure( bool DigitizeData ) { if ( m_pvtImageInProgress ) { Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_END_EXPOSURE ); if ( PostStopExposure( DigitizeData ) != 0 ) { return false; } } return true; } unsigned short CApnCamera::GetExposurePixelsH() { return m_pvtExposurePixelsH; } unsigned short CApnCamera::GetExposurePixelsV() { return m_pvtExposurePixelsV; } double CApnCamera::read_InputVoltage() { UpdateGeneralStatus(); return m_pvtInputVoltage; } long CApnCamera::read_AvailableMemory() { long AvailableMemory(0); switch( m_CameraInterface ) { case Apn_Interface_NET: AvailableMemory = 28 * 1024; break; case Apn_Interface_USB: AvailableMemory = 32 * 1024; break; default: break; } return AvailableMemory; } unsigned short CApnCamera::read_FirmwareVersion() { unsigned short FirmwareVersion; Read( FPGA_REG_FIRMWARE_REV, FirmwareVersion ); return FirmwareVersion; } bool CApnCamera::read_ShutterState() { UpdateGeneralStatus(); return m_pvtShutterState; } bool CApnCamera::read_DisableShutter() { unsigned short RegVal; Read( FPGA_REG_OP_A, RegVal ); return ( (RegVal & FPGA_BIT_DISABLE_SHUTTER) != 0 ); } void CApnCamera::write_DisableShutter( bool DisableShutter ) { unsigned short RegVal; Read( FPGA_REG_OP_A, RegVal ); if ( DisableShutter ) RegVal |= FPGA_BIT_DISABLE_SHUTTER; else RegVal &= ~FPGA_BIT_DISABLE_SHUTTER; Write( FPGA_REG_OP_A, RegVal ); } bool CApnCamera::read_ForceShutterOpen() { unsigned short RegVal; Read( FPGA_REG_OP_A, RegVal ); return ( (RegVal & FPGA_BIT_FORCE_SHUTTER) != 0 ); } void CApnCamera::write_ForceShutterOpen( bool ForceShutterOpen ) { unsigned short RegVal; Read( FPGA_REG_OP_A, RegVal ); if ( ForceShutterOpen ) RegVal |= FPGA_BIT_FORCE_SHUTTER; else RegVal &= ~FPGA_BIT_FORCE_SHUTTER; Write( FPGA_REG_OP_A, RegVal ); } bool CApnCamera::read_ShutterAmpControl() { unsigned short RegVal; Read( FPGA_REG_OP_A, RegVal ); return ( (RegVal & FPGA_BIT_SHUTTER_AMP_CONTROL ) != 0 ); } void CApnCamera::write_ShutterAmpControl( bool ShutterAmpControl ) { unsigned short RegVal; Read( FPGA_REG_OP_A, RegVal ); if ( ShutterAmpControl ) RegVal |= FPGA_BIT_SHUTTER_AMP_CONTROL; else RegVal &= ~FPGA_BIT_SHUTTER_AMP_CONTROL; Write( FPGA_REG_OP_A, RegVal ); } bool CApnCamera::read_ExternalIoReadout() { unsigned short RegVal; Read( FPGA_REG_OP_A, RegVal ); return ( (RegVal & FPGA_BIT_SHUTTER_MODE) != 0 ); } void CApnCamera::write_ExternalIoReadout( bool ExternalIoReadout ) { unsigned short RegVal; Read( FPGA_REG_OP_A, RegVal ); if ( ExternalIoReadout ) RegVal |= FPGA_BIT_SHUTTER_MODE; else RegVal &= ~FPGA_BIT_SHUTTER_MODE; Write( FPGA_REG_OP_A, RegVal ); } bool CApnCamera::read_FastSequence() { if ( m_ApnSensorInfo->m_InterlineCCD == false ) return false; unsigned short RegVal; Read( FPGA_REG_OP_A, RegVal ); return ( (RegVal & FPGA_BIT_RATIO) != 0 ); } void CApnCamera::write_FastSequence( bool FastSequence ) { if ( m_ApnSensorInfo->m_InterlineCCD == false ) return; unsigned short RegVal; Read( FPGA_REG_OP_A, RegVal ); if ( FastSequence ) { RegVal |= FPGA_BIT_RATIO; Write( FPGA_REG_SHUTTER_CLOSE_DELAY, 0x0 ); } else { RegVal &= ~FPGA_BIT_RATIO; } Write( FPGA_REG_OP_A, RegVal ); } Apn_NetworkMode CApnCamera::read_NetworkTransferMode() { return m_pvtNetworkTransferMode; } void CApnCamera::write_NetworkTransferMode( Apn_NetworkMode TransferMode ) { SetNetworkTransferMode( TransferMode ); m_pvtNetworkTransferMode = TransferMode; } Apn_CameraMode CApnCamera::read_CameraMode() { return m_pvtCameraMode; } void CApnCamera::write_CameraMode( Apn_CameraMode CameraMode ) { unsigned short RegVal; // If our state isn't going to change, do nothing if ( m_pvtCameraMode == CameraMode ) return; // If we didn't return already, then if we know our state is going to // change. If we're in test mode, clear the appropriate FPGA bit(s). switch( m_pvtCameraMode ) { case Apn_CameraMode_Normal: break; case Apn_CameraMode_TDI: break; case Apn_CameraMode_Test: Read( FPGA_REG_OP_B, RegVal ); RegVal &= ~FPGA_BIT_AD_SIMULATION; Write( FPGA_REG_OP_B, RegVal ); break; case Apn_CameraMode_ExternalTrigger: break; case Apn_CameraMode_ExternalShutter: Read( FPGA_REG_OP_A, RegVal ); RegVal &= ~FPGA_BIT_SHUTTER_SOURCE; Write( FPGA_REG_OP_A, RegVal ); break; } switch ( CameraMode ) { case Apn_CameraMode_Normal: break; case Apn_CameraMode_TDI: break; case Apn_CameraMode_Test: Read( FPGA_REG_OP_B, RegVal ); RegVal |= FPGA_BIT_AD_SIMULATION; Write( FPGA_REG_OP_B, RegVal ); break; case Apn_CameraMode_ExternalTrigger: Read( FPGA_REG_IO_PORT_ASSIGNMENT, RegVal ); RegVal |= 0x01; Write( FPGA_REG_IO_PORT_ASSIGNMENT, RegVal ); break; case Apn_CameraMode_ExternalShutter: Read( FPGA_REG_OP_A, RegVal ); RegVal |= FPGA_BIT_SHUTTER_SOURCE; Write( FPGA_REG_OP_A, RegVal ); break; } m_pvtCameraMode = CameraMode; } void CApnCamera::write_DataBits( Apn_Resolution BitResolution ) { unsigned short RegVal; if ( m_CameraInterface == Apn_Interface_NET ) { // The network interface is 16bpp only. Changing the resolution // for network cameras has no effect. return; } if ( m_DataBits != BitResolution ) { // Reset the camera Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); // Change bit setting after the reset Read( FPGA_REG_OP_A, RegVal ); if ( BitResolution == Apn_Resolution_TwelveBit ) RegVal |= FPGA_BIT_DIGITIZATION_RES; if ( BitResolution == Apn_Resolution_SixteenBit ) RegVal &= ~FPGA_BIT_DIGITIZATION_RES; Write( FPGA_REG_OP_A, RegVal ); m_DataBits = BitResolution; LoadClampPattern(); LoadSkipPattern(); LoadRoiPattern( m_RoiBinningH ); // Reset the camera Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); // Start flushing Write( FPGA_REG_COMMAND_A, FPGA_BIT_CMD_FLUSH ); } } Apn_Status CApnCamera::read_ImagingStatus() { bool Exposing, Active, Done, Flushing, WaitOnTrigger; bool DataHalted, RamError; UpdateGeneralStatus(); // Update the ImagingStatus Exposing = false; Active = false; Done = false; Flushing = false; WaitOnTrigger = false; DataHalted = false; RamError = false; if ( (m_pvtStatusReg & FPGA_BIT_STATUS_IMAGING_ACTIVE) != 0 ) Active = true; if ( (m_pvtStatusReg & FPGA_BIT_STATUS_IMAGE_EXPOSING) != 0 ) Exposing = true; if ( (m_pvtStatusReg & FPGA_BIT_STATUS_IMAGE_DONE) != 0 ) Done = true; if ( (m_pvtStatusReg & FPGA_BIT_STATUS_FLUSHING) != 0 ) Flushing = true; if ( (m_pvtStatusReg & FPGA_BIT_STATUS_WAITING_TRIGGER) != 0 ) WaitOnTrigger = true; if ( (m_pvtStatusReg & FPGA_BIT_STATUS_DATA_HALTED) != 0 ) DataHalted = true; if ( (m_pvtStatusReg & FPGA_BIT_STATUS_PATTERN_ERROR) != 0 ) RamError = true; if ( RamError ) { m_pvtImagingStatus = Apn_Status_PatternError; } else { if ( DataHalted ) { m_pvtImagingStatus = Apn_Status_DataError; } else { if ( WaitOnTrigger ) { m_pvtImagingStatus = Apn_Status_WaitingOnTrigger; } else { if ( Done && m_pvtImageInProgress ) { m_pvtImageReady = true; m_pvtImagingStatus = Apn_Status_ImageReady; } else { if ( Active ) { if ( Exposing ) m_pvtImagingStatus = Apn_Status_Exposing; else m_pvtImagingStatus = Apn_Status_ImagingActive; } else { if ( Flushing ) m_pvtImagingStatus = Apn_Status_Flushing; else m_pvtImagingStatus = Apn_Status_Idle; } } } } } /* switch( m_pvtImagingStatus ) { case Apn_Status_DataError: OutputDebugString( "ImagingStatus: Apn_Status_DataError" ); break; case Apn_Status_PatternError: OutputDebugString( "ImagingStatus: Apn_Status_PatternError" ); break; case Apn_Status_Idle: OutputDebugString( "ImagingStatus: Apn_Status_Idle" ); break; case Apn_Status_Exposing: OutputDebugString( "ImagingStatus: Apn_Status_Exposing" ); break; case Apn_Status_ImagingActive: OutputDebugString( "ImagingStatus: Apn_Status_ImagingActive" ); break; case Apn_Status_ImageReady: OutputDebugString( "ImagingStatus: Apn_Status_ImageReady" ); break; case Apn_Status_Flushing: OutputDebugString( "ImagingStatus: Apn_Status_Flushing" ); break; case Apn_Status_WaitingOnTrigger: OutputDebugString( "ImagingStatus: Apn_Status_WaitingOnTrigger" ); break; default: OutputDebugString( "ImagingStatus: UNDEFINED!!" ); break; } */ return m_pvtImagingStatus; } Apn_LedMode CApnCamera::read_LedMode() { return m_pvtLedMode; } void CApnCamera::write_LedMode( Apn_LedMode LedMode ) { unsigned short RegVal; Read( FPGA_REG_OP_A, RegVal ); switch ( LedMode ) { case Apn_LedMode_DisableAll: RegVal |= FPGA_BIT_LED_DISABLE; break; case Apn_LedMode_DisableWhileExpose: RegVal &= ~FPGA_BIT_LED_DISABLE; RegVal |= FPGA_BIT_LED_EXPOSE_DISABLE; break; case Apn_LedMode_EnableAll: RegVal &= ~FPGA_BIT_LED_DISABLE; RegVal &= ~FPGA_BIT_LED_EXPOSE_DISABLE; break; } m_pvtLedMode = LedMode; Write( FPGA_REG_OP_A, RegVal ); } Apn_LedState CApnCamera::read_LedState( unsigned short LedId ) { Apn_LedState RetVal(0); if ( LedId == 0 ) // LED A RetVal = m_pvtLedStateA; if ( LedId == 1 ) // LED B RetVal = m_pvtLedStateB; return RetVal; } void CApnCamera::write_LedState( unsigned short LedId, Apn_LedState LedState ) { unsigned short RegVal; RegVal = 0x0; if ( LedId == 0 ) // LED A { RegVal = (m_pvtLedStateB << 4); // keep the current settings for LED B RegVal |= LedState; // program new settings m_pvtLedStateA = LedState; } else if ( LedId == 1 ) // LED B { RegVal = m_pvtLedStateA; // keep the current settings for LED A RegVal |= (LedState << 4); // program new settings m_pvtLedStateB = LedState; } Write( FPGA_REG_LED_SELECT, RegVal ); } bool CApnCamera::read_CoolerEnable() { return m_pvtCoolerEnable; } void CApnCamera::write_CoolerEnable( bool CoolerEnable ) { if ( CoolerEnable ) { Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RAMP_TO_SETPOINT ); } else { Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RAMP_TO_AMBIENT ); } m_pvtCoolerEnable = CoolerEnable; } Apn_CoolerStatus CApnCamera::read_CoolerStatus() { bool CoolerAtTemp; bool CoolerActive; bool CoolerTempRevised; UpdateGeneralStatus(); // Update CoolerStatus CoolerActive = false; CoolerAtTemp = false; CoolerTempRevised = false; if ( (m_pvtStatusReg & FPGA_BIT_STATUS_TEMP_AT_TEMP) != 0 ) CoolerAtTemp = true; if ( (m_pvtStatusReg & FPGA_BIT_STATUS_TEMP_ACTIVE) != 0 ) CoolerActive = true; if ( (m_pvtStatusReg & FPGA_BIT_STATUS_TEMP_REVISION) != 0 ) CoolerTempRevised = true; // Now derive our cooler state if ( !CoolerActive ) { m_pvtCoolerStatus = Apn_CoolerStatus_Off; } else { if ( CoolerTempRevised ) { m_pvtCoolerStatus = Apn_CoolerStatus_Revision; } else { if ( CoolerAtTemp ) m_pvtCoolerStatus = Apn_CoolerStatus_AtSetPoint; else m_pvtCoolerStatus = Apn_CoolerStatus_RampingToSetPoint; } } return m_pvtCoolerStatus; } double CApnCamera::read_CoolerSetPoint() { unsigned short RegVal; double TempVal; Read( FPGA_REG_TEMP_DESIRED, RegVal ); RegVal &= 0x0FFF; TempVal = ( RegVal - APN_TEMP_SETPOINT_ZERO_POINT ) * APN_TEMP_DEGREES_PER_BIT; return TempVal; } void CApnCamera::write_CoolerSetPoint( double SetPoint ) { unsigned short RegVal; double TempVal; TempVal = SetPoint; if ( SetPoint < (APN_TEMP_SETPOINT_MIN - APN_TEMP_KELVIN_SCALE_OFFSET) ) TempVal = APN_TEMP_SETPOINT_MIN; if ( SetPoint > (APN_TEMP_SETPOINT_MAX - APN_TEMP_KELVIN_SCALE_OFFSET) ) TempVal = APN_TEMP_SETPOINT_MAX; RegVal = (unsigned short)( (TempVal / APN_TEMP_DEGREES_PER_BIT) + APN_TEMP_SETPOINT_ZERO_POINT ); Write( FPGA_REG_TEMP_DESIRED, RegVal ); } double CApnCamera::read_CoolerBackoffPoint() { return ( m_pvtCoolerBackoffPoint ); } void CApnCamera::write_CoolerBackoffPoint( double BackoffPoint ) { unsigned short RegVal; double TempVal; TempVal = BackoffPoint; // BackoffPoint must be a positive number! if ( BackoffPoint < 0.0 ) TempVal = 0.0; if ( BackoffPoint < (APN_TEMP_SETPOINT_MIN - APN_TEMP_KELVIN_SCALE_OFFSET) ) TempVal = APN_TEMP_SETPOINT_MIN; if ( BackoffPoint > (APN_TEMP_SETPOINT_MAX - APN_TEMP_KELVIN_SCALE_OFFSET) ) TempVal = APN_TEMP_SETPOINT_MAX; m_pvtCoolerBackoffPoint = TempVal; RegVal = (unsigned short)( TempVal / APN_TEMP_DEGREES_PER_BIT ); Write( FPGA_REG_TEMP_BACKOFF, RegVal ); } double CApnCamera::read_CoolerDrive() { UpdateGeneralStatus(); return m_pvtCoolerDrive; } double CApnCamera::read_TempCCD() { // UpdateGeneralStatus(); unsigned short TempReg; unsigned short TempAvg; unsigned long TempTotal; int don; TempTotal = 0; don = 8; if ( m_CameraInterface == Apn_Interface_NET ) { don = 1; } for ( int i=0; i APN_SEQUENCE_DELAY_LIMIT ) Delay = APN_SEQUENCE_DELAY_LIMIT; m_pvtSequenceDelay = Delay; RegVal = (unsigned short)(Delay / APN_SEQUENCE_DELAY_RESOLUTION); Write( FPGA_REG_SEQUENCE_DELAY, RegVal ); } bool CApnCamera::read_VariableSequenceDelay() { unsigned short RegVal; Read( FPGA_REG_OP_A, RegVal ); // variable delay occurs when the bit is 0 return ( (RegVal & FPGA_BIT_DELAY_MODE) == 0 ); } void CApnCamera::write_VariableSequenceDelay( bool VariableSequenceDelay ) { unsigned short RegVal; Read( FPGA_REG_OP_A, RegVal ); if ( VariableSequenceDelay ) RegVal &= ~FPGA_BIT_DELAY_MODE; // variable when zero else RegVal |= FPGA_BIT_DELAY_MODE; // constant when one Write( FPGA_REG_OP_A, RegVal ); } unsigned short CApnCamera::read_ImageCount() { return m_pvtImageCount; } void CApnCamera::write_ImageCount( unsigned short Count ) { if ( Count == 0 ) Count = 1; Write( FPGA_REG_IMAGE_COUNT, Count ); m_pvtImageCount = Count; } void CApnCamera::write_RoiBinningH( unsigned short BinningH ) { // Check to see if we actually need to update the binning if ( BinningH != m_RoiBinningH ) { // Reset the camera Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); LoadRoiPattern( BinningH ); m_RoiBinningH = BinningH; // Reset the camera Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); // Start flushing Write( FPGA_REG_COMMAND_A, FPGA_BIT_CMD_FLUSH ); } } void CApnCamera::write_RoiBinningV( unsigned short BinningV ) { // Check to see if we actually need to update the binning if ( BinningV != m_RoiBinningV ) { m_RoiBinningV = BinningV; } } void CApnCamera::write_RoiPixelsV( unsigned short PixelsV ) { m_RoiPixelsV = PixelsV; } void CApnCamera::write_RoiStartY( unsigned short StartY ) { m_RoiStartY = StartY; } unsigned short CApnCamera::read_OverscanColumns() { return m_ApnSensorInfo->m_OverscanColumns; } unsigned short CApnCamera::read_MaxBinningV() { if ( m_ApnSensorInfo->m_ImagingRows < APN_VBINNING_MAX ) return m_ApnSensorInfo->m_ImagingRows; else return APN_VBINNING_MAX; } unsigned short CApnCamera::read_SequenceCounter() { unsigned short RegVal; Read( FPGA_REG_SEQUENCE_COUNTER, RegVal ); return RegVal; } unsigned short CApnCamera::read_TDICounter() { unsigned short RegVal; Read( FPGA_REG_TDI_COUNTER, RegVal ); return RegVal; } unsigned short CApnCamera::read_TDIRows() { return m_pvtTDIRows; } void CApnCamera::write_TDIRows( unsigned short TdiRows ) { if ( TdiRows == 0 ) // Make sure the TDI row count is at least 1 TdiRows = 1; Write( FPGA_REG_TDI_COUNT, TdiRows ); m_pvtTDIRows = TdiRows; } double CApnCamera::read_TDIRate() { return m_pvtTDIRate; } void CApnCamera::write_TDIRate( double TdiRate ) { unsigned short RegVal; if ( TdiRate < APN_TDI_RATE_MIN ) TdiRate = APN_TDI_RATE_MIN; if ( TdiRate > APN_TDI_RATE_MAX ) TdiRate = APN_TDI_RATE_MAX; RegVal = (unsigned short)( TdiRate / APN_TDI_RATE_RESOLUTION ); Write( FPGA_REG_TDI_RATE, RegVal ); m_pvtTDIRate = TdiRate; } unsigned short CApnCamera::read_IoPortAssignment() { unsigned short RegVal; Read( FPGA_REG_IO_PORT_ASSIGNMENT, RegVal ); RegVal &= FPGA_MASK_IO_PORT_ASSIGNMENT; return RegVal; } void CApnCamera::write_IoPortAssignment( unsigned short IoPortAssignment ) { IoPortAssignment &= FPGA_MASK_IO_PORT_ASSIGNMENT; Write( FPGA_REG_IO_PORT_ASSIGNMENT, IoPortAssignment ); } unsigned short CApnCamera::read_IoPortDirection() { unsigned short RegVal; Read( FPGA_REG_IO_PORT_DIRECTION, RegVal ); RegVal &= FPGA_MASK_IO_PORT_DIRECTION; return RegVal; } void CApnCamera::write_IoPortDirection( unsigned short IoPortDirection ) { IoPortDirection &= FPGA_MASK_IO_PORT_DIRECTION; Write( FPGA_REG_IO_PORT_DIRECTION, IoPortDirection ); } unsigned short CApnCamera::read_IoPortData() { unsigned short RegVal; Read( FPGA_REG_IO_PORT_READ, RegVal ); RegVal &= FPGA_MASK_IO_PORT_DATA; return RegVal; } void CApnCamera::write_IoPortData( unsigned short IoPortData ) { IoPortData &= FPGA_MASK_IO_PORT_DATA; Write( FPGA_REG_IO_PORT_WRITE, IoPortData ); } unsigned short CApnCamera::read_TwelveBitGain() { return m_pvtTwelveBitGain; } void CApnCamera::write_TwelveBitGain( unsigned short TwelveBitGain ) { unsigned short NewVal; unsigned short StartVal; unsigned short FirstBit; NewVal = 0x0; StartVal = TwelveBitGain & 0x3FF; for ( int i=0; i<10; i++ ) { FirstBit = ( StartVal & 0x0001 ); NewVal |= ( FirstBit << (10-i) ); StartVal = StartVal >> 1; } NewVal |= 0x4000; Write( FPGA_REG_AD_CONFIG_DATA, NewVal ); Write( FPGA_REG_COMMAND_B, 0x8000 ); m_pvtTwelveBitGain = TwelveBitGain & 0x3FF; } double CApnCamera::read_MaxExposureTime() { return APN_EXPOSURE_TIME_MAX; } double CApnCamera::read_TestLedBrightness() { return m_pvtTestLedBrightness; } void CApnCamera::write_TestLedBrightness( double TestLedBrightness ) { unsigned short RegVal; unsigned short OpRegA; if ( TestLedBrightness == m_pvtTestLedBrightness ) return; if ( m_pvtCoolerEnable ) { Read( FPGA_REG_OP_A, OpRegA ); OpRegA |= FPGA_BIT_TEMP_SUSPEND; Write( FPGA_REG_OP_A, OpRegA ); do { Read( FPGA_REG_GENERAL_STATUS, RegVal ); } while ( (RegVal & FPGA_BIT_STATUS_TEMP_SUSPEND_ACK) == 0 ); } RegVal = (unsigned short)( (double)FPGA_MASK_LED_ILLUMINATION * (TestLedBrightness/100.0) ); Write( FPGA_REG_LED_DRIVE, RegVal ); Read( FPGA_REG_OP_B, RegVal ); RegVal &= ~FPGA_BIT_DAC_SELECT_ZERO; RegVal |= FPGA_BIT_DAC_SELECT_ONE; Write( FPGA_REG_OP_B, RegVal ); Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_DAC_LOAD ); m_pvtTestLedBrightness = TestLedBrightness; if ( m_pvtCoolerEnable ) { OpRegA &= ~FPGA_BIT_TEMP_SUSPEND; Write( FPGA_REG_OP_A, OpRegA ); } } long CApnCamera::LoadVerticalPattern() { unsigned short RegData; // Prime the RAM (Enable) Read( FPGA_REG_OP_B, RegData ); RegData |= FPGA_BIT_VRAM_ENABLE; Write( FPGA_REG_OP_B, RegData ); WriteMultiSRMD( FPGA_REG_VRAM_INPUT, m_ApnSensorInfo->m_VerticalPattern.PatternData, m_ApnSensorInfo->m_VerticalPattern.NumElements ); // RAM is now loaded (Disable) Read( FPGA_REG_OP_B, RegData ); RegData &= ~FPGA_BIT_VRAM_ENABLE; Write( FPGA_REG_OP_B, RegData ); return 0; } long CApnCamera::LoadClampPattern() { unsigned short RegData; // Prime the RAM (Enable) Read( FPGA_REG_OP_B, RegData ); RegData |= FPGA_BIT_HCLAMP_ENABLE; Write( FPGA_REG_OP_B, RegData ); if ( m_DataBits == Apn_Resolution_SixteenBit ) { WriteHorizontalPattern( &m_ApnSensorInfo->m_ClampPatternSixteen, FPGA_REG_HCLAMP_INPUT, 1 ); } else if ( m_DataBits == Apn_Resolution_TwelveBit ) { WriteHorizontalPattern( &m_ApnSensorInfo->m_ClampPatternTwelve, FPGA_REG_HCLAMP_INPUT, 1 ); } // RAM is now loaded (Disable) Read( FPGA_REG_OP_B, RegData ); RegData &= ~FPGA_BIT_HCLAMP_ENABLE; Write( FPGA_REG_OP_B, RegData ); return 0; } long CApnCamera::LoadSkipPattern() { unsigned short RegData; // Prime the RAM (Enable) Read( FPGA_REG_OP_B, RegData ); RegData |= FPGA_BIT_HSKIP_ENABLE; Write( FPGA_REG_OP_B, RegData ); if ( m_DataBits == Apn_Resolution_SixteenBit ) { WriteHorizontalPattern( &m_ApnSensorInfo->m_SkipPatternSixteen, FPGA_REG_HSKIP_INPUT, 1 ); } else if ( m_DataBits == Apn_Resolution_TwelveBit ) { WriteHorizontalPattern( &m_ApnSensorInfo->m_SkipPatternTwelve, FPGA_REG_HSKIP_INPUT, 1 ); } // RAM is now loaded (Disable) Read( FPGA_REG_OP_B, RegData ); RegData &= ~FPGA_BIT_HSKIP_ENABLE; Write( FPGA_REG_OP_B, RegData ); return 0; } long CApnCamera::LoadRoiPattern( unsigned short binning ) { unsigned short RegData; // Prime the RAM (Enable) Read( FPGA_REG_OP_B, RegData ); RegData |= FPGA_BIT_HRAM_ENABLE; Write( FPGA_REG_OP_B, RegData ); if ( m_DataBits == Apn_Resolution_SixteenBit ) { WriteHorizontalPattern( &m_ApnSensorInfo->m_RoiPatternSixteen, FPGA_REG_HRAM_INPUT, binning ); } else if ( m_DataBits == Apn_Resolution_TwelveBit ) { WriteHorizontalPattern( &m_ApnSensorInfo->m_RoiPatternTwelve, FPGA_REG_HRAM_INPUT, binning ); } // RAM is now loaded (Disable) Read( FPGA_REG_OP_B, RegData ); RegData &= ~FPGA_BIT_HRAM_ENABLE; Write( FPGA_REG_OP_B, RegData ); return 0; } long CApnCamera::WriteHorizontalPattern( APN_HPATTERN_FILE *Pattern, unsigned short RamReg, unsigned short Binning ) { unsigned short i; unsigned short DataCount; unsigned short *DataArray; unsigned short Index; unsigned short BinNumber; Index = 0; BinNumber = Binning - 1; // arrays are zero-based DataCount = Pattern->RefNumElements + Pattern->BinNumElements[BinNumber] + Pattern->SigNumElements; DataArray = (unsigned short *)malloc(DataCount * sizeof(unsigned short)); for ( i=0; iRefNumElements; i++ ) { DataArray[Index] = Pattern->RefPatternData[i]; Index++; } for ( i=0; iBinNumElements[BinNumber]; i++ ) { DataArray[Index] = Pattern->BinPatternData[BinNumber][i]; Index++; } for ( i=0; iSigNumElements; i++ ) { DataArray[Index] = Pattern->SigPatternData[i]; Index++; } WriteMultiSRMD( RamReg, DataArray, DataCount ); // cleanup free( DataArray ); return 0; } long CApnCamera::InitDefaults() { unsigned short RegVal; unsigned short CameraID; unsigned short ShutterDelay; unsigned short PreRoiRows, PostRoiRows; unsigned short PreRoiVBinning, PostRoiVBinning; unsigned short UnbinnedRoiY; // Vertical ROI pixels // Read the Camera ID register Read( FPGA_REG_CAMERA_ID, CameraID ); CameraID &= FPGA_MASK_CAMERA_ID; // Look up the ID and dynamically create the m_ApnSensorInfo object switch ( CameraID ) { case APN_ALTA_KAF0401E_CAM_ID: m_ApnSensorInfo = new CApnCamData_KAF0401E; break; case APN_ALTA_KAF1602E_CAM_ID: m_ApnSensorInfo = new CApnCamData_KAF1602E; break; case APN_ALTA_KAF0261E_CAM_ID: m_ApnSensorInfo = new CApnCamData_KAF0261E; break; case APN_ALTA_KAF1301E_CAM_ID: m_ApnSensorInfo = new CApnCamData_KAF1301E; break; case APN_ALTA_KAF1401E_CAM_ID: m_ApnSensorInfo = new CApnCamData_KAF1401E; break; case APN_ALTA_KAF1001E_CAM_ID: m_ApnSensorInfo = new CApnCamData_KAF1001E; break; case APN_ALTA_KAF3200E_CAM_ID: m_ApnSensorInfo = new CApnCamData_KAF3200E; break; case APN_ALTA_KAF4202_CAM_ID: m_ApnSensorInfo = new CApnCamData_KAF4202; break; case APN_ALTA_KAF6303E_CAM_ID: m_ApnSensorInfo = new CApnCamData_KAF6303E; break; case APN_ALTA_KAF16801E_CAM_ID: m_ApnSensorInfo = new CApnCamData_KAF16801E; break; case APN_ALTA_TH7899_CAM_ID: m_ApnSensorInfo = new CApnCamData_TH7899; break; case APN_ALTA_CCD4710LS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD4710LS; break; case APN_ALTA_CCD4710HS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD4710HS; break; case APN_ALTA_CCD4240LS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD4240LS; break; case APN_ALTA_CCD4240HS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD4240HS; break; case APN_ALTA_CCD5710LS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD5710LS; break; case APN_ALTA_CCD5710HS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD5710HS; break; case APN_ALTA_CCD3011LS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD3011LS; break; case APN_ALTA_CCD3011HS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD3011HS; break; case APN_ALTA_CCD5520LS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD5520LS; break; case APN_ALTA_CCD5520HS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD5520HS; break; case APN_ALTA_CCD4720LS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD4720LS; break; case APN_ALTA_CCD4720HS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD4720HS; break; case APN_ALTA_CCD7700LS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD7700LS; break; case APN_ALTA_CCD7700HS_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD7700HS; break; case APN_ALTA_CCD4710LS2_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD4710LS2; break; case APN_ALTA_CCD4710LS3_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD4710LS3; break; case APN_ALTA_CCD4710LS4_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD4710LS4; break; case APN_ALTA_CCD4710LS5_CAM_ID: m_ApnSensorInfo = new CApnCamData_CCD4710LS5; break; default: return 1; break; } // we created the object, now set everything m_ApnSensorInfo->Initialize(); // Initialize public variables m_DigitizeOverscan = false; m_DataBits = Apn_Resolution_SixteenBit; // Initialize private variables m_pvtCameraMode = Apn_CameraMode_Normal; m_pvtNetworkTransferMode = Apn_NetworkMode_Tcp; // Initialize variables used for imaging m_RoiStartX = 0; m_RoiStartY = 0; m_RoiPixelsH = m_ApnSensorInfo->m_ImagingColumns; m_RoiPixelsV = m_ApnSensorInfo->m_ImagingRows; m_RoiBinningH = 1; m_RoiBinningV = 1; printf ("Camera ID is %u\n",CameraID); printf("sensor = %s\n", m_ApnSensorInfo->m_Sensor); printf("model = %s\n",m_ApnSensorInfo->m_CameraModel); printf("interline = %u\n",m_ApnSensorInfo->m_InterlineCCD); printf("serialA = %u\n",m_ApnSensorInfo->m_SupportsSerialA); printf("serialB = %u\n",m_ApnSensorInfo->m_SupportsSerialB); printf("ccdtype = %u\n",m_ApnSensorInfo->m_SensorTypeCCD); printf("Tcolumns = %u\n",m_ApnSensorInfo->m_TotalColumns); printf("ImgColumns = %u\n",m_ApnSensorInfo->m_ImagingColumns); printf("ClampColumns = %u\n",m_ApnSensorInfo->m_ClampColumns); printf("PreRoiSColumns = %u\n",m_ApnSensorInfo->m_PreRoiSkipColumns); printf("PostRoiSColumns = %u\n",m_ApnSensorInfo->m_PostRoiSkipColumns); printf("OverscanColumns = %u\n",m_ApnSensorInfo->m_OverscanColumns); printf("TRows = %u\n",m_ApnSensorInfo->m_TotalRows); printf("ImgRows = %u\n",m_ApnSensorInfo->m_ImagingRows); printf("UnderscanRows = %u\n",m_ApnSensorInfo->m_UnderscanRows); printf("OverscanRows = %u\n",m_ApnSensorInfo->m_OverscanRows); printf("VFlushBinning = %u\n",m_ApnSensorInfo->m_VFlushBinning); printf("HFlushDisable = %u\n",m_ApnSensorInfo->m_HFlushDisable); printf("ShutterCloseDelay = %u\n",m_ApnSensorInfo->m_ShutterCloseDelay); printf("PixelSizeX = %lf\n",m_ApnSensorInfo->m_PixelSizeX); printf("PixelSizeY = %lf\n",m_ApnSensorInfo->m_PixelSizeY); printf("Color = %u\n",m_ApnSensorInfo->m_Color); // printf("ReportedGainTwelveBit = %lf\n",m_ApnSensorInfo->m_ReportedGainTwelveBit); printf("ReportedGainSixteenBit = %lf\n",m_ApnSensorInfo->m_ReportedGainSixteenBit); printf("MinSuggestedExpTime = %lf\n",m_ApnSensorInfo->m_MinSuggestedExpTime); printf("CoolingSupported = %u\n",m_ApnSensorInfo->m_CoolingSupported); printf("RegulatedCoolingSupported = %u\n",m_ApnSensorInfo->m_RegulatedCoolingSupported); printf("TempSetPoint = %lf\n",m_ApnSensorInfo->m_TempSetPoint); // printf("TempRegRate = %u\n",m_ApnSensorInfo->m_TempRegRate); printf("TempRampRateOne = %u\n",m_ApnSensorInfo->m_TempRampRateOne); printf("TempRampRateTwo = %u\n",m_ApnSensorInfo->m_TempRampRateTwo); printf("TempBackoffPoint = %lf\n",m_ApnSensorInfo->m_TempBackoffPoint); printf("DefaultGainTwelveBit = %u\n",m_ApnSensorInfo->m_DefaultGainTwelveBit); printf("DefaultOffsetTwelveBit = %u\n",m_ApnSensorInfo->m_DefaultOffsetTwelveBit); printf("DefaultRVoltage = %u\n",m_ApnSensorInfo->m_DefaultRVoltage); printf ("RoiPixelsH is %u\n",m_RoiPixelsH); printf ("RoiPixelsV is %u\n",m_RoiPixelsV); // Issue a clear command, so the registers are zeroed out // This will put the camera in a known state for us. Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_CLEAR_ALL ); // Reset the camera Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); // Load Inversion Masks Write( FPGA_REG_VRAM_INV_MASK, m_ApnSensorInfo->m_VerticalPattern.Mask ); Write( FPGA_REG_HRAM_INV_MASK, m_ApnSensorInfo->m_RoiPatternSixteen.Mask ); // Load Pattern Files LoadVerticalPattern(); LoadClampPattern(); LoadSkipPattern(); LoadRoiPattern( m_RoiBinningH ); // Program default camera settings Write( FPGA_REG_CLAMP_COUNT, m_ApnSensorInfo->m_ClampColumns ); Write( FPGA_REG_PREROI_SKIP_COUNT, m_ApnSensorInfo->m_PreRoiSkipColumns ); Write( FPGA_REG_ROI_COUNT, m_ApnSensorInfo->m_ImagingColumns ); Write( FPGA_REG_POSTROI_SKIP_COUNT, m_ApnSensorInfo->m_PostRoiSkipColumns + m_ApnSensorInfo->m_OverscanColumns ); // Since the default state of m_DigitizeOverscan is false, set the count to zero. Write( FPGA_REG_OVERSCAN_COUNT, 0x0 ); // Now calculate the vertical settings UnbinnedRoiY = m_RoiPixelsV * m_RoiBinningV; PreRoiRows = m_ApnSensorInfo->m_UnderscanRows + m_RoiStartY; PostRoiRows = m_ApnSensorInfo->m_TotalRows - PreRoiRows - UnbinnedRoiY; PreRoiVBinning = 1; PostRoiVBinning = 1; // For interline CCDs, set "Fast Dump" mode if the particular array is NOT digitized if ( m_ApnSensorInfo->m_InterlineCCD ) { // use the fast dump feature to get rid of the data quickly. // one row, binning to the original row count // note that we only are not digitized in arrays 1 and 3 PreRoiVBinning = PreRoiRows; PostRoiVBinning = PostRoiRows; PreRoiVBinning |= FPGA_BIT_ARRAY_FASTDUMP; PostRoiVBinning |= FPGA_BIT_ARRAY_FASTDUMP; PreRoiRows = 1; PostRoiRows = 1; } // Program the vertical settings Write( FPGA_REG_A1_ROW_COUNT, PreRoiRows ); Write( FPGA_REG_A1_VBINNING, PreRoiVBinning ); Write( FPGA_REG_A2_ROW_COUNT, m_RoiPixelsV ); Write( FPGA_REG_A2_VBINNING, (m_RoiBinningV | FPGA_BIT_ARRAY_DIGITIZE) ); Write( FPGA_REG_A3_ROW_COUNT, PostRoiRows ); Write( FPGA_REG_A3_VBINNING, PostRoiVBinning ); Write( FPGA_REG_VFLUSH_BINNING, m_ApnSensorInfo->m_VFlushBinning ); double CloseDelay = (double)m_ApnSensorInfo->m_ShutterCloseDelay / 1000; ShutterDelay = (unsigned short) ( (CloseDelay - APN_SHUTTER_CLOSE_DIFF) / APN_TIMER_RESOLUTION ); Write( FPGA_REG_SHUTTER_CLOSE_DELAY, ShutterDelay ); Write( FPGA_REG_IMAGE_COUNT, 1 ); Write( FPGA_REG_SEQUENCE_DELAY, 0 ); if ( m_ApnSensorInfo->m_HFlushDisable ) { Read( FPGA_REG_OP_A, RegVal ); RegVal |= FPGA_BIT_DISABLE_H_CLK; Write( FPGA_REG_OP_A, RegVal ); } // Reset the camera again Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_RESET ); // Start flushing Write( FPGA_REG_COMMAND_A, FPGA_BIT_CMD_FLUSH ); // If we are a USB2 camera, set all the 12bit variables for the 12bit // A/D processor if ( m_CameraInterface == Apn_Interface_USB ) { InitTwelveBitAD(); write_TwelveBitGain( m_ApnSensorInfo->m_DefaultGainTwelveBit ); WriteTwelveBitOffset(); } // Set the Fan State. Setting the private var first to make sure the write_FanMode // call thinks we're doing a state transition. // On write_FanMode return, our state will be Apn_FanMode_Medium m_pvtFanMode = Apn_FanMode_Off; // we're going to set this write_FanMode( Apn_FanMode_Medium ); // Initialize the LED states and the LED mode. There is nothing to output // to the device since we issued our CLEAR early in the init() process, and // we are now in a known state. m_pvtLedStateA = Apn_LedState_Expose; m_pvtLedStateB = Apn_LedState_Expose; m_pvtLedMode = Apn_LedMode_EnableAll; // Default value for test LED is 0% m_pvtTestLedBrightness = 0.0; // Program our initial cooler values. The only cooler value that we reset // at init time is the backoff point. Everything else is left untouched, and // state information is determined from the camera controller. m_pvtCoolerBackoffPoint = m_ApnSensorInfo->m_TempBackoffPoint; write_CoolerBackoffPoint( m_pvtCoolerBackoffPoint ); Write( FPGA_REG_TEMP_RAMP_DOWN_A, m_ApnSensorInfo->m_TempRampRateOne ); Write( FPGA_REG_TEMP_RAMP_DOWN_B, m_ApnSensorInfo->m_TempRampRateTwo ); // the collor code not only determines the m_pvtCoolerEnable state, but // also implicitly calls UpdateGeneralStatus() as part of read_CoolerStatus() if ( read_CoolerStatus() == Apn_CoolerStatus_Off ) m_pvtCoolerEnable = false; else m_pvtCoolerEnable = true; m_pvtImageInProgress = false; m_pvtImageReady = false; return 0; } long CApnCamera::InitTwelveBitAD() { Write( FPGA_REG_AD_CONFIG_DATA, 0x0028 ); Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_AD_CONFIG ); return 0; } long CApnCamera::WriteTwelveBitOffset() { unsigned short NewVal; unsigned short StartVal; unsigned short FirstBit; NewVal = 0x0; StartVal = m_ApnSensorInfo->m_DefaultOffsetTwelveBit & 0xFF; for ( int i=0; i<8; i++ ) { FirstBit = ( StartVal & 0x0001 ); NewVal |= ( FirstBit << (10-i) ); StartVal = StartVal >> 1; } NewVal |= 0x2000; Write( FPGA_REG_AD_CONFIG_DATA, NewVal ); Write( FPGA_REG_COMMAND_B, FPGA_BIT_CMD_AD_CONFIG ); return 0; } void CApnCamera::UpdateGeneralStatus() { unsigned short StatusReg; unsigned short HeatsinkTempReg; unsigned short CcdTempReg; unsigned short CoolerDriveReg; unsigned short VoltageReg; unsigned short TdiCounterReg; unsigned short SequenceCounterReg; // Read the general status register of the device QueryStatusRegs( StatusReg, HeatsinkTempReg, CcdTempReg, CoolerDriveReg, VoltageReg, TdiCounterReg, SequenceCounterReg ); m_pvtStatusReg = StatusReg; HeatsinkTempReg &= FPGA_MASK_TEMP_PARAMS; CcdTempReg &= FPGA_MASK_TEMP_PARAMS; CoolerDriveReg &= FPGA_MASK_TEMP_PARAMS; VoltageReg &= FPGA_MASK_INPUT_VOLTAGE; if ( CoolerDriveReg > 3200 ) m_pvtCoolerDrive = 100.0; else m_pvtCoolerDrive = ( (double)(CoolerDriveReg - 600) / 2600.0 ) * 100.0; m_pvtCurrentCcdTemp = ( (CcdTempReg - APN_TEMP_SETPOINT_ZERO_POINT) * APN_TEMP_DEGREES_PER_BIT ); m_pvtCurrentHeatsinkTemp = ( (HeatsinkTempReg - APN_TEMP_HEATSINK_ZERO_POINT) * APN_TEMP_DEGREES_PER_BIT ); m_pvtInputVoltage = VoltageReg * APN_VOLTAGE_RESOLUTION; // Update ShutterState m_pvtShutterState = ( (m_pvtStatusReg & FPGA_BIT_STATUS_SHUTTER_OPEN) != 0 ); } bool CApnCamera::ImageReady() { return m_pvtImageReady; } void CApnCamera::SignalImagingDone() { m_pvtImageInProgress = false; } indi-0.5/src/apogee/FpgaRegs.h0000644000175000017500000001430410610474640014013 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __FPGAREGS_H__APOGEE_APN__ #define __FPGAREGS_H__APOGEE_APN__ #define FPGA_TOTAL_REGISTER_COUNT 103 #define FPGA_REG_COMMAND_A 0 #define FPGA_BIT_CMD_EXPOSE 0x0001 #define FPGA_BIT_CMD_DARK 0x0002 #define FPGA_BIT_CMD_TEST 0x0004 #define FPGA_BIT_CMD_TDI 0x0008 #define FPGA_BIT_CMD_FLUSH 0x0010 #define FPGA_BIT_CMD_TRIGGER_EXPOSE 0x0020 #define FPGA_REG_COMMAND_B 1 #define FPGA_BIT_CMD_RESET 0x0002 #define FPGA_BIT_CMD_CLEAR_ALL 0x0010 #define FPGA_BIT_CMD_END_EXPOSURE 0x0080 #define FPGA_BIT_CMD_RAMP_TO_SETPOINT 0x0200 #define FPGA_BIT_CMD_RAMP_TO_AMBIENT 0x0400 #define FPGA_BIT_CMD_START_TEMP_READ 0x2000 #define FPGA_BIT_CMD_DAC_LOAD 0x4000 #define FPGA_BIT_CMD_AD_CONFIG 0x8000 #define FPGA_REG_OP_A 2 #define FPGA_BIT_LED_DISABLE 0x0001 #define FPGA_BIT_PAUSE_TIMER 0x0002 #define FPGA_BIT_RATIO 0x0004 #define FPGA_BIT_DELAY_MODE 0x0008 #define FPGA_BIT_P_CLK_MODE 0x0010 #define FPGA_BIT_LED_EXPOSE_DISABLE 0x0020 #define FPGA_BIT_DISABLE_H_CLK 0x0040 #define FPGA_BIT_SHUTTER_AMP_CONTROL 0x0080 #define FPGA_BIT_HALT_DISABLE 0x0100 #define FPGA_BIT_SHUTTER_MODE 0x0200 #define FPGA_BIT_DIGITIZATION_RES 0x0400 #define FPGA_BIT_FORCE_SHUTTER 0x0800 #define FPGA_BIT_DISABLE_SHUTTER 0x1000 #define FPGA_BIT_TEMP_SUSPEND 0x2000 #define FPGA_BIT_SHUTTER_SOURCE 0x4000 #define FPGA_BIT_TEST_MODE 0x8000 #define FPGA_REG_OP_B 3 #define FPGA_BIT_HCLAMP_ENABLE 0x0008 #define FPGA_BIT_HSKIP_ENABLE 0x0010 #define FPGA_BIT_HRAM_ENABLE 0x0020 #define FPGA_BIT_VRAM_ENABLE 0x0040 #define FPGA_BIT_DAC_SELECT_ZERO 0x0080 #define FPGA_BIT_DAC_SELECT_ONE 0x0100 #define FPGA_BIT_AD_SIMULATION 0x8000 #define FPGA_REG_TIMER_UPPER 4 #define FPGA_REG_TIMER_LOWER 5 #define FPGA_REG_HRAM_INPUT 6 #define FPGA_REG_VRAM_INPUT 7 #define FPGA_REG_HRAM_INV_MASK 8 #define FPGA_REG_VRAM_INV_MASK 9 #define FPGA_REG_HCLAMP_INPUT 10 #define FPGA_REG_HSKIP_INPUT 11 #define FPGA_REG_PRECLAMP_SKIP_COUNT 12 #define FPGA_REG_CLAMP_COUNT 13 #define FPGA_REG_PREROI_SKIP_COUNT 14 #define FPGA_REG_ROI_COUNT 15 #define FPGA_REG_POSTROI_SKIP_COUNT 16 #define FPGA_REG_OVERSCAN_COUNT 17 #define FPGA_REG_IMAGE_COUNT 18 #define FPGA_REG_VFLUSH_BINNING 19 #define FPGA_REG_SHUTTER_CLOSE_DELAY 20 #define FPGA_REG_POSTOVERSCAN_SKIP_COUNT 21 #define FPGA_REG_SHUTTER_STROBE_POSITION 23 #define FPGA_REG_SHUTTER_STROBE_PERIOD 24 #define FPGA_REG_FAN_SPEED_CONTROL 25 #define FPGA_REG_LED_DRIVE 26 #define FPGA_REG_SUBSTRATE_ADJUST 27 #define FPGA_MASK_FAN_SPEED_CONTROL 0x0FFF #define FPGA_MASK_LED_ILLUMINATION 0x0FFF #define FPGA_MASK_SUBSTRATE_ADJUST 0x0FFF #define FPGA_REG_TEST_COUNT_UPPER 28 #define FPGA_REG_TEST_COUNT_LOWER 29 #define FPGA_REG_A1_ROW_COUNT 30 #define FPGA_REG_A1_VBINNING 31 #define FPGA_REG_A2_ROW_COUNT 32 #define FPGA_REG_A2_VBINNING 33 #define FPGA_REG_A3_ROW_COUNT 34 #define FPGA_REG_A3_VBINNING 35 #define FPGA_MASK_VBINNING 0x0FFF #define FPGA_BIT_ARRAY_DIGITIZE 0x1000 #define FPGA_BIT_ARRAY_FASTDUMP 0x4000 #define FPGA_REG_SEQUENCE_DELAY 47 #define FPGA_REG_TDI_RATE 48 #define FPGA_REG_IO_PORT_WRITE 49 #define FPGA_REG_IO_PORT_DIRECTION 50 #define FPGA_MASK_IO_PORT_DIRECTION 0x003F #define FPGA_REG_IO_PORT_ASSIGNMENT 51 #define FPGA_MASK_IO_PORT_ASSIGNMENT 0x003F #define FPGA_REG_LED_SELECT 52 #define FPGA_MASK_LED_SELECT_A 0x000F #define FPGA_MASK_LED_SELECT_B 0x00F0 #define FPGA_BIT_LED_EXPOSE 0x0001 #define FPGA_BIT_LED_IMAGE_ACTIVE 0x0002 #define FPGA_BIT_LED_FLUSHING 0x0004 #define FPGA_BIT_LED_TRIGGER_WAIT 0x0008 #define FPGA_BIT_LED_EXT_TRIGGER 0x0010 #define FPGA_BIT_LED_EXT_SHUTTER_INPUT 0x0020 #define FPGA_BIT_LED_EXT_START_READOUT 0x0040 #define FPGA_BIT_LED_AT_TEMP 0x0080 #define FPGA_REG_SCRATCH 53 #define FPGA_REG_TDI_COUNT 54 #define FPGA_REG_TEMP_DESIRED 55 #define FPGA_REG_TEMP_RAMP_DOWN_A 57 #define FPGA_REG_TEMP_RAMP_DOWN_B 58 #define FPGA_REG_TEMP_BACKOFF 60 #define FPGA_REG_TEMP_COOLER_OVERRIDE 61 #define FPGA_MASK_TEMP_PARAMS 0x0FFF // 12 bits #define FPGA_REG_AD_CONFIG_DATA 62 #define FPGA_MASK_AD_GAIN 0x07FF // 11 bits #define FPGA_REG_IO_PORT_READ 90 #define FPGA_MASK_IO_PORT_DATA 0x003F #define FPGA_REG_GENERAL_STATUS 91 #define FPGA_BIT_STATUS_IMAGE_EXPOSING 0x0001 #define FPGA_BIT_STATUS_IMAGING_ACTIVE 0x0002 #define FPGA_BIT_STATUS_DATA_HALTED 0x0004 #define FPGA_BIT_STATUS_IMAGE_DONE 0x0008 #define FPGA_BIT_STATUS_FLUSHING 0x0010 #define FPGA_BIT_STATUS_WAITING_TRIGGER 0x0020 #define FPGA_BIT_STATUS_SHUTTER_OPEN 0x0040 #define FPGA_BIT_STATUS_PATTERN_ERROR 0x0080 #define FPGA_BIT_STATUS_TEMP_SUSPEND_ACK 0x0100 #define FPGA_BIT_STATUS_TEMP_REVISION 0x2000 #define FPGA_BIT_STATUS_TEMP_AT_TEMP 0x4000 #define FPGA_BIT_STATUS_TEMP_ACTIVE 0x8000 #define FPGA_REG_TEMP_HEATSINK 93 #define FPGA_REG_TEMP_CCD 94 #define FPGA_REG_TEMP_DRIVE 95 #define FPGA_REG_INPUT_VOLTAGE 96 #define FPGA_MASK_INPUT_VOLTAGE 0x0FFF #define FPGA_REG_TEMP_REVISED 97 #define FPGA_REG_FIFO_DATA 98 #define FPGA_REG_FIFO_STATUS 99 #define FPGA_REG_CAMERA_ID 100 #define FPGA_MASK_CAMERA_ID 0x007F #define FPGA_REG_FIRMWARE_REV 101 #define FPGA_REG_FIFO_FULL_COUNT 102 #define FPGA_REG_FIFO_EMPTY_COUNT 103 #define FPGA_REG_TDI_COUNTER 104 #define FPGA_REG_SEQUENCE_COUNTER 105 #endif indi-0.5/src/apogee/ApogeeIoctl.h0000644000175000017500000000360610610474640014513 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApogeeIoctl.h Include file for I/O // // Define the IOCTL codes we will use. The IOCTL code contains a command // identifier, plus other information about the device, the type of access // with which the file must have been opened, and the type of buffering. // extern unsigned short apogee_bit; extern unsigned short apogee_word; extern unsigned long apogee_long; extern short apogee_signed; // General Ioctl definitions for Apogee CCD device driver #define APOGEE_IOC_MAGIC 'j' #define APOGEE_IOC_MAXNR 100 #define APOGEE_IOCHARDRESET _IO(APOGEE_IOC_MAGIC,0) // Read single word #define IOCTL_GPD_READ_ISA_USHORT _IOR(APOGEE_IOC_MAGIC,1,apogee_word) // Write single word #define IOCTL_GPD_WRITE_ISA_USHORT _IOW(APOGEE_IOC_MAGIC,2,apogee_word) // Read line from camera #define IOCTL_GPD_READ_ISA_LINE _IOR(APOGEE_IOC_MAGIC,3,apogee_word) #define IOCTL_GPD_READ_PPI_USHORT _IOR(APOGEE_IOC_MAGIC,1,apogee_word) // Write single word #define IOCTL_GPD_WRITE_PPI_USHORT _IOW(APOGEE_IOC_MAGIC,2,apogee_word) // Read line from camera #define IOCTL_GPD_READ_PPI_LINE _IOR(APOGEE_IOC_MAGIC,3,apogee_word) indi-0.5/src/apogee/ApogeeUsb.h0000644000175000017500000000447610610474640014200 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #if !defined(_APOGEEUSB_H__INCLUDED_) #define _APOGEEUSB_H__INCLUDED_ #ifndef APN_USB_TYPE #define APN_USB_TYPE unsigned short #endif #define APN_USB_MAXCAMERAS 255 typedef struct _APN_USB_CAMINFO { unsigned short CamNumber; unsigned short CamModel; } APN_USB_CAMINFO; #ifndef IN #define IN #endif #ifndef OUT #define OUT #endif APN_USB_TYPE ApnUsbOpen( unsigned short DeviceNumber ); APN_USB_TYPE ApnUsbClose( void ); APN_USB_TYPE ApnUsbDiscovery( unsigned short *UsbCamCount, APN_USB_CAMINFO UsbCamInfo[] ); APN_USB_TYPE ApnUsbReadReg( unsigned short FpgaReg, unsigned short *FpgaData ); APN_USB_TYPE ApnUsbWriteReg( unsigned short FpgaReg, unsigned short FpgaData ); APN_USB_TYPE ApnUsbWriteRegMulti( unsigned short FpgaReg, unsigned short FpgaData[], unsigned short RegCount ); APN_USB_TYPE ApnUsbWriteRegMultiMRMD( unsigned short FpgaReg[], unsigned short FpgaData[], unsigned short RegCount ); APN_USB_TYPE ApnUsbReadStatusRegs( unsigned short *StatusReg, unsigned short *HeatsinkTempReg, unsigned short *CcdTempReg, unsigned short *CoolerDriveReg, unsigned short *VoltageReg, unsigned short *TdiCounter, unsigned short *SequenceCounter ); APN_USB_TYPE ApnUsbStartExp( unsigned short ImageWidth, unsigned short ImageHeight ); APN_USB_TYPE ApnUsbStopExp( bool DigitizeData ); APN_USB_TYPE ApnUsbGetImage( unsigned short *pMem ); APN_USB_TYPE ApnUsbReset(); #endif // !defined(_APOGEEUSB_H__INCLUDED_) indi-0.5/src/apogee/ApnCamData_KAF1602E.h0000644000175000017500000000335210610474640015346 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF1602E.h: Interface file for the CApnCamData_KAF1602E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_KAF1602E : public CApnCamData { public: CApnCamData_KAF1602E(); virtual ~CApnCamData_KAF1602E(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_CCD5710HS.cpp0000644000175000017500000005222510610474646016034 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD5710HS.cpp: Implementation file for the CApnCamData_CCD5710HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD5710HS.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD5710HS::CApnCamData_CCD5710HS() { } CApnCamData_CCD5710HS::~CApnCamData_CCD5710HS() { } void CApnCamData_CCD5710HS::Initialize() { strcpy( m_Sensor, "CCD5710HS" ); strcpy( m_CameraModel, "57" ); m_CameraId = 19; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 536; m_ImagingColumns = 512; m_ClampColumns = 12; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 12; m_TotalRows = 1056; m_ImagingRows = 512; m_UnderscanRows = 536; m_OverscanRows = 8; m_VFlushBinning = 4; m_EnableSingleRowOffset = true; m_RowOffsetBinning = 536; m_HFlushDisable = false; m_ShutterCloseDelay = 0; m_PixelSizeX = 13; m_PixelSizeY = 13; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 1.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD5710HS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 23; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/Apn.h0000644000175000017500000000405510610474640013035 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define APN_DRIVER_VERSION "2.0.13.0" #define APN_HBINNING_MAX 10 #define APN_VBINNING_MAX 2048 #define APN_TIMER_RESOLUTION 0.00000256 #define APN_PERIOD_TIMER_RESOLUTION 0.000000040 #define APN_TIMER_OFFSET_COUNT 3 #define APN_SEQUENCE_DELAY_RESOLUTION 0.000327 #define APN_SEQUENCE_DELAY_LIMIT 21.429945 #define APN_EXPOSURE_TIME_MIN 0.00001 // 10us is the defined min. #define APN_EXPOSURE_TIME_MAX 10990.0 // seconds #define APN_TDI_RATE_RESOLUTION 0.00000512 #define APN_TDI_RATE_MIN 0.00000512 #define APN_TDI_RATE_MAX 0.336 #define APN_VOLTAGE_RESOLUTION 0.00439453 #define APN_SHUTTER_CLOSE_DIFF 0.00001024 #define APN_STROBE_POSITION_MIN 0.00000331 #define APN_STROBE_POSITION_MAX 0.1677 #define APN_STROBE_PERIOD_MIN 0.000000045 #define APN_STROBE_PERIOD_MAX 0.0026 #define APN_TEMP_COUNTS 4096 #define APN_TEMP_KELVIN_SCALE_OFFSET 273.16 #define APN_TEMP_SETPOINT_MIN 213 #define APN_TEMP_SETPOINT_MAX 313 #define APN_TEMP_HEATSINK_MIN 240 #define APN_TEMP_HEATSINK_MAX 340 #define APN_TEMP_SETPOINT_ZERO_POINT 2458 #define APN_TEMP_HEATSINK_ZERO_POINT 1351 #define APN_TEMP_DEGREES_PER_BIT 0.024414 #define APN_FAN_SPEED_OFF 0 #define APN_FAN_SPEED_LOW 3100 #define APN_FAN_SPEED_MEDIUM 3660 #define APN_FAN_SPEED_HIGH 4095 indi-0.5/src/apogee/ApnCamera_USB.cpp0000644000175000017500000001313710610474646015221 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnCamera_USB.cpp: implementation of the CApnCamera_USB class. #include "stdafx.h" #include "ApnCamera_USB.h" #include "ApogeeUsb.h" #include "ApogeeUsbErr.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// bool CApnCamera::InitDriver( unsigned long CamIdA, unsigned short /*CamIdB*/, unsigned long /*Option*/ ) { if ( ApnUsbOpen( (unsigned short)CamIdA ) != APN_USB_SUCCESS ) { return false; } m_CameraInterface = Apn_Interface_USB; // Before trying to initialize, perform a simple loopback test unsigned short RegData; unsigned short NewRegData; RegData = 0x5AA5; if ( Write( FPGA_REG_SCRATCH, RegData ) != APN_USB_SUCCESS ) return false; if ( Read( FPGA_REG_SCRATCH, NewRegData ) != APN_USB_SUCCESS ) return false; if ( RegData != NewRegData ) return false; RegData = 0xA55A; if ( Write( FPGA_REG_SCRATCH, RegData ) != APN_USB_SUCCESS ) return false; if ( Read( FPGA_REG_SCRATCH, NewRegData ) != APN_USB_SUCCESS ) return false; if ( RegData != NewRegData ) return false; // The loopback test was successful. Proceed with initialization. if ( InitDefaults() != 0 ) return false; return true; } bool CApnCamera::CloseDriver() { ApnUsbClose(); return true; } void CApnCamera::SetNetworkTransferMode( Apn_NetworkMode /*TransferMode*/ ) { return; } bool CApnCamera::GetImageData( unsigned short *pImageBuffer, unsigned short &Width, unsigned short &Height, unsigned long &Count ) { unsigned short Offset(0); unsigned short *pTempBuffer; long i, j; // Make sure it is okay to get the image data // The app *should* have done this on its own, but we have to make sure while ( !ImageReady() ) { Sleep( 50 ); read_ImagingStatus(); } Width = m_pvtWidth; Height = m_pvtHeight; if ( m_pvtBitsPerPixel == 16 ) Offset = 1; if ( m_pvtBitsPerPixel == 12 ) Offset = 10; Width -= Offset; // Calculate the true image width pTempBuffer = new unsigned short[(Width+Offset) * Height]; ApnUsbGetImage( pTempBuffer ); for ( i=0; i 1000 #pragma once #endif // _MSC_VER > 1000 #include "ApnSerial.h" class CApnSerial_NET : public CApnSerial { public: CApnSerial_NET(); virtual ~CApnSerial_NET(); bool InitPort( unsigned long CamIdA, unsigned short CamIdB, unsigned short SerialId ); bool ClosePort(); bool GetBaudRate( unsigned long *BaudRate ); bool SetBaudRate( unsigned long BaudRate ); bool GetFlowControl( Apn_SerialFlowControl *FlowControl ); bool SetFlowControl( Apn_SerialFlowControl FlowControl ); bool GetParity( Apn_SerialParity *Parity ); bool SetParity( Apn_SerialParity Parity ); bool Read( char *ReadBuffer, unsigned short *ReadCount ); bool Write( char *WriteBuffer, unsigned short WriteCount ); }; #endif // !defined(AFX_APNSERIAL_NET_H__F31A372D_2B82_4998_B74C_FFAD8E3EEE86__INCLUDED_) indi-0.5/src/apogee/ApnCamData.h0000644000175000017500000000652210610474640014251 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnCamData.h: interface for the CApnCamData class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_APNCAMDATA_H__32231556_A1FD_421B_94F8_295D4148E195__INCLUDED_) #define AFX_APNCAMDATA_H__32231556_A1FD_421B_94F8_295D4148E195__INCLUDED_ #define APN_MAX_HBINNING 10 #define APN_MAX_PATTERN_ENTRIES 256 typedef struct _APN_VPATTERN_FILE { unsigned short Mask; unsigned short NumElements; unsigned short *PatternData; } APN_VPATTERN_FILE; typedef struct _APN_HPATTERN_FILE { unsigned short Mask; unsigned short BinningLimit; unsigned short RefNumElements; unsigned short BinNumElements[APN_MAX_HBINNING]; unsigned short SigNumElements; unsigned short *RefPatternData; unsigned short *BinPatternData[APN_MAX_HBINNING]; unsigned short *SigPatternData; } APN_HPATTERN_FILE; class CApnCamData { public: CApnCamData(); virtual ~CApnCamData(); virtual void Initialize() = 0; char m_Sensor[20]; char m_CameraModel[20]; unsigned short m_CameraId; bool m_InterlineCCD; bool m_SupportsSerialA; bool m_SupportsSerialB; bool m_SensorTypeCCD; unsigned short m_TotalColumns; unsigned short m_ImagingColumns; unsigned short m_ClampColumns; unsigned short m_PreRoiSkipColumns; unsigned short m_PostRoiSkipColumns; unsigned short m_OverscanColumns; unsigned short m_TotalRows; unsigned short m_ImagingRows; unsigned short m_UnderscanRows; unsigned short m_OverscanRows; unsigned short m_VFlushBinning; bool m_EnableSingleRowOffset; unsigned short m_RowOffsetBinning; bool m_HFlushDisable; unsigned short m_ShutterCloseDelay; double m_PixelSizeX; double m_PixelSizeY; bool m_Color; double m_ReportedGainSixteenBit; double m_MinSuggestedExpTime; bool m_CoolingSupported; bool m_RegulatedCoolingSupported; double m_TempSetPoint; unsigned short m_TempRampRateOne; unsigned short m_TempRampRateTwo; double m_TempBackoffPoint; unsigned short m_DefaultGainTwelveBit; unsigned short m_DefaultOffsetTwelveBit; unsigned short m_DefaultRVoltage; // Pattern Files APN_VPATTERN_FILE m_VerticalPattern; APN_HPATTERN_FILE m_ClampPatternSixteen; APN_HPATTERN_FILE m_SkipPatternSixteen; APN_HPATTERN_FILE m_RoiPatternSixteen; APN_HPATTERN_FILE m_ClampPatternTwelve; APN_HPATTERN_FILE m_SkipPatternTwelve; APN_HPATTERN_FILE m_RoiPatternTwelve; private: void init_vpattern( ); void clear_vpattern( ); void init_hpattern( APN_HPATTERN_FILE *Pattern ); void clear_hpattern( APN_HPATTERN_FILE *Pattern ); }; #endif // !defined(AFX_APNCAMDATA_H__32231556_A1FD_421B_94F8_295D4148E195__INCLUDED_) indi-0.5/src/apogee/ApnUsbSys.h0000644000175000017500000000362210610474640014205 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnUsbSys.h // // // Defines common data structure(s) for sharing between application // layer and the ApUSB.sys device driver. // #if !defined(_APNUSBSYS_H__INCLUDED_) #define _APNUSBSYS_H__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define VND_ANCHOR_LOAD_INTERNAL 0xA0 #define VND_APOGEE_CMD_BASE 0xC0 #define VND_APOGEE_STATUS ( VND_APOGEE_CMD_BASE + 0x0 ) #define VND_APOGEE_CAMCON_REG ( VND_APOGEE_CMD_BASE + 0x2 ) #define VND_APOGEE_BUFCON_REG ( VND_APOGEE_CMD_BASE + 0x3 ) #define VND_APOGEE_SET_SERIAL ( VND_APOGEE_CMD_BASE + 0x4 ) #define VND_APOGEE_SERIAL ( VND_APOGEE_CMD_BASE + 0x5 ) #define VND_APOGEE_EEPROM ( VND_APOGEE_CMD_BASE + 0x6 ) #define VND_APOGEE_SOFT_RESET ( VND_APOGEE_CMD_BASE + 0x8 ) #define VND_APOGEE_GET_IMAGE ( VND_APOGEE_CMD_BASE + 0x9 ) #define VND_APOGEE_STOP_IMAGE ( VND_APOGEE_CMD_BASE + 0xA ) #define REQUEST_IN 0x1 #define REQUEST_OUT 0x0 typedef struct _APN_USB_REQUEST { unsigned char Request; unsigned char Direction; unsigned short Value; unsigned short Index; } APN_USB_REQUEST, *PAPN_USB_REQUEST; #endif // !defined(_APNUSBSYS_H__INCLUDED_) indi-0.5/src/apogee/ApnCamData_KAF6303E.h0000644000175000017500000000335210610474640015351 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF6303E.h: Interface file for the CApnCamData_KAF6303E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_KAF6303E : public CApnCamData { public: CApnCamData_KAF6303E(); virtual ~CApnCamData_KAF6303E(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_CCD4710LS3.h0000644000175000017500000000336610610474640015563 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4710LS3.h: Interface file for the CApnCamData_CCD4710LS3 class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD4710LS3 : public CApnCamData { public: CApnCamData_CCD4710LS3(); virtual ~CApnCamData_CCD4710LS3(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_KAF16801E.h0000644000175000017500000000335710610474640015442 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF16801E.h: Interface file for the CApnCamData_KAF16801E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_KAF16801E : public CApnCamData { public: CApnCamData_KAF16801E(); virtual ~CApnCamData_KAF16801E(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_KAF1001E.h0000644000175000017500000000335210610474640015337 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF1001E.h: Interface file for the CApnCamData_KAF1001E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_KAF1001E : public CApnCamData { public: CApnCamData_KAF1001E(); virtual ~CApnCamData_KAF1001E(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamera.h0000644000175000017500000002332410610474640014146 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnCamera.h: interface for the CApnCamera class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_APNCAMERA_H__CF513996_359F_4103_BBA6_2C730AE2C301__INCLUDED_) #define AFX_APNCAMERA_H__CF513996_359F_4103_BBA6_2C730AE2C301__INCLUDED_ #include "Apogee.h" #include "Apn.h" #include "FpgaRegs.h" #include "ApnCamData.h" #include "ApnCamData_CCD3011HS.h" #include "ApnCamData_CCD3011LS.h" #include "ApnCamData_CCD4240HS.h" #include "ApnCamData_CCD4240LS.h" #include "ApnCamData_CCD4710HS.h" #include "ApnCamData_CCD4710LS.h" #include "ApnCamData_CCD4720HS.h" #include "ApnCamData_CCD4720LS.h" #include "ApnCamData_CCD5520HS.h" #include "ApnCamData_CCD5520LS.h" #include "ApnCamData_CCD5710HS.h" #include "ApnCamData_CCD5710LS.h" #include "ApnCamData_CCD7700HS.h" #include "ApnCamData_CCD7700LS.h" #include "ApnCamData_KAF0261E.h" #include "ApnCamData_KAF0401E.h" #include "ApnCamData_KAF1001E.h" #include "ApnCamData_KAF1301E.h" #include "ApnCamData_KAF1401E.h" #include "ApnCamData_KAF1602E.h" #include "ApnCamData_KAF16801E.h" #include "ApnCamData_KAF3200E.h" #include "ApnCamData_KAF4202.h" #include "ApnCamData_KAF6303E.h" #include "ApnCamData_TH7899.h" #include "ApnCamData_CCD4710LS2.h" #include "ApnCamData_CCD4710LS3.h" #include "ApnCamData_CCD4710LS4.h" #include "ApnCamData_CCD4710LS5.h" class CApnCamera { public: CApnCamera(); ~CApnCamera(); bool InitDriver( unsigned long CamIdA, unsigned short CamIdB, unsigned long Option ); bool CloseDriver(); long PreStartExpose( unsigned short BitsPerPixel ); long PostStopExposure( bool DigitizeData ); bool GetImageData( unsigned short *pImageData, unsigned short &Width, unsigned short &Height, unsigned long &Count ); bool GetLineData( unsigned short *pLineBuffer, unsigned short &Size ); long Read( unsigned short reg, unsigned short& val ); long Write( unsigned short reg, unsigned short val ); long WriteMultiSRMD( unsigned short reg, unsigned short val[], unsigned short count ); long WriteMultiMRMD( unsigned short reg[], unsigned short val[], unsigned short count ); long QueryStatusRegs( unsigned short& StatusReg, unsigned short& HeatsinkTempReg, unsigned short& CcdTempReg, unsigned short& CoolerDriveReg, unsigned short& VoltageReg, unsigned short& TdiCounter, unsigned short& SequenceCounter ); void SetNetworkTransferMode( Apn_NetworkMode TransferMode ); long InitDefaults(); bool Expose( double Duration, bool Light ); bool BufferImage(char *bufferName ); bool BufferDriftScan(char *bufferName, int delay, int rowCount, int nblock , int npipe); bool StopExposure( bool DigitizeData ); bool ResetSystem(); bool PauseTimer( bool PauseState ); unsigned short GetExposurePixelsH(); unsigned short GetExposurePixelsV(); bool read_Present(); unsigned short read_FirmwareVersion(); bool read_ShutterState(); bool read_DisableShutter(); void write_DisableShutter( bool DisableShutter ); bool read_ForceShutterOpen(); void write_ForceShutterOpen( bool ForceShutterOpen ); bool read_ShutterAmpControl(); void write_ShutterAmpControl( bool ShutterAmpControl ); bool read_ExternalIoReadout(); void write_ExternalIoReadout( bool ExternalIoReadout ); bool read_FastSequence(); void write_FastSequence( bool FastSequence ); Apn_CameraMode read_CameraMode(); void write_CameraMode( Apn_CameraMode CameraMode ); void write_DataBits( Apn_Resolution BitResolution ); Apn_Status read_ImagingStatus(); Apn_LedMode read_LedMode(); void write_LedMode( Apn_LedMode LedMode ); Apn_LedState read_LedState( unsigned short LedId ); void write_LedState( unsigned short LedId, Apn_LedState LedState ); bool read_CoolerEnable(); void write_CoolerEnable( bool CoolerEnable ); Apn_CoolerStatus read_CoolerStatus(); double read_CoolerSetPoint(); void write_CoolerSetPoint( double SetPoint ); double read_CoolerBackoffPoint(); void write_CoolerBackoffPoint( double BackoffPoint ); double read_CoolerDrive(); double read_TempCCD(); double read_TempHeatsink(); Apn_FanMode read_FanMode(); void write_FanMode( Apn_FanMode FanMode ); void write_RoiBinningH( unsigned short BinningH ); void write_RoiBinningV( unsigned short BinningV ); void write_RoiPixelsV( unsigned short PixelsV ); void write_RoiStartY( unsigned short StartY ); unsigned short read_MaxBinningV(); unsigned short read_OverscanColumns(); double read_ShutterStrobePosition(); void write_ShutterStrobePosition( double Position ); double read_ShutterStrobePeriod(); void write_ShutterStrobePeriod( double Period ); double read_SequenceDelay(); void write_SequenceDelay( double Delay ); bool read_VariableSequenceDelay(); void write_VariableSequenceDelay( bool VariableSequenceDelay ); unsigned short read_ImageCount(); void write_ImageCount( unsigned short Count ); unsigned short read_SequenceCounter(); unsigned short read_TDICounter(); unsigned short read_TDIRows(); void write_TDIRows( unsigned short TdiRows ); double read_TDIRate(); void write_TDIRate( double TdiRate ); unsigned short read_IoPortAssignment(); void write_IoPortAssignment( unsigned short IoPortAssignment ); unsigned short read_IoPortDirection(); void write_IoPortDirection( unsigned short IoPortDirection ); unsigned short read_IoPortData(); void write_IoPortData( unsigned short IoPortData ); unsigned short read_TwelveBitGain(); void write_TwelveBitGain( unsigned short TwelveBitGain ); double read_InputVoltage(); long read_AvailableMemory(); double read_MaxExposureTime(); Apn_NetworkMode read_NetworkTransferMode(); void write_NetworkTransferMode( Apn_NetworkMode TransferMode ); double read_TestLedBrightness(); void write_TestLedBrightness( double TestLedBrightness ); // Public helper function bool ImageReady(); void SignalImagingDone(); // Variables Apn_Interface m_CameraInterface; CApnCamData *m_ApnSensorInfo; unsigned short m_RoiStartX, m_RoiStartY; unsigned short m_RoiPixelsH, m_RoiPixelsV; unsigned short m_RoiBinningH, m_RoiBinningV; bool m_DigitizeOverscan; Apn_Resolution m_DataBits; /* was private: */ // General helper functions long LoadVerticalPattern(); long LoadClampPattern(); long LoadSkipPattern(); long LoadRoiPattern( unsigned short Binning ); long WriteHorizontalPattern( APN_HPATTERN_FILE *Pattern, unsigned short reg, unsigned short binning ); long InitTwelveBitAD(); long WriteTwelveBitOffset(); void UpdateGeneralStatus(); // Internal private variables bool m_ResetVerticalArrays; // Camera state variables Apn_CameraMode m_pvtCameraMode; Apn_NetworkMode m_pvtNetworkTransferMode; unsigned short m_pvtImageCount; unsigned short m_pvtTDIRows; double m_pvtTDIRate; double m_pvtSequenceDelay; double m_pvtShutterStrobePosition; double m_pvtShutterStrobePeriod; unsigned short m_pvtExposurePixelsH, m_pvtExposurePixelsV; unsigned short m_pvtTwelveBitGain; Apn_LedMode m_pvtLedMode; Apn_LedState m_pvtLedStateA; Apn_LedState m_pvtLedStateB; double m_pvtTestLedBrightness; bool m_pvtCoolerEnable; Apn_FanMode m_pvtFanMode; double m_pvtCoolerBackoffPoint; Apn_CoolerStatus m_pvtCoolerStatus; Apn_Status m_pvtImagingStatus; bool m_pvtShutterState; bool m_pvtImageInProgress; bool m_pvtImageReady; unsigned short m_pvtStatusReg; double m_pvtCoolerDrive; double m_pvtCurrentHeatsinkTemp; double m_pvtCurrentCcdTemp; double m_pvtInputVoltage; unsigned short m_pvtIoPortAssignment; unsigned short m_pvtIoPortDirection; /* added USB/NET specifics */ unsigned short m_pvtBitsPerPixel; unsigned short m_pvtWidth; unsigned short m_pvtHeight; /* added sensor data mirrors */ bool sensorInfo(); char m_Sensor[20]; char m_CameraModel[20]; unsigned short m_CameraId; bool m_InterlineCCD; bool m_SupportsSerialA; bool m_SupportsSerialB; bool m_SensorTypeCCD; unsigned short m_TotalColumns; unsigned short m_ImagingColumns; unsigned short m_ClampColumns; unsigned short m_PreRoiSkipColumns; unsigned short m_PostRoiSkipColumns; unsigned short m_OverscanColumns; unsigned short m_TotalRows; unsigned short m_ImagingRows; unsigned short m_UnderscanRows; unsigned short m_OverscanRows; unsigned short m_VFlushBinning; bool m_HFlushDisable; unsigned short m_ShutterCloseDelay; double m_PixelSizeX; double m_PixelSizeY; bool m_Color; // double m_ReportedGainTwelveBit; double m_ReportedGainSixteenBit; double m_MinSuggestedExpTime; // unsigned short m_TempRegRate; unsigned short m_TempRampRateOne; unsigned short m_TempRampRateTwo; unsigned short m_DefaultGainTwelveBit; unsigned short m_DefaultOffsetTwelveBit; unsigned short m_DefaultRVoltage; }; #endif // !defined(AFX_APNCAMERA_H__CF513996_359F_4103_BBA6_2C730AE2C301__INCLUDED_) indi-0.5/src/apogee/ApnCamData_CCD4710LS3.cpp0000644000175000017500000005556010610474646016127 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4710LS3.cpp: Implementation file for the CApnCamData_CCD4710LS3 class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD4710LS3.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD4710LS3::CApnCamData_CCD4710LS3() { } CApnCamData_CCD4710LS3::~CApnCamData_CCD4710LS3() { } void CApnCamData_CCD4710LS3::Initialize() { strcpy( m_Sensor, "CCD4710LS3" ); strcpy( m_CameraModel, "47" ); m_CameraId = 13; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1072; m_ImagingColumns = 1024; m_ClampColumns = 24; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 24; m_TotalRows = 1027; m_ImagingRows = 1024; m_UnderscanRows = 3; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 13; m_PixelSizeY = 13; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD4710LS3::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 247; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_CCD3011LS.cpp0000644000175000017500000005572610610474646016041 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD3011LS.cpp: Implementation file for the CApnCamData_CCD3011LS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD3011LS.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD3011LS::CApnCamData_CCD3011LS() { } CApnCamData_CCD3011LS::~CApnCamData_CCD3011LS() { } void CApnCamData_CCD3011LS::Initialize() { strcpy( m_Sensor, "CCD3011LS" ); strcpy( m_CameraModel, "30" ); m_CameraId = 20; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1040; m_ImagingColumns = 1024; m_ClampColumns = 8; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 8; m_TotalRows = 256; m_ImagingRows = 256; m_UnderscanRows = 0; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 26; m_PixelSizeY = 26; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD3011LS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 247; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/reb1100.cpp0000644000175000017500000001253210610474646013731 0ustar jrjr/*************************************************************************** reb1100.cpp - REB1100 communication class ------------------- begin : Thu Mar 27 2003 copyright : (C) 2003 by Igor Izyumin email : igor@mlug.missouri.edu ***************************************************************************/ /*************************************************************************** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **********************************************************************/ #include "reb1100.h" REB1100::REB1100(){ struct usb_bus *bus; struct usb_device *dev; usb_init(); usb_find_busses(); usb_find_devices(); char string[256]; int found = 0; /* find ebook device */ for(bus = usb_busses; bus && !found; bus = bus->next) { for(dev = bus->devices; dev && !found; dev = dev->next) { if (dev->descriptor.idVendor == 0x993 && dev->descriptor.idProduct == 0x1) { hDevice = usb_open(dev); cerr << "Found eBook. Attempting to open... "; found = 1; if (hDevice) { // if (!usb_get_string_simple(hDevice, dev->descriptor.iSerialNumber, string, sizeof(string))) throw DevOpenError(); cerr << "Success.\n"; // cerr << "Serial number: " << string << endl; } else throw DevOpenError(); } } } if (!found) throw DevNotFoundError(); if (!usb_set_configuration(hDevice, 0x0)) throw DevOpenError(); if (!usb_claim_interface(hDevice, 0x1)) throw DevOpenError(); memTarget = INTERNAL; } REB1100::~REB1100(){ usb_release_interface(hDevice, 0x0); usb_close(hDevice); } void REB1100::getFile(string filename, string &data) { long flength = filename.length(); char buf[4096]; char zeros[4] = {0, 0, 0, 0}; int ret; string request; // first four bytes are the length of the filename // (low-endian) char *byte = reinterpret_cast(&flength); request += *byte; byte++; request += *byte; byte++; request += *byte; byte++; request += *byte; // the rest is the filename request += filename; // send a USB control request to tell the device what file we want char *temp; temp = new char[request.length()]; request.copy(temp, string::npos); ret = usb_control_msg(hDevice, 0x42, 0x01, 0x00, 0x00, temp, request.length(), 300); if (ret == -1) throw DevControlError(); delete temp; temp = NULL; // read the return code ret = usb_control_msg(hDevice, 0xc2, 0x02, 0x00, 0x00, zeros, 4, 300); if (ret == -1) throw DevControlError(); // read file from pipe do { ret = usb_bulk_read(hDevice, 2, buf, 4096, 1000); if (ret == -1) throw DevReadError(); for(int i = 0; i < ret; i++) { data += buf[i]; } } while(ret == 4096); } void REB1100::sendFile(string filename, string &data) { string prefix = ""; if (memTarget == MEMCARD) { // prefix with \SM\ when sending to memory card prefix = "\\SM\\"; } filename = prefix + filename; long flength = data.length(); long fnlength = filename.length(); // prepare initial request string request; // first four bytes are the length of the file // (low-endian) char *byte = reinterpret_cast(&flength); request += *byte; byte++; request += *byte; byte++; request += *byte; byte++; request += *byte; // next four bytes are the length of the filename // (low-endian) byte = reinterpret_cast(&fnlength); request += *byte; byte++; request += *byte; byte++; request += *byte; byte++; request += *byte; // append filename request += filename; // send message to device int ret; char *temp; temp = new char[request.length()]; request.copy(temp, string::npos); ret = usb_control_msg(hDevice, 0x42, 0x00, 0x00, 0x00, temp, request.length(), 3000); delete temp; temp = NULL; if (ret == -1) throw DevControlError(); // read from device and check for error char temp2[4] = {0, 0, 0, 0}; ret = usb_control_msg(hDevice, 0xc2, 0x03, 0x00, 0x00, temp2, 4, 3000); if (ret == -1) throw DevControlError(); if (temp2[0] || temp2[1] || temp2[2] || temp2[3]) throw DevControlError(); // now start bulk writing to the device string buf; int n, offset = 0; char *temp3; do { buf = data.substr(offset, 4096); n = buf.length(); if (buf.length() > 0) { temp3 = new char[buf.length()]; buf.copy(temp3, string::npos); // cout << "Sending block (" << n << " bytes)\n"; ret = usb_bulk_write(hDevice, 2, temp3, n, 3000); if (ret == -1) throw DevWriteError(); delete temp3; temp3 = NULL; offset += 4096; } } while(offset + 1 < data.length()); // send empty packet to signify end of file ret = usb_bulk_write(hDevice, 2, 0, 0, 3000); if (ret == -1) throw DevWriteError(); } void REB1100::setTarget(bool target) { memTarget = target; } indi-0.5/src/apogee/ApnCamData_CCD4710LS2.cpp0000644000175000017500000005575310610474646016132 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4710LS2.cpp: Implementation file for the CApnCamData_CCD4710LS2 class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD4710LS2.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD4710LS2::CApnCamData_CCD4710LS2() { } CApnCamData_CCD4710LS2::~CApnCamData_CCD4710LS2() { } void CApnCamData_CCD4710LS2::Initialize() { strcpy( m_Sensor, "CCD4710LS2" ); strcpy( m_CameraModel, "47" ); m_CameraId = 12; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1072; m_ImagingColumns = 1024; m_ClampColumns = 24; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 24; m_TotalRows = 1027; m_ImagingRows = 1024; m_UnderscanRows = 3; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 13; m_PixelSizeY = 13; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD4710LS2::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 247; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamera_NET.h0000644000175000017500000000471710610474640014661 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnCamera_NET.h: interface for the CApnCamera_NET class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_APNCAMERA_NET_H__D6F0E3AB_536C_4937_9E2B_DCF682D0DD31__INCLUDED_) #define AFX_APNCAMERA_NET_H__D6F0E3AB_536C_4937_9E2B_DCF682D0DD31__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "ApnCamera.h" class CApnCamera_NET : public CApnCamera { private: unsigned short m_pvtBitsPerPixel; unsigned short m_pvtWidth; unsigned short m_pvtHeight; public: CApnCamera_NET(); virtual ~CApnCamera_NET(); bool InitDriver( unsigned long CamIdA, unsigned short CamIdB, unsigned long Option ); bool CloseDriver(); long PreStartExpose( unsigned short BitsPerPixel ); long PostStopExposure( bool DigitizeData ); bool GetImageData( unsigned short *pImageData, unsigned short &Width, unsigned short &Height, unsigned long &Count ); bool GetLineData( unsigned short *pLineBuffer, unsigned short &Size ); long Read( unsigned short reg, unsigned short& val ); long Write( unsigned short reg, unsigned short val ); long WriteMultiSRMD( unsigned short reg, unsigned short val[], unsigned short count ); long WriteMultiMRMD( unsigned short reg[], unsigned short val[], unsigned short count ); long QueryStatusRegs( unsigned short& StatusReg, unsigned short& HeatsinkTempReg, unsigned short& CcdTempReg, unsigned short& CoolerDriveReg, unsigned short& VoltageReg, unsigned short& TdiCounter, unsigned short& SequenceCounter ); }; #endif // !defined(AFX_APNCAMERA_NET_H__D6F0E3AB_536C_4937_9E2B_DCF682D0DD31__INCLUDED_) indi-0.5/src/apogee/ApnCamData_CCD5520HS.h0000644000175000017500000000335710610474640015474 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD5520HS.h: Interface file for the CApnCamData_CCD5520HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD5520HS : public CApnCamData { public: CApnCamData_CCD5520HS(); virtual ~CApnCamData_CCD5520HS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_CCD5710HS.h0000644000175000017500000000453010610474640015467 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /*************************************************************************** * * * 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. * * * ***************************************************************************/ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD5710HS.h: Interface file for the CApnCamData_CCD5710HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD5710HS : public CApnCamData { public: CApnCamData_CCD5710HS(); virtual ~CApnCamData_CCD5710HS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/CameraIO_PCI.cpp0000644000175000017500000002420410610474646014771 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // CameraIO_PCI.cpp: implementation of the CCameraIO_PCI class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include #include "ApogeeLinux.h" // This defines the IOCTL constants. #include "CameraIO_PCI.h" #include "time.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CCameraIO_PCI::CCameraIO_PCI() { m_IsWDM = false; m_hDriver = NULL; } CCameraIO_PCI::~CCameraIO_PCI() { CloseDriver(); } long CCameraIO_PCI::Read(unsigned short reg, unsigned short& val) { BOOLEAN IoctlResult; ULONG ReturnedLength; USHORT RegNumber; USHORT ReadBuffer; switch ( reg ) { case Reg_Command: RegNumber = RegPCI_CommandRead; break; case Reg_Timer: RegNumber = RegPCI_TimerRead; break; case Reg_VBinning: RegNumber = RegPCI_VBinningRead; break; case Reg_AICCounter: RegNumber = RegPCI_AICCounterRead; break; case Reg_TempSetPoint: RegNumber = RegPCI_TempSetPointRead; break; case Reg_PixelCounter: RegNumber = RegPCI_PixelCounterRead; break; case Reg_LineCounter: RegNumber = RegPCI_LineCounterRead; break; case Reg_BICCounter: RegNumber = RegPCI_BICCounterRead; break; case Reg_ImageData: RegNumber = RegPCI_ImageData; break; case Reg_TempData: RegNumber = RegPCI_TempData; break; case Reg_Status: RegNumber = RegPCI_Status; break; case Reg_CommandReadback: RegNumber = RegPCI_CommandReadback; break; default: _ASSERT( false ); // Application program bug val = 0; return 0; } if ( m_IsWDM ) { IoctlResult = DeviceIoControl( m_hDriver, // Handle to device IOCTL_WDM_READ_PCI_USHORT, // IO Control code for Read &RegNumber, // Buffer to driver. sizeof(RegNumber), // Length of buffer in bytes. &ReadBuffer, // Buffer from driver. sizeof(ReadBuffer), // Length of buffer in bytes. &ReturnedLength, // Bytes placed in DataBuffer. NULL // NULL means wait till op. completes. ); } else { IoctlResult = DeviceIoControl( m_hDriver, // Handle to device IOCTL_GPD_READ_PCI_USHORT, // IO Control code for Read &RegNumber, // Buffer to driver. sizeof(RegNumber), // Length of buffer in bytes. &ReadBuffer, // Buffer from driver. sizeof(ReadBuffer), // Length of buffer in bytes. &ReturnedLength, // Bytes placed in DataBuffer. NULL // NULL means wait till op. completes. ); } if ( (ReturnedLength != 2) || (IoctlResult == false) ) { return 1; } val = ReadBuffer; return 0; } long CCameraIO_PCI::Write(unsigned short reg, unsigned short val) { BOOLEAN IoctlResult; ULONG InBuffer[2]; ULONG ReturnedLength; USHORT RegNumber; switch ( reg ) { case Reg_Command: RegNumber = RegPCI_Command; break; case Reg_Timer: RegNumber = RegPCI_Timer; break; case Reg_VBinning: RegNumber = RegPCI_VBinning; break; case Reg_AICCounter: RegNumber = RegPCI_AICCounter; break; case Reg_TempSetPoint: RegNumber = RegPCI_TempSetPoint; break; case Reg_PixelCounter: RegNumber = RegPCI_PixelCounter; break; case Reg_LineCounter: RegNumber = RegPCI_LineCounter; break; case Reg_BICCounter: RegNumber = RegPCI_BICCounter; break; default: _ASSERT ( false ); return 0; } InBuffer[0] = RegNumber; InBuffer[1] = val; // Do an I/O write if ( m_IsWDM ) { IoctlResult = DeviceIoControl( m_hDriver, // Handle to device IOCTL_WDM_WRITE_PCI_USHORT, // IO Control code for Write &InBuffer, // Buffer to driver. Holds register/data. sizeof ( InBuffer ), // Length of buffer in bytes. NULL, // Buffer from driver. Not used. 0, // Length of buffer in bytes. &ReturnedLength, // Bytes placed in outbuf. Should be 0. NULL // NULL means wait till I/O completes. ); } else { IoctlResult = DeviceIoControl( m_hDriver, // Handle to device IOCTL_GPD_WRITE_PCI_USHORT, // IO Control code for Write &InBuffer, // Buffer to driver. Holds register/data. sizeof ( InBuffer ), // Length of buffer in bytes. NULL, // Buffer from driver. Not used. 0, // Length of buffer in bytes. &ReturnedLength, // Bytes placed in outbuf. Should be 0. NULL // NULL means wait till I/O completes. ); } if ( (IoctlResult == false) || (ReturnedLength != 0) ) { return 1; } return 0; } long CCameraIO_PCI::ReadLine( long SkipPixels, long Pixels, unsigned short* pLineBuffer ) { BOOLEAN IoctlResult; ULONG InBuffer[3]; ULONG ReturnedLength; // Number of bytes returned in output buffer ULONG NumBytes; USHORT* DataBuffer; InBuffer[0] = RegPCI_ImageData; InBuffer[1] = SkipPixels; // Data points to skip InBuffer[2] = Pixels; // Data points to keep NumBytes = Pixels * sizeof( unsigned short ); DataBuffer = pLineBuffer; if ( !m_TDI ) { ///////////////////////////////////// // Clock out the line m_RegShadow[ Reg_Command ] |= RegBit_StartNextLine; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_StartNextLine; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// } if ( m_IsWDM ) { IoctlResult = DeviceIoControl( m_hDriver, // Handle to device IOCTL_WDM_READ_PCI_LINE, // IO Control code for Read line &InBuffer, // Buffer to driver. sizeof(InBuffer), // Length of buffer in bytes. DataBuffer, // Buffer from driver. NumBytes, // Length of buffer in bytes. &ReturnedLength, // Bytes placed in DataBuffer. NULL // NULL means wait till op. completes. ); } else { IoctlResult = DeviceIoControl( m_hDriver, // Handle to device IOCTL_GPD_READ_PCI_LINE, // IO Control code for Read line &InBuffer, // Buffer to driver. sizeof(InBuffer), // Length of buffer in bytes. DataBuffer, // Buffer from driver. NumBytes, // Length of buffer in bytes. &ReturnedLength, // Bytes placed in DataBuffer. NULL // NULL means wait till op. completes. ); } if ( (ReturnedLength != NumBytes) || (!IoctlResult) ) { return 1; // Failed to get line info } ///////////////////////////////////// // Assert done reading line m_RegShadow[ Reg_Command ] |= RegBit_DoneReading; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_DoneReading; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// if ( !m_TDI ) { ///////////////////////////////////// // Wait until camera is done clock_t StopTime = clock() + CLOCKS_PER_SEC; // wait at most one second while ( true ) { unsigned short val = 0; Read( Reg_Status, val ); if ( ( val & RegBit_LineDone ) != 0 ) break;// Line done if ( clock() > StopTime ) return 1; // Timed out } } return 0; } bool CCameraIO_PCI::InitDriver() { OSVERSIONINFO OSVerInfo; BOOLEAN IsPostWin98OS; BOOLEAN IsNT4OS; BOOLEAN IsPostNT4OS; IsPostWin98OS = false; IsNT4OS = false; IsPostNT4OS = false; CloseDriver(); OSVerInfo.dwOSVersionInfoSize = sizeof ( OSVERSIONINFO ); GetVersionEx( &OSVerInfo ); // Check for Win9x versions. Pre-Win98 is unsupported. if ( OSVerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) { // Check for pre-Win98 if (( OSVerInfo.dwMajorVersion < 4 ) || (( OSVerInfo.dwMajorVersion == 4 ) && ( OSVerInfo.dwMinorVersion == 0 ))) { return false; // Pre-Win98 not supported } else { IsPostWin98OS = true; } } else if ( OSVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) { // Check if NT4 if ( OSVerInfo.dwMajorVersion < 4 ) { // NT3.51 is not supported. Right?? return false; } else if (OSVerInfo.dwMajorVersion == 4 ) { IsNT4OS = true; } else if (OSVerInfo.dwMajorVersion > 4 ) { IsPostNT4OS = true; } } if ( IsNT4OS ) { ULONG ReturnedLength; ULONG DataBuffer[2]; // Open the driver m_hDriver = CreateFile( "\\\\.\\ApogeeIO", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if ( m_hDriver == INVALID_HANDLE_VALUE ) { m_hDriver = NULL; return false; } BOOL IoctlResult = DeviceIoControl( m_hDriver, // Handle to device IOCTL_PCI_BUS_SCAN, // IO Control code for PCI Bus Scan NULL, // Buffer to driver. 0, // Length of buffer in bytes. DataBuffer, // Buffer from driver. sizeof( DataBuffer ), // Length of buffer in bytes. &ReturnedLength, // Bytes placed in DataBuffer. NULL // NULL means wait till op. completes. ); if ( (!IoctlResult) || (ReturnedLength != sizeof(DataBuffer)) ) { return false; } } else if ( IsPostWin98OS || IsPostNT4OS ) { // Should be okay to use the WDM driver. Note that the kernel // driver will actually check to see if WDM services are available // Open the driver m_hDriver = CreateFile( "\\\\.\\ApPCI", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if ( m_hDriver == INVALID_HANDLE_VALUE ) { m_hDriver = NULL; return false; } // Safe to assume we're using the WDM driver at this point. m_IsWDM = true; } return true; } void CCameraIO_PCI::CloseDriver() { // Close the driver if it already exists if ( m_hDriver != NULL ) { CloseHandle ( m_hDriver ); } m_hDriver = NULL; } indi-0.5/src/apogee/ApnCamData_KAF0401E.cpp0000644000175000017500000006104610610474646015707 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF0401E.cpp: Implementation file for the CApnCamData_KAF0401E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_KAF0401E.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_KAF0401E::CApnCamData_KAF0401E() { } CApnCamData_KAF0401E::~CApnCamData_KAF0401E() { } void CApnCamData_KAF0401E::Initialize() { strcpy( m_Sensor, "KAF0401E" ); strcpy( m_CameraModel, "1" ); m_CameraId = 0; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 796; m_ImagingColumns = 768; m_ClampColumns = 14; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 14; m_TotalRows = 520; m_ImagingRows = 512; m_UnderscanRows = 4; m_OverscanRows = 4; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 9; m_PixelSizeY = 9; m_Color = false; m_ReportedGainSixteenBit = 1.5; m_MinSuggestedExpTime = 10.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 100; m_DefaultOffsetTwelveBit = 255; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_KAF0401E::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 71; unsigned short Pattern[NumElements] = { 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_KAF4202.cpp0000644000175000017500000006103010610474646015576 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF4202.cpp: Implementation file for the CApnCamData_KAF4202 class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_KAF4202.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_KAF4202::CApnCamData_KAF4202() { } CApnCamData_KAF4202::~CApnCamData_KAF4202() { } void CApnCamData_KAF4202::Initialize() { strcpy( m_Sensor, "KAF4202" ); strcpy( m_CameraModel, "4" ); m_CameraId = 7; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 2060; m_ImagingColumns = 2032; m_ClampColumns = 25; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 3; m_TotalRows = 2048; m_ImagingRows = 2044; m_UnderscanRows = 2; m_OverscanRows = 2; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 9; m_PixelSizeY = 9; m_Color = false; m_ReportedGainSixteenBit = 1.5; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 100; m_DefaultOffsetTwelveBit = 255; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_KAF4202::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 71; unsigned short Pattern[NumElements] = { 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/CameraIO_Linux.cpp0000644000175000017500000011073610610474646015463 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // CameraIO.cpp: implementation of the CCameraIO class. // ////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #define HANDLE int #define DWORD long #define _ASSERT assert #define REALTIME_PRIORITY_CLASS 1 #define GetCurrentProcess getpid #define LOBYTE(x) ((x) & 0xff) #define HIBYTE(x) ((x >> 8) & 0xff) #define MIRQ1 0x21 #define MIRQ2 0xA1 #include "time.h" //#include "tcl.h" //#include "ccd.h" #include "CameraIO_Linux.h" #include "ApogeeLinux.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CCameraIO::CCameraIO() { InitDefaults(); m_TDI = false; m_Shutter = false; m_FilterPosition = 0; m_FilterStepPos = 0; m_WaitingforImage = false; m_WaitingforLine = false; m_WaitingforTrigger = false; m_Status = Camera_Status_Idle; m_CoolerStatus = Camera_CoolerStatus_Off; m_ExposureBinX = 0; m_ExposureBinY = 0; m_ExposureStartX = 0; m_ExposureStartY = 0; m_ExposureNumX = 0; m_ExposureNumY = 0; m_ExposureColumns = 0; m_ExposureRows = 0; m_ExposureSkipC = 0; m_ExposureSkipR = 0; m_ExposureHFlush = 0; m_ExposureVFlush = 0; m_ExposureBIC = 0; m_ExposureBIR = 0; m_ExposureAIC = 0; m_ExposureRemainingLines = 0; m_ExposureAIR = 0; m_RegShadow[ Reg_Command ] = 0; m_RegShadow[ Reg_Timer ] = 0; m_RegShadow[ Reg_VBinning ] = 0; m_RegShadow[ Reg_AICCounter ] = 0; m_RegShadow[ Reg_TempSetPoint ] = 0; m_RegShadow[ Reg_PixelCounter ] = 0; m_RegShadow[ Reg_LineCounter ] = 0; m_RegShadow[ Reg_BICCounter ] = 0; m_FastShutterBits_Mode = 0; m_FastShutterBits_Test = 0; m_IRQMask = 0; saveIRQS = 0; } CCameraIO::~CCameraIO() { //::close(fileHandle); close(fileHandle); } //////////////////////////////////////////////////////////// // System methods int GetPriorityClass ( HANDLE /*hProcess*/ ) { int i; i = sched_getscheduler(0); return(i); } int SetPriorityClass ( HANDLE /*hProcess*/, int hPriority) { int i; sched_param p; if (hPriority) { i = sched_setscheduler(0,SCHED_RR,&p); } else { i = sched_setscheduler(0,SCHED_OTHER,&p); } return(i); } void Sleep (int hTime) { timespec t; t.tv_sec= 0; t.tv_nsec = hTime*1000000; // nanosleep(&t); } void ATLTRACE (char * /*msg*/) { } void CCameraIO::Reset() { unsigned short val = 0; Read( Reg_CommandReadback, val ); // Take snapshot of currrent status m_RegShadow[ Reg_Command ] = val; // remember it in our write shadow // In case these were left on, turn them off m_RegShadow[ Reg_Command ] &= ~RegBit_FIFOCache; // set bit to 0 m_RegShadow[ Reg_Command ] &= ~RegBit_TDIMode; // set bit to 0 m_RegShadow[ Reg_Command ] |= RegBit_ResetSystem; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_ResetSystem; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_WaitingforImage = false; m_WaitingforLine = false; m_WaitingforTrigger = false; } void CCameraIO::AuxOutput( unsigned char val ) { // clear bits to 0 m_RegShadow[ Reg_TempSetPoint ] &= ~( RegBitMask_PortControl << RegBitShift_PortControl ); // set our new bits m_RegShadow[ Reg_TempSetPoint ] |= val << RegBitShift_PortControl; Write( Reg_TempSetPoint, m_RegShadow[ Reg_TempSetPoint ] ); } // Input reg is from 0 to 7, val is any 16 bit number void CCameraIO::RegWrite( short reg, unsigned short val ) { Write( reg, val ); // Update our shadow register switch ( reg ) { case Reg_Command: m_RegShadow[ Reg_Command ] = val; break; case Reg_Timer: m_RegShadow[ Reg_Timer ] = val; break; case Reg_VBinning: m_RegShadow[ Reg_VBinning ] = val; break; case Reg_AICCounter: m_RegShadow[ Reg_AICCounter ] = val; break; case Reg_TempSetPoint: m_RegShadow[ Reg_TempSetPoint ] = val; break; case Reg_PixelCounter: m_RegShadow[ Reg_PixelCounter ] = val; break; case Reg_LineCounter: m_RegShadow[ Reg_LineCounter ] = val; break; case Reg_BICCounter: m_RegShadow[ Reg_BICCounter ] = val; break; default: _ASSERT( false ); // application program bug } } // Input reg is from 8 to 12, returned val is any 16 bit number void CCameraIO::RegRead( short reg, unsigned short& val ) { Read( reg, val ); } bool CCameraIO::FilterHome() { HANDLE hProcess(0); DWORD Class(0); if ( m_HighPriority ) { // Store current process class and priority hProcess = GetCurrentProcess(); Class = GetPriorityClass ( hProcess ); SetPriorityClass ( hProcess, REALTIME_PRIORITY_CLASS ); } // Find the home position m_FilterPosition = 0; int Safety = 0; for (int I = 0; I < NUM_POSITIONS * NUM_STEPS_PER_FILTER * 2; I++) { // Advance the filter one step m_FilterStepPos += 1; if (m_FilterStepPos >= NUM_STEPS) m_FilterStepPos = 0; unsigned char Step = Steps[ m_FilterStepPos ]; AuxOutput( Step ); Sleep ( STEP_DELAY ); // Check for strobe unsigned short val = 0; Read( Reg_Status, val ); if ( val & RegBit_GotTrigger ) { // Cycle all the way around if it's on the first time if (I < NUM_STEPS_PER_FILTER) { if (++Safety > NUM_STEPS_PER_FILTER * 2) { // Restore normal priority if ( m_HighPriority ) SetPriorityClass ( hProcess, Class ); return false; } I = 0; continue; } // Continue cycling until we get clear of the opto mirror for (int J = 0; J < NUM_STEPS_PER_FILTER; J++) { // Advance the filter one step m_FilterStepPos += 1; if (m_FilterStepPos >= NUM_STEPS) m_FilterStepPos = 0; unsigned char Step = Steps[ m_FilterStepPos ]; AuxOutput( Step ); Sleep ( STEP_DELAY ); val = 0; Read( Reg_Status, val ); if ( val & RegBit_GotTrigger ) { Sleep ( 10 ); val = 0; Read( Reg_Status, val ); if ( val & RegBit_GotTrigger ) { // Restore normal priority if ( m_HighPriority ) SetPriorityClass ( hProcess, Class ); return true; } } } // Restore normal priority if ( m_HighPriority ) SetPriorityClass ( hProcess, Class ); return true; } } // Restore normal priority if ( m_HighPriority ) SetPriorityClass ( hProcess, Class ); return false; } void CCameraIO::FilterSet( short Slot ) { // Determine how far we have to move int Pos = Slot - m_FilterPosition; if (Pos < 0) Pos += NUM_POSITIONS; HANDLE hProcess(0); DWORD Class(0); if ( m_HighPriority ) { // Store current process class and priority hProcess = GetCurrentProcess(); Class = GetPriorityClass ( hProcess ); SetPriorityClass ( hProcess, REALTIME_PRIORITY_CLASS ); } for (int I = 0; I < Pos; I++) { // Advance one position for (int J = 0; J < NUM_STEPS_PER_FILTER; J++) { m_FilterStepPos += 1; if (m_FilterStepPos >= NUM_STEPS) m_FilterStepPos = 0; unsigned char Step = Steps[ m_FilterStepPos ]; AuxOutput( Step ); Sleep ( STEP_DELAY ); } } if ( m_HighPriority ) SetPriorityClass ( hProcess, Class ); m_FilterPosition = Slot; } //////////////////////////////////////////////////////////// // Normal exposure methods bool CCameraIO::Expose( double Duration, bool Light ) { if ( !m_TDI && ( Duration < m_MinExposure || Duration > m_MaxExposure ) ) return false; // Validate all input variables if ( m_Columns < 1 || m_Columns > MAXCOLUMNS ) return false; m_ExposureColumns = m_Columns; if ( m_Rows < 1 || m_Rows > MAXROWS ) return false; m_ExposureRows = m_Rows; if ( m_SkipC < 0 ) return false; m_ExposureSkipC = m_SkipC; if ( m_SkipR < 0 ) return false; m_ExposureSkipR = m_SkipR; if ( m_HFlush < 1 || m_HFlush > MAXHBIN ) return false; m_ExposureHFlush = m_HFlush; if ( m_VFlush < 1 || m_VFlush > MAXVBIN ) return false; m_ExposureVFlush = m_VFlush; if ( m_BIC < 1 || m_BIC > MAXCOLUMNS ) return false; m_ExposureBIC = m_BIC; if ( m_BIR < 1 || m_BIR > MAXROWS ) return false; m_ExposureBIR = m_BIR; // Validate all input variables if ( m_BinX < 1 || m_BinX > MAXHBIN ) return false; m_ExposureBinX = m_BinX; if ( m_StartX < 0 || m_StartX >= MAXCOLUMNS ) return false; m_ExposureStartX = m_StartX; if ( m_NumX < 1 || m_NumX * m_BinX > m_ImgColumns ) return false; m_ExposureNumX = m_NumX; // Calculate BIC, RawPixelCount, AIC unsigned short BIC = m_ExposureBIC + m_ExposureStartX; // unbinned columns unsigned short RawPixelCount = m_ExposureNumX * m_ExposureBinX; m_ExposureAIC = m_ExposureColumns - BIC - RawPixelCount; // unbinned columns if ( m_BinY < 1 || m_BinY > MAXVBIN ) return false; m_ExposureBinY = m_BinY; unsigned short VBin(0), row_offset(0); if ( m_TDI ) { // row_offset is the drift time in milliseconds when in TDI mode row_offset = (unsigned short) (Duration * 1000 + 0.5); Duration = 0.0; } else { if ( m_StartY < 0 || m_StartX >= MAXROWS ) return false; m_ExposureStartY = m_StartY; if ( m_NumY < 1 || m_NumY * m_BinY > m_ImgRows ) return false; m_ExposureNumY = m_NumY; unsigned short BIR = m_ExposureBIR + m_ExposureStartY; // unbinned rows if ( BIR >= MAXROWS ) return false; m_ExposureAIR = m_ExposureRows - BIR - m_ExposureNumY * m_ExposureBinY; // unbinned rows if ( m_VFlush > BIR ) { VBin = BIR; m_ExposureRemainingLines = 0; } else { VBin = m_VFlush; m_ExposureRemainingLines = BIR % VBin; // unbinned rows } row_offset = BIR - m_ExposureRemainingLines; // unbinned rows } StopFlushing(); Reset(); LoadColumnLayout( m_ExposureAIC, BIC, (unsigned short) m_ExposureNumX + m_ExposureSkipC ); LoadTimerAndBinning( Duration, (unsigned short) m_ExposureHFlush, VBin ); LoadLineCounter( row_offset ); if ( m_TDI ) { // Turn on TDI m_RegShadow[ Reg_Command ] |= RegBit_TDIMode; // set bit to 1 // Disable FIFO cache m_RegShadow[ Reg_Command ] &= ~RegBit_FIFOCache; // set bit to 0 // Set shutter override if ( Light ) m_RegShadow[ Reg_Command ] |= RegBit_ShutterOverride; // set bit to 1 else m_RegShadow[ Reg_Command ] &= ~RegBit_ShutterOverride; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); // Update our status m_Shutter = Light; m_WaitingforTrigger = false; m_WaitingforLine = false; } else { // Set shutter if ( Light ) m_RegShadow[ Reg_Command ] |= RegBit_ShutterEnable; // set bit to 1 else m_RegShadow[ Reg_Command ] &= ~RegBit_ShutterEnable; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); // Update our status unsigned short val = 0; Read( Reg_CommandReadback, val ); if ( val & RegBit_ShutterOverride ) m_Shutter = true; else m_Shutter = Light; if ( ( val & RegBit_TriggerEnable ) ) m_WaitingforTrigger = true; else m_WaitingforTrigger = false; // Start the exposure m_RegShadow[ Reg_Command ] |= RegBit_StartTimer; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_StartTimer; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_WaitingforImage = true; } return true; } /*bool CCameraIO::BufferImage(char *bufferName ) { unsigned short *pImageData; bool status; short cols,rows,hbin,vbin; short xSize, ySize; cols = m_NumX*m_BinX; rows = m_NumY*m_BinY; hbin = m_BinX; vbin = m_BinY; pImageData = (unsigned short *)CCD_locate_buffer(bufferName, 2 , cols, rows, hbin, vbin ); if (pImageData == NULL) { return 0; } status = GetImage(pImageData, xSize, ySize); return status; }*/ bool CCameraIO::GetImage( unsigned short* pImageData, short& xSize, short& ySize ) { int i; unsigned short BIC = m_ExposureBIC + m_ExposureStartX; // Update internal variables in case application did not poll read_Status m_WaitingforTrigger = false; m_WaitingforLine = false; if ( m_WaitingforImage ) { // In case application did not poll read_Status m_WaitingforImage = false; ///////////////////////////////////// // Wait until camera is done flushing clock_t StopTime = clock() + long( m_Timeout * CLOCKS_PER_SEC ); // wait at most m_Timeout seconds while ( true ) { unsigned short val = 0; Read( Reg_Status, val ); if ( ( val & RegBit_FrameDone ) != 0 ) break; if ( clock() > StopTime ) return false; // Timed out } } // MaskIrqs(); ///////////////////////////////////// // Update our internal status unsigned short val = 0; Read( Reg_CommandReadback, val ); if ( !( val & RegBit_ShutterOverride ) ) m_Shutter = false; StopFlushing(); LoadColumnLayout( m_ExposureAIC, BIC, (unsigned short) m_ExposureNumX + m_ExposureSkipC ); if ( m_ExposureRemainingLines > 0 ) { LoadTimerAndBinning( 0.0, m_ExposureHFlush, m_ExposureRemainingLines ); ///////////////////////////////////// // Clock out the remaining lines m_RegShadow[ Reg_Command ] |= RegBit_StartNextLine; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_StartNextLine; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// ///////////////////////////////////// // Wait until camera is done clocking clock_t StopTime = clock() + CLOCKS_PER_SEC; // wait at most one second while ( true ) { unsigned short val = 0; Read( Reg_Status, val ); if ( ( val & RegBit_LineDone ) != 0 ) break; // Line done if ( clock() > StopTime ) { Flush(); return false; // Timed out, no image available } } } LoadTimerAndBinning( 0.0, m_ExposureBinX, m_ExposureBinY ); bool ret = false; // assume failure // NB Application must have allocated enough memory or else !!! if ( pImageData != NULL ) { HANDLE hProcess(0); DWORD Class(0); if ( m_HighPriority ) { // Store current process class and priority hProcess = GetCurrentProcess(); Class = GetPriorityClass ( hProcess ); SetPriorityClass ( hProcess, REALTIME_PRIORITY_CLASS ); } m_RegShadow[ Reg_Command ] |= RegBit_FIFOCache; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); long XPixels = long( m_ExposureNumX ); long SkipPixels = long( m_ExposureSkipC ); for (i = 0; i < m_ExposureSkipR; i++) { if ( ReadLine( SkipPixels, XPixels, pImageData ) ) break; } if ( i == m_ExposureSkipR ) { // We have skipped all the lines long YPixels = long( m_ExposureNumY ); unsigned short* pLineBuffer = pImageData; for (i = 0; i < YPixels; i++) { if ( ReadLine( SkipPixels, XPixels, pLineBuffer ) ) break; pLineBuffer += XPixels; } if ( i == YPixels ) ret = true; // We have read all the lines } m_RegShadow[ Reg_Command ] &= ~RegBit_FIFOCache; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); //Restore priority if ( m_HighPriority ) SetPriorityClass ( hProcess, Class ); } // UnmaskIrqs(); if ( ret ) { // We were successful Flush( m_ExposureAIR ); // flush after imaging rows xSize = m_ExposureNumX; ySize = m_ExposureNumY; if ( m_DataBits == 16 ) { // Take care of two's complement converters unsigned short *Ptr = pImageData; short *Ptr2 = (short *) pImageData; long Size = m_ExposureNumX * m_ExposureNumY; for (i = 0; i < Size; i++) { *Ptr++ = (unsigned short) *Ptr2++ + 32768 ; } } } else { // Something went wrong xSize = 0; ySize = 0; } Flush(); // start normal flushing return ret; } //////////////////////////////////////////////////////////// // Drift scan methods bool CCameraIO::DigitizeLine() { ///////////////////////////////////// // All of these are done just in case // since they are called in Expose() StopFlushing(); unsigned short BIC = m_ExposureBIC + m_ExposureStartX; LoadColumnLayout( m_ExposureAIC, BIC, (unsigned short) m_ExposureNumX + m_ExposureSkipC ); LoadTimerAndBinning( 0.0, m_ExposureBinX, m_ExposureBinY ); // Disable FIFO cache m_RegShadow[ Reg_Command ] &= ~RegBit_FIFOCache; // set bit to 0 ///////////////////////////////////// ///////////////////////////////////// // Clock out the line m_RegShadow[ Reg_Command ] |= RegBit_StartNextLine; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_StartNextLine; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// m_WaitingforLine = true; return true; } bool CCameraIO::GetLine( unsigned short* pLineData, short& xSize ) { int i; if ( m_WaitingforLine ) { // In case application did not poll read_Status m_WaitingforLine = false; ///////////////////////////////////// // Wait until camera is done clocking clock_t StopTime = clock() + CLOCKS_PER_SEC; // wait at most one second while ( true ) { unsigned short val = 0; Read( Reg_Status, val ); if ( ( val & RegBit_LineDone ) != 0 ) break; // Line done if ( clock() > StopTime ) { Flush(); return false; // Timed out, no line available } } } bool ret = false; // assume failure // MaskIrqs(); // NB Application must have allocated enough memory or else !!! if ( pLineData != NULL ) { HANDLE hProcess(0); DWORD Class(0); if ( m_HighPriority ) { // Store current process class and priority hProcess = GetCurrentProcess(); Class = GetPriorityClass ( hProcess ); SetPriorityClass ( hProcess, REALTIME_PRIORITY_CLASS ); } long XPixels = long( m_ExposureNumX ); long SkipPixels = long( m_ExposureSkipC ); if ( ReadLine( SkipPixels, XPixels, pLineData ) ) { // Something went wrong xSize = 0; ret = false; } else { xSize = m_ExposureNumX; if ( m_DataBits == 16 ) { // Take care of two's complement converters unsigned short *Ptr = pLineData; short *Ptr2 = (short *) pLineData; long Size = m_ExposureNumX; for (i = 0; i < Size; i++) { *Ptr++ = (unsigned short) *Ptr2++ + 32768 ; } } ret = true; } //Restore priority if ( m_HighPriority ) SetPriorityClass ( hProcess, Class ); } // UnmaskIrqs(); return ret; } //////////////////////////////////////////////////////////// // Easy to use methods bool CCameraIO::Snap( double Duration, bool Light, unsigned short* pImageData, short& xSize, short& ySize ) { // NB This also demonstrates how an application might use the // Expose and GetImage routines. bool ret = Expose( Duration, Light ); if ( !ret ) return false; if ( m_WaitingforTrigger ) { Camera_Status stat; while ( true ) { // This will wait forever if no trigger happens stat = read_Status(); if ( stat == Camera_Status_Exposing ) break; Sleep( 220 ); // don't bog down the CPU while polling } m_WaitingforTrigger = false; } // Only wait a time slightly greater than the duration of the exposure // but enough for the BIR to flush out clock_t StopTime = clock() + long( ( 1.2 * Duration + m_Timeout ) * CLOCKS_PER_SEC ); while ( true ) { Camera_Status stat = read_Status(); if ( stat == Camera_Status_ImageReady ) break; if ( clock() > StopTime ) return false; // Timed out, no image available Sleep( 220 ); // don't bog down the CPU while polling } return GetImage( pImageData, xSize, ySize ); } //////////////////////////////////////////////////////////// // Camera Settings Camera_Status CCameraIO::read_Status() { unsigned short val = 0; Read( Reg_Status, val ); if ( val & RegBit_Exposing ) //11.0 { ATLTRACE( "Exposing\r\n" ); m_WaitingforTrigger = false; m_Status = Camera_Status_Exposing; } else if ( m_WaitingforTrigger ) m_Status = Camera_Status_Waiting; else if ( m_WaitingforImage && ( val & RegBit_FrameDone ) ) //11.11 { ATLTRACE( "ImageReady\r\n" ); m_WaitingforImage = false; m_Status = Camera_Status_ImageReady; } else if ( m_WaitingforLine && ( val & RegBit_LineDone ) ) //11.1 { ATLTRACE( "LineReady\r\n" ); m_WaitingforLine = false; m_Status = Camera_Status_LineReady; } else if ( m_WaitingforImage || m_WaitingforLine ) { ATLTRACE( "Flushing\r\n" ); m_Status = Camera_Status_Flushing; } else m_Status = Camera_Status_Idle; return m_Status; } bool CCameraIO::read_Present() { // This does not work on all cameras /* m_RegShadow[ Reg_BICCounter ] |= RegBit_LoopbackTest; // set bit to 1 Write( Reg_BICCounter, m_RegShadow[ Reg_BICCounter ] ); bool FailedLoopback = false; unsigned short val = 0; Read( Reg_Status, val ); if ( !( val & RegBit_LoopbackTest ) ) FailedLoopback = true; m_RegShadow[ Reg_BICCounter ] &= ~RegBit_LoopbackTest; // clear bit to 0 Write( Reg_BICCounter, m_RegShadow[ Reg_BICCounter ] ); Read( Reg_Status, val ); if ( val & RegBit_LoopbackTest ) FailedLoopback = true; */ unsigned short val = 0; Read( Reg_CommandReadback, val ); // Take snapshot of currrent status m_RegShadow[ Reg_Command ] = val; // remember it in our write shadow bool TriggerEnabled = ( val & RegBit_TriggerEnable ) != 0; m_RegShadow[ Reg_Command ] &= ~RegBit_TriggerEnable;// clear bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); Read( Reg_CommandReadback, val ); // get currrent status if ( val & RegBit_TriggerEnable ) return false; m_RegShadow[ Reg_Command ] |= RegBit_TriggerEnable; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); Read( Reg_CommandReadback, val ); // get currrent status if ( !(val & RegBit_TriggerEnable) ) return false; m_RegShadow[ Reg_Command ] &= ~RegBit_TriggerEnable;// clear bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); Read( Reg_CommandReadback, val ); // get currrent status if ( val & RegBit_TriggerEnable ) return false; if ( TriggerEnabled ) { // Set it back the way it was m_RegShadow[ Reg_Command ] |= RegBit_TriggerEnable; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); } return true; } bool CCameraIO::read_Shutter() { unsigned short regval = 0; Read( Reg_Status, regval ); if ( !( regval & RegBit_Exposing ) ) { // We are not exposing, but might have finnshed an exposure // and have not called GetImage yet, so update our internal variable regval = 0; Read( Reg_CommandReadback, regval ); if ( !( regval & RegBit_ShutterOverride ) ) // The shutter override is not on, so the shutter must be closed m_Shutter = false; } return m_Shutter; } bool CCameraIO::read_ForceShutterOpen() { unsigned short val = 0; Read( Reg_CommandReadback, val ); return ( ( val & RegBit_ShutterOverride ) != 0 ); } void CCameraIO::write_ForceShutterOpen( bool val ) { if ( val ) { m_RegShadow[ Reg_Command ] |= RegBit_ShutterOverride; // set bit to 1 m_Shutter = true; // shutter will open immediately now matter what is going on } else { m_RegShadow[ Reg_Command ] &= ~RegBit_ShutterOverride; // clear bit to 0 unsigned short regval = 0; Read( Reg_Status, regval ); if ( ( regval & RegBit_Exposing ) ) { // Shutter will remain open if a Light frame is being taken // however if a dark frame was being exposed while the // override was on or the override is turned on during the exposure // and now is turned off (dumb idea but some app might do it!) // we must update our variable since the shutter will close // when override gets turned off below regval = 0; Read( Reg_CommandReadback, regval ); if ( !( regval & RegBit_ShutterEnable ) ) m_Shutter = false; } else { // Not currently exposing so shutter will close // once override is turned off, update our variable m_Shutter = false; } } Write( Reg_Command, m_RegShadow[ Reg_Command ] ); } bool CCameraIO::read_LongCable() { unsigned short val = 0; Read( Reg_CommandReadback, val ); return ( ( val & RegBit_CableLength ) != 0 ); } void CCameraIO::write_Shutter( bool val ) { if ( val ) m_RegShadow[ Reg_Command ] |= RegBit_ShutterEnable; // set bit to 1 else m_RegShadow[ Reg_Command ] &= ~RegBit_ShutterEnable; // clear bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); } void CCameraIO::write_LongCable( bool val ) { if ( val ) m_RegShadow[ Reg_Command ] |= RegBit_CableLength; // set bit to 1 else m_RegShadow[ Reg_Command ] &= ~RegBit_CableLength; // clear bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); } short CCameraIO::read_Mode() { return ( ( m_RegShadow[ Reg_LineCounter ] >> RegBitShift_Mode ) & RegBitMask_Mode ); } void CCameraIO::write_Mode( short val ) { // clear bits to 0 m_RegShadow[ Reg_LineCounter ] &= ~( RegBitMask_Mode << RegBitShift_Mode ); // set our new bits m_RegShadow[ Reg_LineCounter ] |= ( (unsigned short) val & RegBitMask_Mode ) << RegBitShift_Mode; Write( Reg_LineCounter, m_RegShadow[ Reg_LineCounter ] ); } short CCameraIO::read_TestBits() { return ( ( m_RegShadow[ Reg_BICCounter ] >> RegBitShift_Test ) & RegBitMask_Test ); } void CCameraIO::write_TestBits( short val ) { // clear bits to 0 m_RegShadow[ Reg_BICCounter ] &= ~( RegBitMask_Test << RegBitShift_Test ); // set our new bits m_RegShadow[ Reg_BICCounter ] |= ( (unsigned short) val & RegBitMask_Test ) << RegBitShift_Test; Write( Reg_BICCounter, m_RegShadow[ Reg_BICCounter ] ); } short CCameraIO::read_Test2Bits() { return ( ( m_RegShadow[ Reg_AICCounter ] >> RegBitShift_Test2 ) & RegBitMask_Test2 ); } void CCameraIO::write_Test2Bits( short val ) { // clear bits to 0 m_RegShadow[ Reg_AICCounter ] &= ~( RegBitMask_Test2 << RegBitShift_Test2 ); // set our new bits m_RegShadow[ Reg_AICCounter ] |= ( (unsigned short) val & RegBitMask_Test2 ) << RegBitShift_Test2; Write( Reg_AICCounter, m_RegShadow[ Reg_AICCounter ] ); } bool CCameraIO::read_FastReadout() { unsigned short val = 0; Read( Reg_CommandReadback , val ); return ( ( val & RegBit_Focus ) != 0 ); } void CCameraIO::write_FastReadout( bool val ) { if ( val ) m_RegShadow[ Reg_Command ] |= RegBit_Focus; // set bit to 1 else m_RegShadow[ Reg_Command ] &= ~RegBit_Focus; // clear bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); } bool CCameraIO::read_UseTrigger() { unsigned short val = 0; Read( Reg_CommandReadback , val ); return ( ( val & RegBit_TriggerEnable ) != 0 ); } void CCameraIO::write_UseTrigger( bool val ) { if ( val ) m_RegShadow[ Reg_Command ] |= RegBit_TriggerEnable; // set bit to 1 else m_RegShadow[ Reg_Command ] &= ~RegBit_TriggerEnable; // clear bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); } //////////////////////////////////////////////////////////// // Cooler Settings double CCameraIO::read_CoolerSetPoint() { // Get the setting from the shadow registers short DACunits = short( ( m_RegShadow[ Reg_TempSetPoint ] >> RegBitShift_TempSetPoint ) & RegBitMask_TempSetPoint ); return ( DACunits - m_TempCalibration ) / m_TempScale; } void CCameraIO::write_CoolerSetPoint( double val ) { // clear bits to 0 m_RegShadow[ Reg_TempSetPoint ] &= ~( RegBitMask_TempSetPoint << RegBitShift_TempSetPoint ); // Calculate DAC units from degrees Celcius unsigned short DACunits = (unsigned )( m_TempScale * val ) + m_TempCalibration ; // set our new bits m_RegShadow[ Reg_TempSetPoint ] |= ( DACunits & RegBitMask_TempSetPoint ) << RegBitShift_TempSetPoint; Write( Reg_TempSetPoint, m_RegShadow[ Reg_TempSetPoint ] ); } Camera_CoolerStatus CCameraIO::read_CoolerStatus() { unsigned short val = 0; Read( Reg_CommandReadback, val ); if ( val & RegBit_CoolerEnable ) //12.15 { unsigned short val2 = 0; Read( Reg_Status, val2 ); if ( val & RegBit_CoolerShutdown ) //12.8 { if ( val2 & RegBit_ShutdownComplete ) //11.6 m_CoolerStatus = Camera_CoolerStatus_AtAmbient; else m_CoolerStatus = Camera_CoolerStatus_RampingToAmbient; } else { if ( val2 & RegBit_TempAtMax ) //11.5 m_CoolerStatus = Camera_CoolerStatus_AtMax; else if ( val2 & RegBit_TempAtMin ) //11.4 m_CoolerStatus = Camera_CoolerStatus_AtMin; else if ( val2 & RegBit_TempAtSetPoint ) //11.7 m_CoolerStatus = Camera_CoolerStatus_AtSetPoint; // Check against last known cooler status else if ( m_CoolerStatus == Camera_CoolerStatus_AtSetPoint ) m_CoolerStatus = Camera_CoolerStatus_Correcting; else m_CoolerStatus = Camera_CoolerStatus_RampingToSetPoint; } } else m_CoolerStatus = Camera_CoolerStatus_Off; return m_CoolerStatus; } Camera_CoolerMode CCameraIO::read_CoolerMode() { unsigned short val = 0; Read( Reg_CommandReadback, val ); if ( val & RegBit_CoolerShutdown ) return Camera_CoolerMode_Shutdown; else if ( val & RegBit_CoolerEnable ) return Camera_CoolerMode_On; else return Camera_CoolerMode_Off; } void CCameraIO::write_CoolerMode( Camera_CoolerMode val ) { switch ( val ) { case Camera_CoolerMode_Off: m_RegShadow[ Reg_Command ] &= ~( RegBit_CoolerEnable ); // clear bit to 0 m_RegShadow[ Reg_Command ] &= ~( RegBit_CoolerShutdown ); // clear bit to 0 break; case Camera_CoolerMode_On: m_RegShadow[ Reg_Command ] |= RegBit_CoolerEnable; // set bit to 1 break; case Camera_CoolerMode_Shutdown: m_RegShadow[ Reg_Command ] |= RegBit_CoolerShutdown; // set bit to 1 break; default: return; } Write( Reg_Command, m_RegShadow[ Reg_Command ] ); } double CCameraIO::read_Temperature() { if ( m_TempScale == 0.0 ) return 0.0; else { unsigned short val = 0; Read( Reg_TempData, val ); short DACunits = short( ( val >> RegBitShift_TempData ) & RegBitMask_TempData ); return ( DACunits - m_TempCalibration ) / m_TempScale; } } // Load line counter void CCameraIO::LoadLineCounter( unsigned short rows ) { ///////////////////////////////////// // Write out Line_Count - in unbinned rows // clear bits to 0 m_RegShadow[ Reg_LineCounter ] &= ~( RegBitMask_LineCounter << RegBitShift_LineCounter ); // set our new bits m_RegShadow[ Reg_LineCounter ] |= ( rows & RegBitMask_LineCounter ) << RegBitShift_LineCounter; Write( Reg_LineCounter, m_RegShadow[ Reg_LineCounter ] ); ///////////////////////////////////// } // Load AIC, BIC and pixel count into registers void CCameraIO::LoadColumnLayout( unsigned short aic, unsigned short bic, unsigned short pixels ) { ///////////////////////////////////// // Write out AIC - in unbinned columns // clear bits to 0 m_RegShadow[ Reg_AICCounter ] &= ~( RegBitMask_AICCounter << RegBitShift_AICCounter ); // set our new bits m_RegShadow[ Reg_AICCounter ] |= ( aic & RegBitMask_AICCounter ) << RegBitShift_AICCounter; Write( Reg_AICCounter, m_RegShadow[ Reg_AICCounter ] ); ///////////////////////////////////// ///////////////////////////////////// // Write out BIC - in unbinned columns // clear bits to 0 m_RegShadow[ Reg_BICCounter ] &= ~( RegBitMask_BICCounter << RegBitShift_BICCounter ); // set our new bits m_RegShadow[ Reg_BICCounter ] |= ( bic & RegBitMask_BICCounter ) << RegBitShift_BICCounter; Write( Reg_BICCounter, m_RegShadow[ Reg_BICCounter ] ); ///////////////////////////////////// ///////////////////////////////////// // Write out pixel count - in binned columns // clear bits to 0 m_RegShadow[ Reg_PixelCounter ] &= ~( RegBitMask_PixelCounter << RegBitShift_PixelCounter ); // set our new bits m_RegShadow[ Reg_PixelCounter ] |= ( pixels & RegBitMask_PixelCounter ) << RegBitShift_PixelCounter; Write( Reg_PixelCounter, m_RegShadow[ Reg_PixelCounter ] ); ///////////////////////////////////// } // Load timer, vertical binning and horizontal binning in to registers // If Duration parameter is 0 the current timer value will be retained. // The VBin and HBin parameters are one based, the HBin value // is converted to zero base inside this routine. void CCameraIO::LoadTimerAndBinning( double Duration, unsigned short HBin, unsigned short VBin ) { ///////////////////////////////////// // Write out HBin for flushing // clear bits to 0 m_RegShadow[ Reg_PixelCounter ] &= ~( RegBitMask_HBinning << RegBitShift_HBinning ); // set our new bits m_RegShadow[ Reg_PixelCounter ] |= ( ( HBin - 1 ) & RegBitMask_HBinning ) << RegBitShift_HBinning; Write( Reg_PixelCounter, m_RegShadow[ Reg_PixelCounter ] ); ///////////////////////////////////// ///////////////////////////////////// // Write out VBin for flushing and Timer if ( Duration > 0.0 ) { if ( Duration > m_MaxExposure ) Duration = m_MaxExposure; long valTimer; if ( m_FastShutter && Duration <= 1048.575 ) { // Automatically switch to high precision mode valTimer = long( ( Duration * 1000 ) + 0.5 ); m_RegShadow[ Reg_LineCounter ] |= ( m_FastShutterBits_Mode & RegBitMask_Mode ) << RegBitShift_Mode; m_RegShadow[ Reg_BICCounter ] |= ( m_FastShutterBits_Test & RegBitMask_Test ) << RegBitShift_Test; } else { valTimer = long( ( Duration * 100 ) + 0.5 ); if ( m_FastShutter ) { // Disable high precision mode m_RegShadow[ Reg_LineCounter ] &= ~( m_FastShutterBits_Mode & RegBitMask_Mode ) << RegBitShift_Mode; m_RegShadow[ Reg_BICCounter ] &= ~( m_FastShutterBits_Test & RegBitMask_Test ) << RegBitShift_Test; } } if ( m_FastShutter ) { Write( Reg_LineCounter, m_RegShadow[ Reg_LineCounter ] ); Write( Reg_BICCounter, m_RegShadow[ Reg_BICCounter ] ); } if ( valTimer <= 0 ) valTimer = 1; // Safety since firmware doesn't like zero unsigned short valTimerLow = (unsigned short) (valTimer & 0x0000FFFF); unsigned short valTimerHigh = (unsigned short) (valTimer >> 16); // Enable loading of timer values m_RegShadow[ Reg_Command ] |= RegBit_TimerLoad; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); // clear bits to 0 m_RegShadow[ Reg_Timer ] = 0; // set our new bits m_RegShadow[ Reg_Timer ] |= ( valTimerLow & RegBitMask_Timer )<< RegBitShift_Timer; Write( Reg_Timer, m_RegShadow[ Reg_Timer ] ); // clear bits to 0 m_RegShadow[ Reg_VBinning ] = 0; // set our new bits m_RegShadow[ Reg_VBinning ] |= ( VBin & RegBitMask_VBinning ) << RegBitShift_VBinning; m_RegShadow[ Reg_VBinning ] |= ( valTimerHigh & RegBitMask_Timer2 ) << RegBitShift_Timer2; Write( Reg_VBinning, m_RegShadow[ Reg_VBinning ] ); // Disable loading of timer values m_RegShadow[ Reg_Command ] &= ~RegBit_TimerLoad; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// } else { // clear bits to 0 m_RegShadow[ Reg_VBinning ] &= ~( RegBitMask_VBinning << RegBitShift_VBinning ); // set our new bits m_RegShadow[ Reg_VBinning ] |= ( VBin & RegBitMask_VBinning ) << RegBitShift_VBinning; Write( Reg_VBinning, m_RegShadow[ Reg_VBinning ] ); } } // Start flushing the entire CCD (rows = -1) or a specific number or rows void CCameraIO::Flush( short Rows ) { if ( Rows == 0 ) return; unsigned short AIC = (unsigned short) ( m_Columns - m_BIC - m_ImgColumns ); unsigned short Pixels = (unsigned short) ( m_ImgColumns / m_HFlush ); if ( m_ImgColumns % m_HFlush > 0 ) Pixels++; // round up if necessary LoadColumnLayout( AIC, (unsigned short) m_BIC, Pixels ); LoadTimerAndBinning( 0.0, m_HFlush, m_VFlush ); if ( Rows > 0 ) { LoadLineCounter( (unsigned short) Rows ); StartFlushing(); ///////////////////////////////////// // Wait until camera is done flushing clock_t StopTime = clock() + long( m_Timeout * CLOCKS_PER_SEC ); // wait at most m_Timeout seconds while ( true ) { unsigned short val = 0; Read( Reg_Status, val ); if ( ( val & RegBit_FrameDone ) != 0 ) break; if ( clock() > StopTime ) break; // Timed out } } else { LoadLineCounter( (unsigned short) m_ImgRows ); StartFlushing(); } } void CCameraIO::StartFlushing() { ///////////////////////////////////// // Start flushing m_RegShadow[ Reg_Command ] |= RegBit_StartFlushing; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_StartFlushing;// set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// } void CCameraIO::StopFlushing() { ///////////////////////////////////// // Stop flushing m_RegShadow[ Reg_Command ] |= RegBit_StopFlushing; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_StopFlushing; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// } indi-0.5/src/apogee/ApnCamData_CCD4720LS.h0000644000175000017500000000335710610474640015501 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4720LS.h: Interface file for the CApnCamData_CCD4720LS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD4720LS : public CApnCamData { public: CApnCamData_CCD4720LS(); virtual ~CApnCamData_CCD4720LS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/CameraIO_LinuxPCI.cpp0000644000175000017500000002623010610474646016012 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // CameraIO.cpp: implementation of the CCameraIO class. // ////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #define HANDLE int #define FALSE 0 #define DWORD long #define _ASSERT assert #define REALTIME_PRIORITY_CLASS 1 #define GetCurrentProcess getpid #define LOBYTE(x) ((x) & 0xff) #define HIBYTE(x) ((x >> 8) & 0xff) #define MIRQ1 0x21 #define MIRQ2 0xA1 #include "time.h" //#include "tcl.h" //#include "ccd.h" #include "CameraIO_Linux.h" #include "ApogeeLinux.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// void CCameraIO::InitDefaults() { //////////////////////////////////////////////////////////// // Camera Settings m_HighPriority = true; m_PPRepeat = 1; m_DataBits = 16; m_FastShutter = false; m_MaxBinX = 8; m_MaxBinY = 63; m_MaxExposure = 10485.75; m_MinExposure = 0.01; m_GuiderRelays = false; m_Timeout = 2.0; //////////////////////////////////////////////////////////// // Cooler Settings m_TempControl = true; m_TempCalibration = 160; m_TempScale = 2.1; //////////////////////////////////////////////////////////// // Exposure Settings m_BinX = 1; m_BinY = 1; m_StartX = 0; m_StartY = 0; m_NumX = 1; m_NumY = 1; //////////////////////////////////////////////////////////// // Geometry Settings m_Columns = 0; m_Rows = 0; m_SkipC = 0; m_SkipR = 0; m_HFlush = 1; m_VFlush = 1; m_BIC = 4; m_BIR = 4; m_ImgColumns = 0; m_ImgRows = 0; //////////////////////////////////////////////////////////// // CCD Settings memset( m_Sensor, 0, 256 ); m_Color = false; m_Noise = 0.0; m_Gain = 0.0; m_PixelXSize = 0.0; m_PixelYSize = 0.0; //////////////////////////////////////////////////////////// // Internal variables fileHandle = 0; m_RegisterOffset = 0; m_Interface = Camera_Interface_PCI; m_SensorType = Camera_SensorType_CCD; } bool CCameraIO::InitDriver(unsigned short camnum) { char deviceName[64]; sprintf(deviceName,"%s%d",APOGEE_PCI_DEVICE,camnum); fileHandle = ::open(deviceName,O_RDONLY); if (fileHandle == -1) return false; return true; } long CCameraIO::Write( unsigned short reg, unsigned short val ) { int status; unsigned short RegNumber; struct apIOparam request; switch ( reg ) { case Reg_Command: RegNumber = RegPCI_Command; break; case Reg_Timer: RegNumber = RegPCI_Timer; break; case Reg_VBinning: RegNumber = RegPCI_VBinning; break; case Reg_AICCounter: RegNumber = RegPCI_AICCounter; break; case Reg_TempSetPoint: RegNumber = RegPCI_TempSetPoint; break; case Reg_PixelCounter: RegNumber = RegPCI_PixelCounter; break; case Reg_LineCounter: RegNumber = RegPCI_LineCounter; break; case Reg_BICCounter: RegNumber = RegPCI_BICCounter; break; default: _ASSERT ( false ); return 0; } request.reg = RegNumber; request.param1=(int)val; status=ioctl(fileHandle,APPCI_WRITE_USHORT,(unsigned long)&request); return 0; } long CCameraIO::Read( unsigned short reg, unsigned short& val ) { int retval, status; struct apIOparam request; unsigned short RegNumber; switch ( reg ) { case Reg_Command: RegNumber = RegPCI_CommandRead; break; case Reg_Timer: RegNumber = RegPCI_TimerRead; break; case Reg_VBinning: RegNumber = RegPCI_VBinningRead; break; case Reg_AICCounter: RegNumber = RegPCI_AICCounterRead; break; case Reg_TempSetPoint: RegNumber = RegPCI_TempSetPointRead; break; case Reg_PixelCounter: RegNumber = RegPCI_PixelCounterRead; break; case Reg_LineCounter: RegNumber = RegPCI_LineCounterRead; break; case Reg_BICCounter: RegNumber = RegPCI_BICCounterRead; break; case Reg_ImageData: RegNumber = RegPCI_ImageData; break; case Reg_TempData: RegNumber = RegPCI_TempData; break; case Reg_Status: RegNumber = RegPCI_Status; break; case Reg_CommandReadback: RegNumber = RegPCI_CommandReadback; break; default: assert( 1 ); // application program bug val = 0; return 0; } request.reg = RegNumber; request.param1=(unsigned long)&retval; status=ioctl(fileHandle,APPCI_READ_USHORT,(unsigned long)&request); val = (unsigned short)retval; return 0; } // Returns 0 if successful, 1 if Line_Done poll timed out. long CCameraIO::ReadLine( long SkipPixels, long Pixels,unsigned short* pLineBuffer ) { int j; int retval, status; struct apIOparam request; if ( !m_TDI ) { ///////////////////////////////////// // Clock out the line m_RegShadow[ Reg_Command ] |= RegBit_StartNextLine; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_StartNextLine; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// } request.reg = RegPCI_ImageData; request.param1=(unsigned long)&retval; for (j = 0; j < SkipPixels; j++) { status=ioctl(fileHandle,APPCI_READ_USHORT,(unsigned long)&request); } for (j = 0; j < Pixels; j++) { status=ioctl(fileHandle,APPCI_READ_USHORT,(unsigned long)&request); *pLineBuffer++ = (unsigned short)retval; } ///////////////////////////////////// // Assert done reading line m_RegShadow[ Reg_Command ] |= RegBit_DoneReading; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_DoneReading; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// if ( !m_TDI ) { ///////////////////////////////////// // Wait until camera is done clock_t StopTime = clock() + CLOCKS_PER_SEC; // wait at most one second while ( true ) { unsigned short val = 0; Read( Reg_Status, val ); if ( ( val & RegBit_LineDone ) != 0 ) break;// Line done if ( clock() > StopTime ) return 1; // Timed out } } return 0; } long CCameraIO::ReadImage( unsigned short* pImageBuffer ) { m_RegShadow[ Reg_Command ] |= RegBit_FIFOCache; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); long XEnd = long( m_ExposureNumX ); long SkipC = long( m_ExposureSkipC ); for (long i = 0; i < m_ExposureSkipR; i++) { if( InternalReadLine( false, SkipC, XEnd, NULL ) ) return 1; } long YEnd = long( m_ExposureNumY ); unsigned short* pLineBuffer = pImageBuffer; for (long i = 0; i < YEnd; i++) { if ( InternalReadLine( true, SkipC, XEnd, pLineBuffer ) ) return 1; pLineBuffer += XEnd; } m_RegShadow[ Reg_Command ] &= !RegBit_FIFOCache; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); return 0; } // Returns 0 if successful, 1 if Line_Done poll timed out. long CCameraIO::InternalReadLine( bool KeepData, long SkipC, long XEnd, unsigned short* pLineBuffer ) { struct apIOparam request; int retval, status; ///////////////////////////////////// // Clock out the line m_RegShadow[ Reg_Command ] |= RegBit_StartNextLine; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= !RegBit_StartNextLine; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// request.reg = RegPCI_ImageData; request.param1=(unsigned long)&retval; for (long j = 0; j < SkipC; j++) status=ioctl(fileHandle,APPCI_READ_USHORT,(unsigned long)&request); if ( KeepData ) { for (long j = 0; j < XEnd; j++) { status=ioctl(fileHandle,APPCI_READ_USHORT,(unsigned long)&request); *pLineBuffer++ = (unsigned short)retval; } } else { for (long j = 0; j < XEnd; j++) status=ioctl(fileHandle,APPCI_READ_USHORT,(unsigned long)&request); } ///////////////////////////////////// // Assert done reading line m_RegShadow[ Reg_Command ] |= RegBit_DoneReading; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= !RegBit_DoneReading; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// ///////////////////////////////////// // Wait until camera is done clocking clock_t StopTime = clock() + CLOCKS_PER_SEC; // wait at most one second while ( true ) { unsigned short val = 0; Read( Reg_Status, val ); if ( ( val & RegBit_LineDone ) != 0 ) break;// Line done clock_t CurrentTime = clock(); if ( CurrentTime > StopTime ) return 1; // Timed out } return 0; } indi-0.5/src/apogee/ApnCamData_KAF1401E.cpp0000644000175000017500000006105410610474646015707 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF1401E.cpp: Implementation file for the CApnCamData_KAF1401E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_KAF1401E.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_KAF1401E::CApnCamData_KAF1401E() { } CApnCamData_KAF1401E::~CApnCamData_KAF1401E() { } void CApnCamData_KAF1401E::Initialize() { strcpy( m_Sensor, "KAF1401E" ); strcpy( m_CameraModel, "14" ); m_CameraId = 4; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1348; m_ImagingColumns = 1320; m_ClampColumns = 26; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 2; m_TotalRows = 1037; m_ImagingRows = 1035; m_UnderscanRows = 1; m_OverscanRows = 1; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 6.8; m_PixelSizeY = 6.8; m_Color = false; m_ReportedGainSixteenBit = 1; m_MinSuggestedExpTime = 10.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 100; m_DefaultOffsetTwelveBit = 255; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_KAF1401E::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 71; unsigned short Pattern[NumElements] = { 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_CCD5710LS.h0000644000175000017500000000335710610474640015501 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD5710LS.h: Interface file for the CApnCamData_CCD5710LS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD5710LS : public CApnCamData { public: CApnCamData_CCD5710LS(); virtual ~CApnCamData_CCD5710LS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_CCD4710LS4.h0000644000175000017500000000336610610474640015564 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4710LS4.h: Interface file for the CApnCamData_CCD4710LS4 class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD4710LS4 : public CApnCamData { public: CApnCamData_CCD4710LS4(); virtual ~CApnCamData_CCD4710LS4(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_KAF1401E.h0000644000175000017500000000335210610474640015343 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF1401E.h: Interface file for the CApnCamData_KAF1401E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_KAF1401E : public CApnCamData { public: CApnCamData_KAF1401E(); virtual ~CApnCamData_KAF1401E(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/Makefile.am0000644000175000017500000000247610605175650014212 0ustar jrjrINCLUDES = METASOURCES = AUTO if HAVE_LIBUSB libapogee_target = libapogee_USB.la endif if LINUX apogee_targets = libapogee_ISA.la libapogee_PCI.la libapogee_PPI.la $(libapogee_target) endif noinst_LTLIBRARIES = $(apogee_targets) libapogee_ISA_la_SOURCES = CameraIO_Linux.cpp CameraIO_LinuxISA.cpp libapogee_PCI_la_SOURCES = CameraIO_Linux.cpp CameraIO_LinuxPCI.cpp libapogee_PPI_la_SOURCES = CameraIO_Linux.cpp CameraIO_LinuxPPI.cpp libapogee_USB_la_SOURCES = ApnCamData.cpp ApnCamData_CCD3011HS.cpp ApnCamData_CCD3011LS.cpp ApnCamData_CCD4240HS.cpp ApnCamData_CCD4240LS.cpp ApnCamData_CCD4710HS.cpp ApnCamData_CCD4710LS.cpp ApnCamData_CCD4710LS2.cpp ApnCamData_CCD4710LS3.cpp ApnCamData_CCD4710LS4.cpp ApnCamData_CCD4710LS5.cpp ApnCamData_CCD4720HS.cpp ApnCamData_CCD4720LS.cpp ApnCamData_CCD5520HS.cpp ApnCamData_CCD5520LS.cpp ApnCamData_CCD5710HS.cpp ApnCamData_CCD5710LS.cpp ApnCamData_CCD7700HS.cpp ApnCamData_CCD7700LS.cpp ApnCamData_KAF0261E.cpp ApnCamData_KAF0401E.cpp ApnCamData_KAF1001E.cpp ApnCamData_KAF1301E.cpp ApnCamData_KAF1401E.cpp ApnCamData_KAF3200E.cpp ApnCamData_KAF4202.cpp ApnCamData_KAF1602E.cpp ApnCamData_KAF16801E.cpp ApnCamData_KAF6303E.cpp ApnCamData_TH7899.cpp ApnCamTable.cpp ApnCamera.cpp ApnCamera_USB.cpp ApnCamera_Linux.cpp ApogeeUsbLinux.cpp libapogee_USB_la_LADD = -lusb KDE_OPTIONS = nofinal indi-0.5/src/apogee/Apogee.h0000644000175000017500000000606110610474640013516 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #if !defined(AFX_APOGEE__INCLUDED_) #define AFX_APOGEE__INCLUDED_ #define Apn_Interface int #define Apn_Interface_NET 0 #define Apn_Interface_USB 1 #define Apn_NetworkMode int #define Apn_NetworkMode_Tcp 0 #define Apn_NetworkMode_Udp 1 #define Apn_Resolution int #define Apn_Resolution_SixteenBit 0 #define Apn_Resolution_TwelveBit 1 #define Apn_CameraMode int #define Apn_CameraMode_Normal 0 #define Apn_CameraMode_TDI 1 #define Apn_CameraMode_Test 2 #define Apn_CameraMode_ExternalTrigger 3 #define Apn_CameraMode_ExternalShutter 4 #define Apn_Status int #define Apn_Status_DataError -2 #define Apn_Status_PatternError -1 #define Apn_Status_Idle 0 #define Apn_Status_Exposing 1 #define Apn_Status_ImagingActive 2 #define Apn_Status_ImageReady 3 #define Apn_Status_Flushing 4 #define Apn_Status_WaitingOnTrigger 5 #define Apn_LedMode int #define Apn_LedMode_DisableAll 0 #define Apn_LedMode_DisableWhileExpose 1 #define Apn_LedMode_EnableAll 2 #define Apn_LedState int #define Apn_LedState_Expose 0 #define Apn_LedState_ImageActive 1 #define Apn_LedState_Flushing 2 #define Apn_LedState_ExtTriggerWaiting 3 #define Apn_LedState_ExtTriggerReceived 4 #define Apn_LedState_ExtShutterInput 5 #define Apn_LedState_ExtStartReadout 6 #define Apn_LedState_AtTemp 7 #define Apn_CoolerStatus int #define Apn_CoolerStatus_Off 0 #define Apn_CoolerStatus_RampingToSetPoint 1 #define Apn_CoolerStatus_AtSetPoint 2 #define Apn_CoolerStatus_Revision 3 #define Apn_FanMode int #define Apn_FanMode_Off 0 #define Apn_FanMode_Low 1 #define Apn_FanMode_Medium 2 #define Apn_FanMode_High 3 #define Camera_Status int #define Camera_Status_Idle 0 #define Camera_Status_Waiting 1 #define Camera_Status_Exposing 2 #define Camera_Status_Downloading 3 #define Camera_Status_LineReady 4 #define Camera_Status_ImageReady 5 #define Camera_Status_Flushing 6 #define Camera_CoolerStatus int #define Camera_CoolerStatus_Off 0 #define Camera_CoolerStatus_RampingToSetPoint 1 #define Camera_CoolerStatus_Correcting 2 #define Camera_CoolerStatus_RampingToAmbient 3 #define Camera_CoolerStatus_AtAmbient 4 #define Camera_CoolerStatus_AtMax 5 #define Camera_CoolerStatus_AtMin 6 #define Camera_CoolerStatus_AtSetPoint 7 #define Camera_CoolerMode int #define Camera_CoolerMode_Off 0 #define Camera_CoolerMode_On 1 #define Camera_CoolerMode_Shutdown 2 #endif indi-0.5/src/apogee/ApogeeUsbLinux.cpp0000644000175000017500000002333110610474646015550 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApogeeUsb.cpp : Library of basic USB functions for Apogee APn/Alta. // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ApogeeUsb.h" #include "ApogeeUsbErr.h" #include "ApogeeLinux.h" #define HANDLE struct usb_dev_handle; #define ULONG unsigned int #define BOOLEAN unsigned int #define USHORT unsigned short #define APOGEE_USB_DEVICE "/dev/usb/alta" #define INVALID_HANDLE_VALUE -1 #define VND_ANCHOR_LOAD_INTERNAL 0xA0 #define VND_APOGEE_CMD_BASE 0xC0 #define VND_APOGEE_STATUS ( VND_APOGEE_CMD_BASE + 0x0 ) #define VND_APOGEE_CAMCON_REG ( VND_APOGEE_CMD_BASE + 0x2 ) #define VND_APOGEE_BUFCON_REG ( VND_APOGEE_CMD_BASE + 0x3 ) #define VND_APOGEE_SET_SERIAL ( VND_APOGEE_CMD_BASE + 0x4 ) #define VND_APOGEE_SERIAL ( VND_APOGEE_CMD_BASE + 0x5 ) #define VND_APOGEE_EEPROM ( VND_APOGEE_CMD_BASE + 0x6 ) #define VND_APOGEE_SOFT_RESET ( VND_APOGEE_CMD_BASE + 0x8 ) #define VND_APOGEE_GET_IMAGE ( VND_APOGEE_CMD_BASE + 0x9 ) #define VND_APOGEE_STOP_IMAGE ( VND_APOGEE_CMD_BASE + 0xA ) #define USB_ALTA_VENDOR_ID 0x125c #define USB_ALTA_PRODUCT_ID 0x0010 #define USB_DIR_IN USB_ENDPOINT_IN #define USB_DIR_OUT USB_ENDPOINT_OUT // Global variables used in this DLL struct usb_dev_handle *g_hSysDriver; ULONG g_UsbImgSizeBytes; char controlBuffer[1024]; #define IMAGE_BUFFER_SIZE 126976 // Number of requested bytes in a transfer //#define IMAGE_BUFFER_SIZE 253952 // Number of requested bytes in a transfer // This is an example of an exported function. APN_USB_TYPE ApnUsbOpen( unsigned short /*DevNumber*/ ) { /*char deviceName[128];*/ struct usb_bus *bus; struct usb_device *dev; struct usb_dev_handle *hDevice(NULL); usb_init(); usb_find_busses(); usb_find_devices(); /*char string[256];*/ int found = 0; /* find ALTA device */ for(bus = usb_busses; bus && !found; bus = bus->next) { for(dev = bus->devices; dev && !found; dev = dev->next) { if (dev->descriptor.idVendor == USB_ALTA_VENDOR_ID && dev->descriptor.idProduct == USB_ALTA_PRODUCT_ID) { hDevice = usb_open(dev); // cerr << "Found ALTA USB. Attempting to open... "; found = 1; if (hDevice) { // if (!usb_get_string_simple(hDevice, // dev->descriptor.iSerialNumber, // string, sizeof(string))) // throw DevOpenError(); // cerr << "Success.\n"; // cerr << "Serial number: " << string << endl; } else return APN_USB_ERR_OPEN; } } } if (!found) return APN_USB_ERR_OPEN; // if (!usb_set_configuration(hDevice, 0x0)) return APN_USB_ERR_OPEN; if (!usb_claim_interface(hDevice, 0x0)) return APN_USB_ERR_OPEN; g_hSysDriver = hDevice; g_UsbImgSizeBytes = 0; // printf("DRIVER: opened device\n"); return APN_USB_SUCCESS; // Success } APN_USB_TYPE ApnUsbClose( void ) { if ( g_hSysDriver != 0 ) { usb_release_interface(g_hSysDriver, 0x0); usb_close(g_hSysDriver); g_hSysDriver = 0; } return APN_USB_SUCCESS; // Success } APN_USB_TYPE ApnUsbReadReg( unsigned short FpgaReg, unsigned short *FpgaData ) { int Success; unsigned short RegData; Success = usb_control_msg((struct usb_dev_handle *)g_hSysDriver, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, VND_APOGEE_CAMCON_REG, FpgaReg, FpgaReg,(char *)&RegData, 2, 50); *FpgaData = RegData; /* printf("DRIVER: usb read reg=%x data=%x s=%x\n",FpgaReg,*FpgaData,Success); */ if ( !Success ) return APN_USB_ERR_WRITE; return APN_USB_SUCCESS; // Success } APN_USB_TYPE ApnUsbWriteReg( unsigned short FpgaReg, unsigned short FpgaData ) { char *cbuf; int Success; cbuf = (char *)&FpgaData; Success = usb_control_msg((struct usb_dev_handle *)g_hSysDriver, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, VND_APOGEE_CAMCON_REG, 0, FpgaReg, cbuf, 2, 50); /* printf("DRIVER: usb write reg=%x data=%x s=%x\n",FpgaReg,FpgaData,Success); */ if ( !Success ) return APN_USB_ERR_WRITE; return APN_USB_SUCCESS; // Success } APN_USB_TYPE ApnUsbWriteRegMulti( unsigned short FpgaReg, unsigned short FpgaData[], unsigned short RegCount ) { unsigned short Counter; for ( Counter=0; Counter> 16) & 0xFFFF, (ImageSize & 0xFFFF), (char *)&BytesReceived, 4, 3000); // printf("DRIVER: startexp s=%x\n",Success); // if ( !Success ) // { // return APN_USB_ERR_START_EXP; // } return APN_USB_SUCCESS; } APN_USB_TYPE ApnUsbStopExp( bool DigitizeData ) { BOOLEAN Success; unsigned short BytesReceived; // if ( (g_hSysDriver) == 0) // { // return APN_USB_ERR_OPEN; // } if ( DigitizeData == false ) { Success = usb_control_msg(g_hSysDriver, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, VND_APOGEE_STOP_IMAGE, 0, 0,(char *)&BytesReceived, 2, 3000); // if ( !Success ) // { // return APN_USB_ERR_STOP_EXP; // } } return APN_USB_SUCCESS; } APN_USB_TYPE ApnUsbGetImage( unsigned short *pMem ) { BOOLEAN Success; ULONG ImageBytesRemaining; ULONG ReceivedSize; Success = 1; // if ( (g_hSysDriver) == 0 ) // { // return APN_USB_ERR_OPEN; // } ImageBytesRemaining = g_UsbImgSizeBytes; //////////////////////// ULONG LoopCount = g_UsbImgSizeBytes / IMAGE_BUFFER_SIZE; ULONG Remainder = g_UsbImgSizeBytes - ( LoopCount * IMAGE_BUFFER_SIZE ); ULONG MemIterator = IMAGE_BUFFER_SIZE / 2; ULONG Counter; for ( Counter=0; Counter #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD5710LS::CApnCamData_CCD5710LS() { } CApnCamData_CCD5710LS::~CApnCamData_CCD5710LS() { } void CApnCamData_CCD5710LS::Initialize() { strcpy( m_Sensor, "CCD5710LS" ); strcpy( m_CameraModel, "57" ); m_CameraId = 18; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 536; m_ImagingColumns = 512; m_ClampColumns = 12; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 12; m_TotalRows = 1056; m_ImagingRows = 512; m_UnderscanRows = 536; m_OverscanRows = 8; m_VFlushBinning = 4; m_EnableSingleRowOffset = true; m_RowOffsetBinning = 536; m_HFlushDisable = false; m_ShutterCloseDelay = 0; m_PixelSizeX = 13; m_PixelSizeY = 13; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 1.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD5710LS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 23; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamera_NET.cpp0000644000175000017500000001410310610474646015210 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "stdafx.h" #include "ApnCamera_NET.h" #include #include #include #include "ApogeeNet.h" #include "ApogeeNetErr.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// bool CApnCamera::InitDriver( unsigned long CamIdA, unsigned short CamIdB, unsigned long Option ) { char Hostname[25]; BYTE ipAddr[4]; int init; ipAddr[0] = (BYTE)(CamIdA & 0xFF); ipAddr[1] = (BYTE)((CamIdA >> 8) & 0xFF); ipAddr[2] = (BYTE)((CamIdA >> 16) & 0xFF); ipAddr[3] = (BYTE)((CamIdA >> 24) & 0xFF); sprintf( Hostname, "%u.%u.%u.%u:%u", ipAddr[3], ipAddr[2], ipAddr[1], ipAddr[0], CamIdB ); if ( ApnNetConnect( Hostname ) != APNET_SUCCESS ) { return false; } m_CameraInterface = Apn_Interface_NET; // Before trying to initialize, perform a simple loopback test unsigned short RegData; unsigned short NewRegData; RegData = 0x5AA5; if ( Write( FPGA_REG_SCRATCH, RegData ) != APNET_SUCCESS ) return false; if ( Read( FPGA_REG_SCRATCH, NewRegData ) != APNET_SUCCESS ) return false; if ( RegData != NewRegData ) return false; RegData = 0xA55A; if ( Write( FPGA_REG_SCRATCH, RegData ) != APNET_SUCCESS ) return false; if ( Read( FPGA_REG_SCRATCH, NewRegData ) != APNET_SUCCESS ) return false; if ( RegData != NewRegData ) return false; printf("Loopback test successful - ALTA-E detected at %u.%u.%u.%u:%u\n", ipAddr[3], ipAddr[2], ipAddr[1], ipAddr[0]); // The loopback test was successful. Proceed with initialization. init = InitDefaults(); if ( init != 0 ) { printf("Loopback test successful - InitDefaults FAILED\n"); return false; } printf("Loopback test successful - InitDefaults completed\n"); return true; } bool CApnCamera::CloseDriver() { ApnNetClose(); return true; } bool CApnCamera::GetImageData( unsigned short *pImageBuffer, unsigned short &Width, unsigned short &Height, unsigned long &Count ) { unsigned short Offset; unsigned short *pTempBuffer; long i, j; // Make sure it is okay to get the image data // The app *should* have done this on its own, but we have to make sure while ( !ImageReady() ) { Sleep( 50 ); read_ImagingStatus(); } Width = m_pvtWidth; Height = m_pvtHeight; if ( m_pvtBitsPerPixel == 16 ) Offset = 1; if ( m_pvtBitsPerPixel == 12 ) Offset = 10; Width -= Offset; // Calculate the true image width pTempBuffer = new unsigned short[(Width+Offset) * Height]; ApnNetGetImageTcp( pTempBuffer ); for ( i=0; i 1000 #pragma once #endif // _MSC_VER > 1000 #include "CameraIO.h" class CCameraIO_PCI : public CCameraIO { public: CCameraIO_PCI(); virtual ~CCameraIO_PCI(); bool InitDriver(); long ReadLine( long SkipPixels, long Pixels, unsigned short* pLineBuffer ); long Write( unsigned short reg, unsigned short val ); long Read( unsigned short reg, unsigned short& val ); private: BOOLEAN m_IsWDM; HANDLE m_hDriver; void CloseDriver(); }; #endif // !defined(AFX_CAMERAIO_PCI_H__0F583058_8596_11D4_915F_0060676644C1__INCLUDED_) indi-0.5/src/apogee/ApnCamData_KAF4202.h0000644000175000017500000000334510610474640015242 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF4202.h: Interface file for the CApnCamData_KAF4202 class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_KAF4202 : public CApnCamData { public: CApnCamData_KAF4202(); virtual ~CApnCamData_KAF4202(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnSerial_NET.cpp0000644000175000017500000001120310610474646015235 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnSerial_NET.cpp: implementation of the CApnSerial_NET class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "apogee.h" #include "ApnSerial_NET.h" #include "ApogeeNet.h" #include "ApogeeNetErr.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CApnSerial_NET::CApnSerial_NET() { m_SerialId = -1; } CApnSerial_NET::~CApnSerial_NET() { } bool CApnSerial_NET::InitPort( unsigned long CamIdA, unsigned short CamIdB, unsigned short SerialId ) { char Hostname[25]; BYTE ipAddr[4]; ipAddr[0] = (BYTE)(CamIdA & 0xFF); ipAddr[1] = (BYTE)((CamIdA >> 8) & 0xFF); ipAddr[2] = (BYTE)((CamIdA >> 16) & 0xFF); ipAddr[3] = (BYTE)((CamIdA >> 24) & 0xFF); sprintf( Hostname, "%u.%u.%u.%u", ipAddr[3], ipAddr[2], ipAddr[1], ipAddr[0] ); if ( m_SerialId != -1 ) { return false; } if ( (SerialId != 0) && (SerialId != 1) ) { return false; } if ( ApnNetStartSockets() != APNET_SUCCESS ) return false; if ( ApnNetSerialPortOpen( Hostname, CamIdB, SerialId ) != APNET_SUCCESS ) return false; m_SerialId = SerialId; return true; } bool CApnSerial_NET::ClosePort() { if ( m_SerialId == -1 ) return false; // just close the port and not care whether it was successful. if it was, // great. if not, we'll still set m_SerialId to -1 so that another call // can at least be tried to connect to the port. ApnNetSerialPortClose( m_SerialId ); ApnNetStopSockets(); m_SerialId = -1; return true; } bool CApnSerial_NET::GetBaudRate( unsigned long *BaudRate ) { *BaudRate = -1; if ( m_SerialId == -1 ) return false; /* unsigned long BaudRateRead; if ( m_SerialId == -1 ) return false; if ( ApnNetSerialReadBaudRate(m_SerialId, &BaudRateRead) != APNET_SUCCESS ) return false; *BaudRate = BaudRateRead; */ return true; } bool CApnSerial_NET::SetBaudRate( unsigned long BaudRate ) { if ( m_SerialId == -1 ) return false; /* if ( ApnNetSerialWriteBaudRate(m_SerialId, BaudRate) != APNET_SUCCESS ) return false; */ return true; } bool CApnSerial_NET::GetFlowControl( Apn_SerialFlowControl *FlowControl ) { *FlowControl = Apn_SerialFlowControl_Unknown; if ( m_SerialId == -1 ) return false; /* bool FlowControlRead; if ( m_SerialId == -1 ) return false; if ( ApnNetSerialReadFlowControl(m_SerialId, &FlowControlRead) != APNET_SUCCESS ) return false; */ return true; } bool CApnSerial_NET::SetFlowControl( Apn_SerialFlowControl FlowControl ) { if ( m_SerialId == -1 ) return false; /* if ( ApnNetSerialWriteFlowControl(m_SerialId, FlowControl) != APNET_SUCCESS ) return false; */ return true; } bool CApnSerial_NET::GetParity( Apn_SerialParity *Parity ) { *Parity = Apn_SerialParity_Unknown; if ( m_SerialId == -1 ) return false; /* ApnNetParity ParityRead; if ( m_SerialId == -1 ) return false; if ( ApnNetSerialReadParity(m_SerialId, &ParityRead) != APNET_SUCCESS ) return false; *Parity = (Apn_SerialParity)ParityRead; */ return true; } bool CApnSerial_NET::SetParity( Apn_SerialParity Parity ) { if ( m_SerialId == -1 ) return false; /* if ( ApnNetSerialWriteParity(m_SerialId, (ApnNetParity)Parity) != APNET_SUCCESS ) return false; */ return true; } bool CApnSerial_NET::Read( char *ReadBuffer, unsigned short *ReadCount ) { if ( m_SerialId == -1 ) return false; if ( ApnNetSerialRead(m_SerialId, ReadBuffer, ReadCount) != APNET_SUCCESS ) { *ReadCount = 0; return false; } return true; } bool CApnSerial_NET::Write( char *WriteBuffer, unsigned short WriteCount ) { if ( m_SerialId == -1 ) return false; if ( ApnNetSerialWrite(m_SerialId, WriteBuffer, WriteCount) != APNET_SUCCESS ) return false; return true; } indi-0.5/src/apogee/ApogeeLinux.h0000644000175000017500000000506410610474640014540 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef APOGEELINUX_H #define APOGEELINUX_H #define APISA_READ_USHORT _IOR('a', 0x01, unsigned int) #define APISA_READ_LINE _IOR('a', 0x02, unsigned int) #define APISA_WRITE_USHORT _IOW('a', 0x03, unsigned int) #define APPPI_READ_USHORT _IOR('a', 0x01, unsigned int) #define APPPI_READ_LINE _IOR('a', 0x02, unsigned int) #define APPPI_WRITE_USHORT _IOW('a', 0x03, unsigned int) #define APPCI_READ_USHORT _IOR('a', 0x01, unsigned int) #define APPCI_READ_LINE _IOR('a', 0x02, unsigned int) #define APPCI_WRITE_USHORT _IOW('a', 0x03, unsigned int) #define APUSB_READ_USHORT _IOR('a', 0x01, unsigned int) #define APUSB_WRITE_USHORT _IOW('a', 0x02, unsigned int) #define APUSB_USB_STATUS _IOR('a', 0x03, unsigned int) #define APUSB_PRIME_USB_DOWNLOAD _IOR('a', 0x04, unsigned int) #define APUSB_STOP_USB_IMAGE _IOR('a', 0x05, unsigned int) #define APUSB_READ_USB_IMAGE _IOR('a', 0x06, unsigned int) #define APUSB_USB_RESET _IOR('a', 0x07, unsigned int) #define APUSB_READ_USB_SERIAL _IOR('a', 0x08, unsigned int) #define APUSB_WRITE_USB_SERIAL _IOR('a', 0x09, unsigned int) #define APUSB_USB_SET_SERIAL _IOR('a', 0x0A, unsigned int) #define APUSB_USB_REQUEST _IOR('a', 0x0B, unsigned int) #define APUSB_READ_STATUS _IOR('a', 0x0C, unsigned int) #define appci_major_number 60 #define apppi_major_number 61 #define apisa_major_number 62 struct apIOparam // IOCTL data { unsigned int reg; unsigned long param1, param2; }; #define APOGEE_PCI_DEVICE "/dev/appci" #define APOGEE_PPI_DEVICE "/dev/apppi" #define APOGEE_ISA_DEVICE "/dev/apisa" #define APOGEE_USB_DEVICE "/dev/usb/alta" const int NUM_POSITIONS = 6; const int NUM_STEPS_PER_FILTER = 48; const int STEP_DELAY = 10; const unsigned char Steps[] = { 0x10, 0x30, 0x20, 0x60, 0x40, 0xc0, 0x80, 0x90 }; const int NUM_STEPS = sizeof ( Steps ); #endif indi-0.5/src/apogee/ApnCamData_CCD4710LS4.cpp0000644000175000017500000005556010610474646016130 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4710LS4.cpp: Implementation file for the CApnCamData_CCD4710LS4 class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD4710LS4.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD4710LS4::CApnCamData_CCD4710LS4() { } CApnCamData_CCD4710LS4::~CApnCamData_CCD4710LS4() { } void CApnCamData_CCD4710LS4::Initialize() { strcpy( m_Sensor, "CCD4710LS4" ); strcpy( m_CameraModel, "47" ); m_CameraId = 15; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1072; m_ImagingColumns = 1024; m_ClampColumns = 24; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 24; m_TotalRows = 1027; m_ImagingRows = 1024; m_UnderscanRows = 3; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 13; m_PixelSizeY = 13; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD4710LS4::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 247; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_KAF16801E.cpp0000644000175000017500000006166310610474646016007 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF16801E.cpp: Implementation file for the CApnCamData_KAF16801E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_KAF16801E.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_KAF16801E::CApnCamData_KAF16801E() { } CApnCamData_KAF16801E::~CApnCamData_KAF16801E() { } void CApnCamData_KAF16801E::Initialize() { strcpy( m_Sensor, "KAF16801E" ); strcpy( m_CameraModel, "16" ); m_CameraId = 9; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 4145; m_ImagingColumns = 4098; m_ClampColumns = 35; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 12; m_TotalRows = 4128; m_ImagingRows = 4098; m_UnderscanRows = 10; m_OverscanRows = 20; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 9; m_PixelSizeY = 9; m_Color = false; m_ReportedGainSixteenBit = 1.5; m_MinSuggestedExpTime = 30.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 100; m_DefaultOffsetTwelveBit = 255; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_KAF16801E::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 116; unsigned short Pattern[NumElements] = { 0x0000, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0204, 0x0204, 0x0204, 0x0204, 0x0204, 0x0204, 0x0204, 0x0204, 0x0204, 0x0204, 0x0004, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_CCD4240LS.h0000644000175000017500000000336110610474640015471 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4240LS.h: Interface file for the CApnCamData_CCD4240LS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD4240LS : public CApnCamData { public: CApnCamData_CCD4240LS(); virtual ~CApnCamData_CCD4240LS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_KAF1602E.cpp0000644000175000017500000006105110610474646015707 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *////////////////////////////////////////////////////////////// // // ApnCamData_KAF1602E.cpp: Implementation file for the CApnCamData_KAF1602E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_KAF1602E.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_KAF1602E::CApnCamData_KAF1602E() { } CApnCamData_KAF1602E::~CApnCamData_KAF1602E() { } void CApnCamData_KAF1602E::Initialize() { strcpy( m_Sensor, "KAF1602E" ); strcpy( m_CameraModel, "2" ); m_CameraId = 1; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1564; m_ImagingColumns = 1536; m_ClampColumns = 14; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 14; m_TotalRows = 1032; m_ImagingRows = 1024; m_UnderscanRows = 4; m_OverscanRows = 4; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 9; m_PixelSizeY = 9; m_Color = false; m_ReportedGainSixteenBit = 1.5; m_MinSuggestedExpTime = 10.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 100; m_DefaultOffsetTwelveBit = 255; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_KAF1602E::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 71; unsigned short Pattern[NumElements] = { 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_CCD4720HS.cpp0000644000175000017500000005223410610474646016034 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4720HS.cpp: Implementation file for the CApnCamData_CCD4720HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD4720HS.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD4720HS::CApnCamData_CCD4720HS() { } CApnCamData_CCD4720HS::~CApnCamData_CCD4720HS() { } void CApnCamData_CCD4720HS::Initialize() { strcpy( m_Sensor, "CCD4720HS" ); strcpy( m_CameraModel, "4720" ); m_CameraId = 25; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1072; m_ImagingColumns = 1024; m_ClampColumns = 24; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 24; m_TotalRows = 2057; m_ImagingRows = 1024; m_UnderscanRows = 1033; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = true; m_RowOffsetBinning = 1033; m_HFlushDisable = false; m_ShutterCloseDelay = 0; m_PixelSizeX = 13; m_PixelSizeY = 13; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 1.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD4720HS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 23; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_CCD4710LS.cpp0000644000175000017500000005573210610474646016045 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4710LS.cpp: Implementation file for the CApnCamData_CCD4710LS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD4710LS.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD4710LS::CApnCamData_CCD4710LS() { } CApnCamData_CCD4710LS::~CApnCamData_CCD4710LS() { } void CApnCamData_CCD4710LS::Initialize() { strcpy( m_Sensor, "CCD4710LS" ); strcpy( m_CameraModel, "47" ); m_CameraId = 10; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1072; m_ImagingColumns = 1024; m_ClampColumns = 24; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 24; m_TotalRows = 1027; m_ImagingRows = 1024; m_UnderscanRows = 3; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 13; m_PixelSizeY = 13; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD4710LS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 247; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_CCD3011HS.cpp0000644000175000017500000005572710610474646016036 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD3011HS.cpp: Implementation file for the CApnCamData_CCD3011HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD3011HS.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD3011HS::CApnCamData_CCD3011HS() { } CApnCamData_CCD3011HS::~CApnCamData_CCD3011HS() { } void CApnCamData_CCD3011HS::Initialize() { strcpy( m_Sensor, "CCD3011HS" ); strcpy( m_CameraModel, "30" ); m_CameraId = 21; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1040; m_ImagingColumns = 1024; m_ClampColumns = 8; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 8; m_TotalRows = 256; m_ImagingRows = 256; m_UnderscanRows = 0; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 26; m_PixelSizeY = 26; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD3011HS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 247; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_KAF0261E.cpp0000644000175000017500000006104710610474646015714 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF0261E.cpp: Implementation file for the CApnCamData_KAF0261E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_KAF0261E.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_KAF0261E::CApnCamData_KAF0261E() { } CApnCamData_KAF0261E::~CApnCamData_KAF0261E() { } void CApnCamData_KAF0261E::Initialize() { strcpy( m_Sensor, "KAF0261E" ); strcpy( m_CameraModel, "260" ); m_CameraId = 2; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 530; m_ImagingColumns = 512; m_ClampColumns = 8; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 10; m_TotalRows = 520; m_ImagingRows = 512; m_UnderscanRows = 4; m_OverscanRows = 4; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 20; m_PixelSizeY = 20; m_Color = false; m_ReportedGainSixteenBit = 3; m_MinSuggestedExpTime = 10.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 100; m_DefaultOffsetTwelveBit = 255; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_KAF0261E::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 71; unsigned short Pattern[NumElements] = { 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_KAF6303E.cpp0000644000175000017500000006105210610474646015713 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF6303E.cpp: Implementation file for the CApnCamData_KAF6303E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_KAF6303E.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_KAF6303E::CApnCamData_KAF6303E() { } CApnCamData_KAF6303E::~CApnCamData_KAF6303E() { } void CApnCamData_KAF6303E::Initialize() { strcpy( m_Sensor, "KAF6303E" ); strcpy( m_CameraModel, "9" ); m_CameraId = 8; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 3100; m_ImagingColumns = 3073; m_ClampColumns = 15; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 12; m_TotalRows = 2056; m_ImagingRows = 2048; m_UnderscanRows = 4; m_OverscanRows = 4; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 9; m_PixelSizeY = 9; m_Color = false; m_ReportedGainSixteenBit = 1.5; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 100; m_DefaultOffsetTwelveBit = 255; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_KAF6303E::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 71; unsigned short Pattern[NumElements] = { 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_KAF1301E.h0000644000175000017500000000335210610474640015342 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF1301E.h: Interface file for the CApnCamData_KAF1301E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_KAF1301E : public CApnCamData { public: CApnCamData_KAF1301E(); virtual ~CApnCamData_KAF1301E(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_TH7899.h0000644000175000017500000000334010610474640015200 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_TH7899.h: Interface file for the CApnCamData_TH7899 class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_TH7899 : public CApnCamData { public: CApnCamData_TH7899(); virtual ~CApnCamData_TH7899(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnSerial.h0000644000175000017500000000401610610474640014172 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnSerial.h: interface for the CApnSerial class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_APNSERIAL_H__A27F1749_FA8F_40E8_A03F_4A28C8378DD1__INCLUDED_) #define AFX_APNSERIAL_H__A27F1749_FA8F_40E8_A03F_4A28C8378DD1__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "Apogee.h" class CApnSerial { public: CApnSerial(); virtual ~CApnSerial(); virtual bool InitPort( unsigned long CamIdA, unsigned short CamIdB, unsigned short SerialId ) = 0; virtual bool ClosePort() = 0; virtual bool GetBaudRate( unsigned long *BaudRate ) = 0; virtual bool SetBaudRate( unsigned long BaudRate ) = 0; virtual bool GetFlowControl( Apn_SerialFlowControl *FlowControl ) = 0; virtual bool SetFlowControl( Apn_SerialFlowControl FlowControl ) = 0; virtual bool GetParity( Apn_SerialParity *Parity ) = 0; virtual bool SetParity( Apn_SerialParity Parity ) = 0; virtual bool Read( char *ReadBuffer, unsigned short *ReadCount ) = 0; virtual bool Write( char *WriteBuffer, unsigned short WriteCount ) = 0; // Variables Apn_Interface m_CameraInterface; short m_SerialId; }; #endif // !defined(AFX_APNSERIAL_H__A27F1749_FA8F_40E8_A03F_4A28C8378DD1__INCLUDED_) indi-0.5/src/apogee/ApnCamData_CCD4020HS.h0000644000175000017500000000141010610474640015452 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ indi-0.5/src/apogee/ApnCamData_CCD4720HS.h0000644000175000017500000000335710610474640015475 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4720HS.h: Interface file for the CApnCamData_CCD4720HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD4720HS : public CApnCamData { public: CApnCamData_CCD4720HS(); virtual ~CApnCamData_CCD4720HS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData.cpp0000644000175000017500000000722010610474646014606 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnCamData.cpp: implementation of the CApnCamData class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ApnCamData.h" #include #include ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CApnCamData::CApnCamData() { init_vpattern(); init_hpattern( &m_ClampPatternSixteen ); init_hpattern( &m_SkipPatternSixteen ); init_hpattern( &m_RoiPatternSixteen ); init_hpattern( &m_ClampPatternTwelve ); init_hpattern( &m_SkipPatternTwelve ); init_hpattern( &m_RoiPatternTwelve ); } CApnCamData::~CApnCamData() { clear_vpattern(); clear_hpattern( &m_ClampPatternSixteen ); clear_hpattern( &m_SkipPatternSixteen ); clear_hpattern( &m_RoiPatternSixteen ); clear_hpattern( &m_ClampPatternTwelve ); clear_hpattern( &m_SkipPatternTwelve ); clear_hpattern( &m_RoiPatternTwelve ); } void CApnCamData::init_vpattern( ) { // OutputDebugString( "init_vpattern()" ); m_VerticalPattern.Mask = 0x0; m_VerticalPattern.NumElements = 0; m_VerticalPattern.PatternData = NULL; } void CApnCamData::clear_vpattern( ) { // OutputDebugString( "clear_vpattern()" ); m_VerticalPattern.Mask = 0x0; m_VerticalPattern.NumElements = 0; if ( m_VerticalPattern.PatternData != NULL ) { free( m_VerticalPattern.PatternData ); m_VerticalPattern.PatternData = NULL; } } void CApnCamData::init_hpattern( APN_HPATTERN_FILE *Pattern ) { int Counter; // OutputDebugString( "init_hpattern()" ); Pattern->Mask = 0x0; Pattern->RefNumElements = 0; Pattern->SigNumElements = 0; Pattern->BinningLimit = 0; Pattern->RefPatternData = NULL; Pattern->SigPatternData = NULL; for ( Counter=0; CounterBinNumElements[Counter] = 0; Pattern->BinPatternData[Counter] = NULL; } } void CApnCamData::clear_hpattern( APN_HPATTERN_FILE *Pattern ) { int Counter; // char szMsg[80]; // OutputDebugString( "clear_hpattern()" ); Pattern->Mask = 0x0; Pattern->RefNumElements = 0; Pattern->SigNumElements = 0; Pattern->BinningLimit = 0; if ( Pattern->RefPatternData != NULL ) { // OutputDebugString( "Freeing Allocated Reference Pattern Memory" ); free( Pattern->RefPatternData ); Pattern->RefPatternData = NULL; } if ( Pattern->SigPatternData != NULL ) { // OutputDebugString( "Freeing Allocated Signal Pattern Memory" ); free( Pattern->SigPatternData ); Pattern->SigPatternData = NULL; } for ( Counter=0; CounterBinNumElements[Counter] = 0; if ( Pattern->BinPatternData[Counter] != NULL ) { // sprintf( szMsg, "Freeing Allocated Binning Pattern Memory (Binning = %d)", Counter+1 ); // OutputDebugString( szMsg ); free( Pattern->BinPatternData[Counter] ); Pattern->BinPatternData[Counter] = NULL; } } } indi-0.5/src/apogee/ApnCamData_KAF1001E.cpp0000644000175000017500000006105110610474646015700 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF1001E.cpp: Implementation file for the CApnCamData_KAF1001E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_KAF1001E.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_KAF1001E::CApnCamData_KAF1001E() { } CApnCamData_KAF1001E::~CApnCamData_KAF1001E() { } void CApnCamData_KAF1001E::Initialize() { strcpy( m_Sensor, "KAF1001E" ); strcpy( m_CameraModel, "6" ); m_CameraId = 5; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1044; m_ImagingColumns = 1024; m_ClampColumns = 8; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 12; m_TotalRows = 1032; m_ImagingRows = 1024; m_UnderscanRows = 4; m_OverscanRows = 4; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 24; m_PixelSizeY = 24; m_Color = false; m_ReportedGainSixteenBit = 3; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 100; m_DefaultOffsetTwelveBit = 255; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_KAF1001E::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 71; unsigned short Pattern[NumElements] = { 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_CCD3011HS.h0000644000175000017500000000336210610474640015461 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD3011HS.h: Interface file for the CApnCamData_CCD3011HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD3011HS : public CApnCamData { public: CApnCamData_CCD3011HS(); virtual ~CApnCamData_CCD3011HS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnSerial.cpp0000644000175000017500000000244510610474646014537 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnSerial.cpp: implementation of the CApnSerial class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "apogee.h" #include "ApnSerial.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CApnSerial::CApnSerial() { m_SerialId = -1; } CApnSerial::~CApnSerial() { } indi-0.5/src/apogee/ApnCamData_KAF3200E.cpp0000644000175000017500000006044210610474646015706 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF3200E.cpp: Implementation file for the CApnCamData_KAF3200E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_KAF3200E.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_KAF3200E::CApnCamData_KAF3200E() { } CApnCamData_KAF3200E::~CApnCamData_KAF3200E() { } void CApnCamData_KAF3200E::Initialize() { strcpy( m_Sensor, "KAF3200E" ); strcpy( m_CameraModel, "32" ); m_CameraId = 6; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 2267; m_ImagingColumns = 2184; m_ClampColumns = 46; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 37; m_TotalRows = 1510; m_ImagingRows = 1472; m_UnderscanRows = 34; m_OverscanRows = 4; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 6.8; m_PixelSizeY = 6.8; m_Color = false; m_ReportedGainSixteenBit = 1; m_MinSuggestedExpTime = 10.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 100; m_DefaultOffsetTwelveBit = 255; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_KAF3200E::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 39; unsigned short Pattern[NumElements] = { 0x0000, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0204, 0x0204, 0x0204, 0x0204, 0x0204, 0x0204, 0x0204, 0x0204, 0x0204, 0x0204, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_CCD7700HS.h0000644000175000017500000000335710610474640015476 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD7700HS.h: Interface file for the CApnCamData_CCD7700HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD7700HS : public CApnCamData { public: CApnCamData_CCD7700HS(); virtual ~CApnCamData_CCD7700HS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_KAF0401E.h0000644000175000017500000000335210610474640015342 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF0401E.h: Interface file for the CApnCamData_KAF0401E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_KAF0401E : public CApnCamData { public: CApnCamData_KAF0401E(); virtual ~CApnCamData_KAF0401E(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_CCD7700LS.h0000644000175000017500000000335710610474640015502 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD7700LS.h: Interface file for the CApnCamData_CCD7700LS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD7700LS : public CApnCamData { public: CApnCamData_CCD7700LS(); virtual ~CApnCamData_CCD7700LS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_CCD7700HS.cpp0000644000175000017500000005271610610474646016042 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD7700HS.cpp: Implementation file for the CApnCamData_CCD7700HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD7700HS.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD7700HS::CApnCamData_CCD7700HS() { } CApnCamData_CCD7700HS::~CApnCamData_CCD7700HS() { } void CApnCamData_CCD7700HS::Initialize() { strcpy( m_Sensor, "CCD7700HS" ); strcpy( m_CameraModel, "77" ); m_CameraId = 27; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 527; m_ImagingColumns = 512; m_ClampColumns = 15; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 0; m_TotalRows = 512; m_ImagingRows = 512; m_UnderscanRows = 0; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 24; m_PixelSizeY = 24; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD7700HS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 61; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x000A, 0x000A, 0x000A, 0x000A, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamera_USB.h0000644000175000017500000000462210610474640014657 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnCamera_USB.h: interface for the CApnCamera_USB class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_APNCAMERA_USB_H__E83248CA_F0AA_4221_8E10_22FA70CEFAA6__INCLUDED_) #define AFX_APNCAMERA_USB_H__E83248CA_F0AA_4221_8E10_22FA70CEFAA6__INCLUDED_ #include "ApnCamera.h" class CApnCamera_USB : public CApnCamera { private: unsigned short m_pvtBitsPerPixel; unsigned short m_pvtWidth; unsigned short m_pvtHeight; public: CApnCamera_USB(); virtual ~CApnCamera_USB(); bool InitDriver( unsigned long CamIdA, unsigned short CamIdB, unsigned long Option ); bool CloseDriver(); long PreStartExpose( unsigned short BitsPerPixel ); long PostStopExposure( bool DigitizeData ); bool GetImageData( unsigned short *pImageData, unsigned short &Width, unsigned short &Height, unsigned long &Count ); bool GetLineData( unsigned short *pLineBuffer, unsigned short &Size ); long Read( unsigned short reg, unsigned short& val ); long Write( unsigned short reg, unsigned short val ); long WriteMultiSRMD( unsigned short reg, unsigned short val[], unsigned short count ); long WriteMultiMRMD( unsigned short reg[], unsigned short val[], unsigned short count ); long QueryStatusRegs( unsigned short& StatusReg, unsigned short& HeatsinkTempReg, unsigned short& CcdTempReg, unsigned short& CoolerDriveReg, unsigned short& VoltageReg, unsigned short& TdiCounter, unsigned short& SequenceCounter ); }; #endif // !defined(AFX_APNCAMERA_USB_H__E83248CA_F0AA_4221_8E10_22FA70CEFAA6__INCLUDED_) indi-0.5/src/apogee/ApnCamData_KAF3200E.h0000644000175000017500000000335210610474640015342 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF3200E.h: Interface file for the CApnCamData_KAF3200E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_KAF3200E : public CApnCamData { public: CApnCamData_KAF3200E(); virtual ~CApnCamData_KAF3200E(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/Camera_Example.cpp0000644000175000017500000004266310610474646015532 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // Example source code for implementing the CCameraIO object #include "windows.h" #include "stdio.h" #include "CameraIO.h" #include "CameraIO_ISA_9x.h" #include "CameraIO_PPI_9x.h" #include "CameraIO_ISA_NT.h" #include "CameraIO_PPI_NT.h" #include "CameraIO_PCI.h" // Error codes returned from config_load const long CCD_OPEN_NOERR = 0; // No error detected const long CCD_OPEN_CFGNAME = 1; // No config file specified const long CCD_OPEN_CFGDATA = 2; // Config missing or missing required data const long CCD_OPEN_LOOPTST = 3; // Loopback test failed, no camera found const long CCD_OPEN_ALLOC = 4; // Memory alloc failed - system error const long CCD_OPEN_NTIO = 5; // NT I/O driver not present CCameraIO* cam; // the Camera interface object // Function declarations for this file int InitCam( char* cfgname ); long config_load( char* cfgname, short BaseAddress, short RegOffset ); bool CfgGet ( FILE* inifp, char* inisect, char* iniparm, char* retbuff, short bufflen, short* parmlen); unsigned short hextoi(char* instr); void trimstr(char* s); // Initializes the CameraIO object from an INI file specified by cfgname int InitCam( char* cfgname ) { long ret = config_load( cfgname, -1, -1 ); if ( ret == 0 ) { // We can now access the cam objects members cam->Flush(); // Start the camera flushing return 0; } else { switch ( ret ) { case CCD_OPEN_CFGNAME: // "No config file specified." break; case CCD_OPEN_CFGDATA: // "Config file missing or missing required data." break; case CCD_OPEN_LOOPTST: // "Loopback test failed, no camera found" break; case CCD_OPEN_ALLOC: // "Memory allocation failed - system error" break; case CCD_OPEN_NTIO: // "NT I/O driver not present" break; } return ret; } } // Convert a string to a decimal or hexadecimal integer unsigned short hextoi(char *instr) { unsigned short val, tot = 0; bool IsHEX = false; long n = strlen( instr ); if ( n > 1 ) { // Look for hex format e.g. 8Fh, A3H or 0x5D if ( instr[ n - 1 ] == 'h' || instr[ n - 1 ] == 'H' ) IsHEX = true; else if ( *instr == '0' && *(instr+1) == 'x' ) { IsHEX = true; instr += 2; } } if ( IsHEX ) { while (instr && *instr && isxdigit(*instr)) { val = *instr++ - '0'; if (9 < val) val -= 7; tot <<= 4; tot |= (val & 0x0f); } } else tot = atoi( instr ); return tot; } // Trim trailing spaces from a string void trimstr(char *s) { char *p; p = s + (strlen(s) - 1); while (isspace(*p)) p--; *(++p) = '\0'; } //------------------------------------------------------------- // CfgGet // // Retrieve a parameter from an INI file. Returns a status code // and the parameter string in retbuff. //------------------------------------------------------------- bool CfgGet ( FILE* inifp, char *inisect, char *iniparm, char *retbuff, short bufflen, short *parmlen) { short gotsect; char tbuf[256]; char *ss, *eq, *ps, *vs, *ptr; rewind( inifp ); // find the target section gotsect = 0; while (fgets(tbuf,256,inifp) != NULL) { if ((ss = strchr(tbuf,'[')) != NULL) { if (strnicmp(ss+1,inisect,strlen(inisect)) == 0) { gotsect = 1; break; } } } if (!gotsect) { // section not found return false; } while (fgets(tbuf,256,inifp) != NULL) { // find parameter in sect if ((ptr = strrchr(tbuf,'\n')) != NULL) // remove newline if there *ptr = '\0'; ps = tbuf+strspn(tbuf," \t"); // find the first non-blank if (*ps == ';') // Skip line if comment continue; if (*ps == '[') { // Start of next section return false; } eq = strchr(ps,'='); // Find '=' sign in string if (eq) vs = eq + 1 + strspn(eq+1," \t"); // Find start of value str else continue; // found the target parameter if (strnicmp(ps,iniparm,strlen(iniparm)) == 0) { if ((ptr = strchr(vs,';')) != NULL) // cut off an EOL comment *ptr = '\0'; if (short(strlen(vs)) > bufflen - 1) {// not enough buffer space strncpy(retbuff,vs,bufflen - 1); retbuff[bufflen - 1] = '\0'; // put EOL in string *parmlen = bufflen; return true; } else { strcpy(retbuff,vs); // got it trimstr(retbuff); // trim any trailing blanks *parmlen = strlen(retbuff); return true; } } } return false; // parameter not found } // Initializes internal variables to their default value and reads the parameters in the // specified INI file. Then initializes the camera using current settings. If BaseAddress // or RegOffset parameters are specified (not equal to -1) then one or both of these // values are used for the m_BaseAddress and m_RegisterOffset properties overriding those // settings in the INI file. long config_load( char* cfgname, short BaseAddress, short RegOffset ) { short plen; char retbuf[256]; if ((strlen(cfgname) == 0) || (cfgname[0] == '\0')) return CCD_OPEN_CFGNAME; // attempt to open INI file FILE* inifp = NULL; if ((inifp = fopen(cfgname,"r")) == NULL) return CCD_OPEN_CFGDATA; // Check whether we are on an NT platform OSVERSIONINFO VersionInfo; memset(&VersionInfo, 0, sizeof(OSVERSIONINFO)); VersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx ( &VersionInfo ); bool IsNT = VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS; // System if (CfgGet (inifp, "system", "interface", retbuf, sizeof(retbuf), &plen)) { // Assume cam is currently null if ( stricmp( "isa", retbuf ) == 0 ) { if ( IsNT ) cam = new CCameraIO_ISA_NT; else cam = new CCameraIO_ISA_9x; } else if ( stricmp( "ppi", retbuf ) == 0 ) { if ( IsNT ) cam = new CCameraIO_PPI_NT; else cam = new CCameraIO_PPI_9x; } else if ( stricmp( "pci", retbuf ) == 0 ) { cam = new CCameraIO_PCI; } if ( cam == NULL ) { fclose( inifp ); return CCD_OPEN_ALLOC; } } else { fclose( inifp ); return CCD_OPEN_CFGDATA; } ///////////////////////////////////////////////////////////////////////////////// // Settings which are stored in a class member (not in firmware) are already set // to a default value in the constructor. Settings accessed by get/put functions // must be set to a default value in this routine, after the base address and // communication protocal is setup. ///////////////////////////////////////////////////////////////////////////////// // These settings must done first since they affect communication with the camera if ( BaseAddress == -1 ) { if (CfgGet (inifp, "system", "base", retbuf, sizeof(retbuf), &plen)) cam->m_BaseAddress = hextoi(retbuf) & 0xFFF; else { fclose( inifp ); delete cam; cam = NULL; return CCD_OPEN_CFGDATA; // base address MUST be defined } } else cam->m_BaseAddress = BaseAddress & 0xFFF; if ( RegOffset == -1 ) { if (CfgGet (inifp, "system", "reg_offset", retbuf, sizeof(retbuf), &plen)) { unsigned short val = hextoi(retbuf); if ( val >= 0x0 && val <= 0xF0 ) cam->m_RegisterOffset = val & 0xF0; } } else { if ( RegOffset >= 0x0 && RegOffset <= 0xF0 ) cam->m_RegisterOffset = RegOffset & 0xF0; } ///////////////////////////////////////////////////////////////////////////////// // Necessary geometry settings if (CfgGet (inifp, "geometry", "rows", retbuf, sizeof(retbuf), &plen)) { short val = hextoi(retbuf); if ( val >= 1 && val <= MAXTOTALROWS ) cam->m_Rows = val; } else { fclose( inifp ); delete cam; cam = NULL; return CCD_OPEN_CFGDATA; // rows MUST be defined } if (CfgGet (inifp, "geometry", "columns", retbuf, sizeof(retbuf), &plen)) { short val = hextoi(retbuf); if ( val >= 1 && val <= MAXTOTALCOLUMNS ) cam->m_Columns = val; } else { fclose( inifp ); delete cam; cam = NULL; return CCD_OPEN_CFGDATA; // columns MUST be defined } ///////////////////////////////////////////////////////////////////////////////// if (CfgGet (inifp, "system", "pp_repeat", retbuf, sizeof(retbuf), &plen)) { short val = hextoi( retbuf ); if ( val > 0 && val <= 1000 ) cam->m_PPRepeat = val; } ///////////////////////////////////////////////////////////////////////////////// // First actual communication with camera if in PPI mode if ( !cam->InitDriver() ) { delete cam; cam = NULL; fclose( inifp ); if ( IsNT ) return CCD_OPEN_NTIO; else return CCD_OPEN_LOOPTST; } ///////////////////////////////////////////////////////////////////////////////// // First actual communication with camera if in ISA mode cam->Reset(); // Read in command register to set shadow register known state ///////////////////////////////////////////////////////////////////////////////// if (CfgGet (inifp, "system", "cable", retbuf, sizeof(retbuf), &plen)) { if (!stricmp("LONG",retbuf)) cam->write_LongCable( true ); else if ( !stricmp("SHORT",retbuf) ) cam->write_LongCable( false ); } else cam->write_LongCable( false ); // default if ( !cam->read_Present() ) { delete cam; cam = NULL; fclose( inifp ); return CCD_OPEN_LOOPTST; } ///////////////////////////////////////////////////////////////////////////////// // Set default setting and read other settings from ini file cam->write_UseTrigger( false ); cam->write_ForceShutterOpen( false ); if (CfgGet (inifp, "system", "high_priority", retbuf, sizeof(retbuf), &plen)) { if (!stricmp("ON",retbuf) || !stricmp("TRUE",retbuf) || !stricmp("1",retbuf)) { cam->m_HighPriority = true; } else if (!stricmp("OFF",retbuf) || !stricmp("FALSE",retbuf) || !stricmp("0",retbuf)) { cam->m_HighPriority = false; } } if (CfgGet (inifp, "system", "data_bits", retbuf, sizeof(retbuf), &plen)) { short val = hextoi( retbuf ); if ( val >= 8 && val <= 18 ) cam->m_DataBits = val; } if (CfgGet (inifp, "system", "sensor", retbuf, sizeof(retbuf), &plen)) { if ( stricmp( "ccd", retbuf ) == 0 ) { cam->m_SensorType = Camera_SensorType_CCD; } else if ( stricmp( "cmos", retbuf ) == 0 ) { cam->m_SensorType = Camera_SensorType_CMOS; } } if (CfgGet (inifp, "system", "mode", retbuf, sizeof(retbuf), &plen)) { unsigned short val = hextoi(retbuf) & 0xF; cam->write_Mode( val ); } else cam->write_Mode( 0 ); // default if (CfgGet (inifp, "system", "test", retbuf, sizeof(retbuf), &plen)) { unsigned short val = hextoi(retbuf) & 0xF; cam->write_TestBits( val ); } else cam->write_TestBits( 0 ); //default if (CfgGet (inifp, "system", "test2", retbuf, sizeof(retbuf), &plen)) { unsigned short val = hextoi(retbuf) & 0xF; cam->write_Test2Bits( val ); } else cam->write_Test2Bits( 0 ); // default cam->write_FastReadout( false ); //default if (CfgGet (inifp, "system", "shutter_speed", retbuf, sizeof(retbuf), &plen)) { if (!stricmp("normal",retbuf)) { cam->m_FastShutter = false; cam->m_MaxExposure = 10485.75; cam->m_MinExposure = 0.01; } else if (!stricmp("fast",retbuf)) { cam->m_FastShutter = true; cam->m_MaxExposure = 1048.575; cam->m_MinExposure = 0.001; } else if ( !stricmp("dual",retbuf)) { cam->m_FastShutter = true; cam->m_MaxExposure = 10485.75; cam->m_MinExposure = 0.001; } } if (CfgGet (inifp, "system", "shutter_bits", retbuf, sizeof(retbuf), &plen)) { unsigned short val = hextoi(retbuf); cam->m_FastShutterBits_Mode = val & 0x0F; cam->m_FastShutterBits_Test = ( val & 0xF0 ) >> 4; } if (CfgGet (inifp, "system", "maxbinx", retbuf, sizeof(retbuf), &plen)) { short val = hextoi(retbuf); if ( val >= 1 && val <= MAXHBIN ) cam->m_MaxBinX = val; } if (CfgGet (inifp, "system", "maxbiny", retbuf, sizeof(retbuf), &plen)) { short val = hextoi(retbuf); if ( val >= 1 && val <= MAXVBIN ) cam->m_MaxBinY = val; } if (CfgGet (inifp, "system", "guider_relays", retbuf, sizeof(retbuf), &plen)) { if (!stricmp("ON",retbuf) || !stricmp("TRUE",retbuf) || !stricmp("1",retbuf)) { cam->m_GuiderRelays = true; } else if (!stricmp("OFF",retbuf) || !stricmp("FALSE",retbuf) || !stricmp("0",retbuf)) { cam->m_GuiderRelays = false; } } if (CfgGet (inifp, "system", "timeout", retbuf, sizeof(retbuf), &plen)) { double val = atof(retbuf); if ( val >= 0.0 && val <= 10000.0 ) cam->m_Timeout = val; } ///////////////////////////////////////////////////////////////////////////////// // Geometry if (CfgGet (inifp, "geometry", "bic", retbuf, sizeof(retbuf), &plen)) { short val = hextoi(retbuf); if ( val >= 1 && val <= MAXCOLUMNS ) cam->m_BIC = val; } if (CfgGet (inifp, "geometry", "bir", retbuf, sizeof(retbuf), &plen)) { short val = hextoi(retbuf); if ( val >= 1 && val <= MAXROWS ) cam->m_BIR = val; } if (CfgGet (inifp, "geometry", "skipc", retbuf, sizeof(retbuf), &plen)) { short val = hextoi(retbuf); if ( val >= 0 && val <= MAXCOLUMNS ) cam->m_SkipC = val; } if (CfgGet (inifp, "geometry", "skipr", retbuf, sizeof(retbuf), &plen)) { short val = hextoi(retbuf); if ( val >= 0 && val <= MAXROWS ) cam->m_SkipR = val; } if (CfgGet (inifp, "geometry", "imgcols", retbuf, sizeof(retbuf), &plen)) { short val = hextoi(retbuf); if ( val >= 1 && val <= MAXTOTALCOLUMNS ) cam->m_ImgColumns = val; } else cam->m_ImgColumns = cam->m_Columns - cam->m_BIC - cam->m_SkipC; if (CfgGet (inifp, "geometry", "imgrows", retbuf, sizeof(retbuf), &plen)) { short val = hextoi(retbuf); if ( val >= 1 && val <= MAXTOTALROWS ) cam->m_ImgRows = val; } else cam->m_ImgRows = cam->m_Rows - cam->m_BIR - cam->m_SkipR; if (CfgGet (inifp, "geometry", "hflush", retbuf, sizeof(retbuf), &plen)) { short val = hextoi(retbuf); if ( val >= 1 && val <= MAXHBIN ) cam->m_HFlush = val; } if (CfgGet (inifp, "geometry", "vflush", retbuf, sizeof(retbuf), &plen)) { short val = hextoi(retbuf); if ( val >= 1 && val <= MAXVBIN ) cam->m_VFlush = val; } // Default to full frame cam->m_NumX = cam->m_ImgColumns; cam->m_NumY = cam->m_ImgRows; ///////////////////////////////////////////////////////////////////////////////// // Temperature if (CfgGet (inifp, "temp", "control", retbuf, sizeof(retbuf), &plen)) { if (!stricmp("ON",retbuf) || !stricmp("TRUE",retbuf) || !stricmp("1",retbuf)) { cam->m_TempControl = true; } else if (!stricmp("OFF",retbuf) || !stricmp("FALSE",retbuf) || !stricmp("0",retbuf)) { cam->m_TempControl = false; } } if (CfgGet (inifp, "temp", "cal", retbuf, sizeof(retbuf), &plen)) { short val = hextoi(retbuf); if ( val >= 1 && val <= 255 ) cam->m_TempCalibration = val; } if (CfgGet (inifp, "temp", "scale", retbuf, sizeof(retbuf), &plen)) { double val = atof(retbuf); if ( val >= 1.0 && val <= 10.0 ) cam->m_TempScale = val; } if (CfgGet (inifp, "temp", "target", retbuf, sizeof(retbuf), &plen)) { double val = atof(retbuf); if ( val >= -60.0 && val <= 40.0 ) cam->write_CoolerSetPoint( val ); else cam->write_CoolerSetPoint( -10.0 ); } else cam->write_CoolerSetPoint( -10.0 ); //default ///////////////////////////////////////////////////////////////////////////////// // CCD if (CfgGet (inifp, "ccd", "sensor", retbuf, sizeof(retbuf), &plen)) { if ( plen > 256 ) plen = 256; memcpy( cam->m_Sensor, retbuf, plen ); } if (CfgGet (inifp, "ccd", "color", retbuf, sizeof(retbuf), &plen)) { if (!stricmp("ON",retbuf) || !stricmp("TRUE",retbuf) || !stricmp("1",retbuf)) { cam->m_Color = true; } else if (!stricmp("OFF",retbuf) || !stricmp("FALSE",retbuf) || !stricmp("0",retbuf)) { cam->m_Color = false; } } if (CfgGet (inifp, "ccd", "noise", retbuf, sizeof(retbuf), &plen)) { cam->m_Noise = atof( retbuf ); } if (CfgGet (inifp, "ccd", "gain", retbuf, sizeof(retbuf), &plen)) { cam->m_Gain = atof( retbuf ); } if (CfgGet (inifp, "ccd", "pixelxsize", retbuf, sizeof(retbuf), &plen)) { cam->m_PixelXSize = atof( retbuf ); } if (CfgGet (inifp, "ccd", "pixelysize", retbuf, sizeof(retbuf), &plen)) { cam->m_PixelYSize = atof( retbuf ); } fclose( inifp ); return CCD_OPEN_NOERR; } indi-0.5/src/apogee/ApnCamData_KAF1301E.cpp0000644000175000017500000006105210610474646015704 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_KAF1301E.cpp: Implementation file for the CApnCamData_KAF1301E class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_KAF1301E.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_KAF1301E::CApnCamData_KAF1301E() { } CApnCamData_KAF1301E::~CApnCamData_KAF1301E() { } void CApnCamData_KAF1301E::Initialize() { strcpy( m_Sensor, "KAF1301E" ); strcpy( m_CameraModel, "13" ); m_CameraId = 3; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1305; m_ImagingColumns = 1280; m_ClampColumns = 4; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 21; m_TotalRows = 1028; m_ImagingRows = 1024; m_UnderscanRows = 2; m_OverscanRows = 2; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 16; m_PixelSizeY = 16; m_Color = false; m_ReportedGainSixteenBit = 3; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 100; m_DefaultOffsetTwelveBit = 255; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_KAF1301E::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 71; unsigned short Pattern[NumElements] = { 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_CCD4240HS.cpp0000644000175000017500000005573710610474646016044 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4240HS.cpp: Implementation file for the CApnCamData_CCD4240HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD4240HS.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD4240HS::CApnCamData_CCD4240HS() { } CApnCamData_CCD4240HS::~CApnCamData_CCD4240HS() { } void CApnCamData_CCD4240HS::Initialize() { strcpy( m_Sensor, "CCD4240HS" ); strcpy( m_CameraModel, "42" ); m_CameraId = 16; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 2148; m_ImagingColumns = 2048; m_ClampColumns = 50; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 50; m_TotalRows = 2052; m_ImagingRows = 2048; m_UnderscanRows = 2; m_OverscanRows = 2; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 600; m_PixelSizeX = 13.5; m_PixelSizeY = 13.5; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD4240HS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 247; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_CCD5520LS.cpp0000644000175000017500000005573410610474646016047 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD5520LS.cpp: Implementation file for the CApnCamData_CCD5520LS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD5520LS.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD5520LS::CApnCamData_CCD5520LS() { } CApnCamData_CCD5520LS::~CApnCamData_CCD5520LS() { } void CApnCamData_CCD5520LS::Initialize() { strcpy( m_Sensor, "CCD5520LS" ); strcpy( m_CameraModel, "55" ); m_CameraId = 22; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 804; m_ImagingColumns = 770; m_ClampColumns = 17; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 17; m_TotalRows = 1152; m_ImagingRows = 1152; m_UnderscanRows = 0; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 22.5; m_PixelSizeY = 22.5; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD5520LS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 247; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamTable.h0000644000175000017500000000706310610474640014430 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __APN_CAM_TABLE_H__ #define __APN_CAM_TABLE_H__ #define APN_MODEL_COUNT 25 // total number of models #define APN_ALTA_KAF0401E_CAM_ID 0 #define APN_ALTA_KAF0401E_CAM_SZ "1" #define APN_ALTA_KAF1602E_CAM_ID 1 #define APN_ALTA_KAF1602E_CAM_SZ "2" #define APN_ALTA_KAF0261E_CAM_ID 2 #define APN_ALTA_KAF0261E_CAM_SZ "260" #define APN_ALTA_KAF1301E_CAM_ID 3 #define APN_ALTA_KAF1301E_CAM_SZ "13" #define APN_ALTA_KAF1401E_CAM_ID 4 #define APN_ALTA_KAF1401E_CAM_SZ "14" #define APN_ALTA_KAF1001E_CAM_ID 5 #define APN_ALTA_KAF1001E_CAM_SZ "6" #define APN_ALTA_KAF3200E_CAM_ID 6 #define APN_ALTA_KAF3200E_CAM_SZ "32" #define APN_ALTA_KAF4202_CAM_ID 7 #define APN_ALTA_KAF4202_CAM_SZ "4" #define APN_ALTA_KAF6303E_CAM_ID 8 #define APN_ALTA_KAF6303E_CAM_SZ "9" #define APN_ALTA_KAF16801E_CAM_ID 9 #define APN_ALTA_KAF16801E_CAM_SZ "16" #define APN_ALTA_CCD4710LS_CAM_ID 10 #define APN_ALTA_CCD4710LS_CAM_SZ "47" #define APN_ALTA_CCD4710HS_CAM_ID 11 #define APN_ALTA_CCD4710HS_CAM_SZ "47" #define APN_ALTA_TH7899_CAM_ID 14 #define APN_ALTA_TH7899_CAM_SZ "10" #define APN_ALTA_CCD4240LS_CAM_ID 16 #define APN_ALTA_CCD4240LS_CAM_SZ "42" #define APN_ALTA_CCD4240HS_CAM_ID 17 #define APN_ALTA_CCD4240HS_CAM_SZ "42" #define APN_ALTA_CCD5710LS_CAM_ID 18 #define APN_ALTA_CCD5710LS_CAM_SZ "57" #define APN_ALTA_CCD5710HS_CAM_ID 19 #define APN_ALTA_CCD5710HS_CAM_SZ "57" #define APN_ALTA_CCD3011LS_CAM_ID 20 #define APN_ALTA_CCD3011LS_CAM_SZ "30" #define APN_ALTA_CCD3011HS_CAM_ID 21 #define APN_ALTA_CCD3011HS_CAM_SZ "30" #define APN_ALTA_CCD5520LS_CAM_ID 22 #define APN_ALTA_CCD5520LS_CAM_SZ "55" #define APN_ALTA_CCD5520HS_CAM_ID 23 #define APN_ALTA_CCD5520HS_CAM_SZ "55" #define APN_ALTA_CCD4720LS_CAM_ID 24 #define APN_ALTA_CCD4720LS_CAM_SZ "4720" #define APN_ALTA_CCD4720HS_CAM_ID 25 #define APN_ALTA_CCD4720HS_CAM_SZ "4720" #define APN_ALTA_CCD7700LS_CAM_ID 26 #define APN_ALTA_CCD7700LS_CAM_SZ "77" #define APN_ALTA_CCD7700HS_CAM_ID 27 #define APN_ALTA_CCD7700HS_CAM_SZ "77" #define APN_ALTA_KAI2001M_CAM_ID 64 #define APN_ALTA_KAI2001M_CAM_SZ "2000" #define APN_ALTA_KAI2001MC_CAM_ID 65 #define APN_ALTA_KAI2001MC_CAM_SZ "2000C" #define APN_ALTA_KAI4020_CAM_ID 66 #define APN_ALTA_KAI4020_CAM_SZ "4000" #define APN_ALTA_KAI11000_CAM_ID 67 #define APN_ALTA_KAI11000_CAM_SZ "11000" #define APN_ALTA_KAI11000C_CAM_ID 68 #define APN_ALTA_KAI11000C_CAM_SZ "11000C" #define APN_ALTA_CCD4710LS2_CAM_ID 12 #define APN_ALTA_CCD4710LS2_CAM_SZ "4710" #define APN_ALTA_CCD4710LS3_CAM_ID 13 #define APN_ALTA_CCD4710LS3_CAM_SZ "4710" #define APN_ALTA_CCD4710LS4_CAM_ID 15 #define APN_ALTA_CCD4710LS4_CAM_SZ "4710" #define APN_ALTA_CCD4710LS5_CAM_ID 28 #define APN_ALTA_CCD4710LS5_CAM_SZ "4710" // Helper function prototype void ApnCamModelLookup( unsigned short CamId, unsigned short Interface, char *szCamModel ); #endif indi-0.5/src/apogee/ApnCamData_CCD4240HS.h0000644000175000017500000000336110610474640015465 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4240HS.h: Interface file for the CApnCamData_CCD4240HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD4240HS : public CApnCamData { public: CApnCamData_CCD4240HS(); virtual ~CApnCamData_CCD4240HS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_CCD4710HS.h0000644000175000017500000000336110610474640015467 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4710HS.h: Interface file for the CApnCamData_CCD4710HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD4710HS : public CApnCamData { public: CApnCamData_CCD4710HS(); virtual ~CApnCamData_CCD4710HS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_CCD4710LS.h0000644000175000017500000000336110610474640015473 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4710LS.h: Interface file for the CApnCamData_CCD4710LS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD4710LS : public CApnCamData { public: CApnCamData_CCD4710LS(); virtual ~CApnCamData_CCD4710LS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApogeeUsbErr.h0000644000175000017500000000212210610474640014633 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // Error codes for the ApogeeUsb* files #define APN_USB_SUCCESS 0 #define APN_USB_ERR_OPEN 1 #define APN_USB_ERR_READ 2 #define APN_USB_ERR_WRITE 3 #define APN_USB_ERR_IMAGE_DOWNLOAD 4 #define APN_USB_ERR_START_EXP 5 #define APN_USB_ERR_STOP_EXP 6 #define APN_USB_ERR_STATUS 7 #define APN_USB_ERR_RESET 8 indi-0.5/src/apogee/ApnSerial_USB.h0000644000175000017500000000357210610474640014711 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnSerial_USB.h: interface for the CApnSerial_USB class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_APNSERIAL_USB_H__D7A1A328_6505_438F_BCCE_FA3F3B5EECC2__INCLUDED_) #define AFX_APNSERIAL_USB_H__D7A1A328_6505_438F_BCCE_FA3F3B5EECC2__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "ApnSerial.h" class CApnSerial_USB : public CApnSerial { public: CApnSerial_USB(); virtual ~CApnSerial_USB(); bool InitPort( unsigned long CamIdA, unsigned short CamIdB, unsigned short SerialId ); bool ClosePort(); bool GetBaudRate( unsigned long *BaudRate ); bool SetBaudRate( unsigned long BaudRate ); bool GetFlowControl( Apn_SerialFlowControl *FlowControl ); bool SetFlowControl( Apn_SerialFlowControl FlowControl ); bool GetParity( Apn_SerialParity *Parity ); bool SetParity( Apn_SerialParity Parity ); bool Read( char *ReadBuffer, unsigned short *ReadCount ); bool Write( char *WriteBuffer, unsigned short WriteCount ); }; #endif // !defined(AFX_APNSERIAL_USB_H__D7A1A328_6505_438F_BCCE_FA3F3B5EECC2__INCLUDED_) indi-0.5/src/apogee/ApnCamData_CCD5520LS.h0000644000175000017500000000335710610474640015500 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD5520LS.h: Interface file for the CApnCamData_CCD5520LS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD5520LS : public CApnCamData { public: CApnCamData_CCD5520LS(); virtual ~CApnCamData_CCD5520LS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApogeeUsbLinuxForKernel.cpp0000644000175000017500000002545510610474646017371 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApogeeUsb.cpp : Library of basic USB functions for Apogee APn/Alta. // #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ApogeeUsb.h" #include "ApogeeUsbErr.h" #include "ApogeeLinux.h" #define HANDLE unsigned int #define ULONG unsigned int #define BOOLEAN unsigned int #define USHORT unsigned short #define APOGEE_USB_DEVICE "/dev/usb/alta" #define INVALID_HANDLE_VALUE -1 // Global variables used in this DLL HANDLE g_hSysDriver; ULONG g_UsbImgSizeBytes; // 1044480 // 520192 // 126976 // 61440 // 49152 // 4096 #define IMAGE_BUFFER_SIZE 126976 // Number of requested bytes in a transfer //#define IMAGE_BUFFER_SIZE 253952 // Number of requested bytes in a transfer // This is an example of an exported function. APN_USB_TYPE ApnUsbOpen( unsigned short DevNumber ) { char deviceName[128]; g_hSysDriver = 0; g_UsbImgSizeBytes = 0; // Open the driver sprintf(deviceName,"%s%d",APOGEE_USB_DEVICE,DevNumber); g_hSysDriver = ::open(deviceName,O_RDONLY); if ( g_hSysDriver == INVALID_HANDLE_VALUE ) { return APN_USB_ERR_OPEN; // Failure to open device } return APN_USB_SUCCESS; // Success } APN_USB_TYPE ApnUsbClose( void ) { if ( (g_hSysDriver != INVALID_HANDLE_VALUE ) && (g_hSysDriver != 0) ) { ::close( g_hSysDriver ); g_hSysDriver = 0; } return APN_USB_SUCCESS; // Success } APN_USB_TYPE ApnUsbDiscovery( unsigned short *UsbCamCount, APN_USB_CAMINFO UsbCamInfo[] ) { HANDLE hDriver; char deviceName[64]; unsigned short RegNumber; unsigned short retval; struct apIOparam request; USHORT RegData; *UsbCamCount = 0; for ( int i=0; i #include #include #include #include #include #include #include #include #define HANDLE int #define DWORD long #define _ASSERT assert #define REALTIME_PRIORITY_CLASS 1 #define GetCurrentProcess getpid #define LOBYTE(x) ((x) & 0xff) #define HIBYTE(x) ((x >> 8) & 0xff) #define MIRQ1 0x21 #define MIRQ2 0xA1 #include "time.h" //#include "tcl.h" //#include "ccd.h" #include "CameraIO_Linux.h" #include "ApogeeLinux.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// void CCameraIO::InitDefaults() { //////////////////////////////////////////////////////////// // Camera Settings m_HighPriority = true; m_PPRepeat = 1; m_DataBits = 16; m_FastShutter = false; m_MaxBinX = 8; m_MaxBinY = 63; m_MaxExposure = 10485.75; m_MinExposure = 0.01; m_GuiderRelays = false; m_Timeout = 2.0; //////////////////////////////////////////////////////////// // Cooler Settings m_TempControl = true; m_TempCalibration = 160; m_TempScale = 2.1; //////////////////////////////////////////////////////////// // Exposure Settings m_BinX = 1; m_BinY = 1; m_StartX = 0; m_StartY = 0; m_NumX = 1; m_NumY = 1; //////////////////////////////////////////////////////////// // Geometry Settings m_Columns = 0; m_Rows = 0; m_SkipC = 0; m_SkipR = 0; m_HFlush = 1; m_VFlush = 1; m_BIC = 4; m_BIR = 4; m_ImgColumns = 0; m_ImgRows = 0; //////////////////////////////////////////////////////////// // CCD Settings memset( m_Sensor, 0, 256 ); m_Color = false; m_Noise = 0.0; m_Gain = 0.0; m_PixelXSize = 0.0; m_PixelYSize = 0.0; //////////////////////////////////////////////////////////// // Internal variables fileHandle = 0; m_RegisterOffset = 0; m_Interface = Camera_Interface_PPI; m_SensorType = Camera_SensorType_CCD; } bool CCameraIO::InitDriver(unsigned short camnum) { char deviceName[64]; sprintf(deviceName,"%s%d",APOGEE_PPI_DEVICE,camnum); fileHandle = ::open(deviceName,O_RDONLY); if (fileHandle == -1) return false; return true; } long CCameraIO::Write( unsigned short reg, unsigned short val ) { int status; struct apIOparam request; unsigned short realreg = ( reg << 1 ) & 0xE; // limit input to our address range request.reg = realreg; request.param1=(int)val; request.param2=(int)m_PPRepeat; status=ioctl(fileHandle,APPPI_WRITE_USHORT,(unsigned long)&request); return 0; } long CCameraIO::Read( unsigned short reg, unsigned short& val ) { unsigned short realreg; int retval, status; struct apIOparam request; switch ( reg ) { case Reg_ImageData: realreg = RegISA_ImageData; break; case Reg_TempData: realreg = RegISA_TempData; break; case Reg_Status: realreg = RegISA_Status; break; case Reg_CommandReadback: realreg = RegISA_CommandReadback; break; default: assert( 1 ); // application program bug val = 0; return 0; } request.reg = realreg; request.param1=(unsigned long)&retval; request.param2=(int)m_PPRepeat; status=ioctl(fileHandle,APPPI_READ_USHORT,(unsigned long)&request); val = (unsigned short)retval; return 0; } // Returns 0 if successful, 1 if Line_Done poll timed out. long CCameraIO::ReadLine( long SkipPixels, long Pixels,unsigned short* pLineBuffer ) { int j; int retval, status; struct apIOparam request; if ( !m_TDI ) { ///////////////////////////////////// // Clock out the line m_RegShadow[ Reg_Command ] |= RegBit_StartNextLine; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_StartNextLine; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// } request.reg = RegISA_ImageData; request.param1=(unsigned long)&retval; request.param2=(int)m_PPRepeat; for (j = 0; j < SkipPixels; j++) { status=ioctl(fileHandle,APPPI_READ_USHORT,(unsigned long)&request); } for (j = 0; j < Pixels; j++) { status=ioctl(fileHandle,APPPI_READ_USHORT,(unsigned long)&request); *pLineBuffer++ = (unsigned short)retval; } ///////////////////////////////////// // Assert done reading line m_RegShadow[ Reg_Command ] |= RegBit_DoneReading; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_DoneReading; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// if ( !m_TDI ) { ///////////////////////////////////// // Wait until camera is done clock_t StopTime = clock() + CLOCKS_PER_SEC; // wait at most one second while ( true ) { unsigned short val = 0; Read( Reg_Status, val ); if ( ( val & RegBit_LineDone ) != 0 ) break;// Line done if ( clock() > StopTime ) return 1; // Timed out } } return 0; } long CCameraIO::ReadImage( unsigned short* pImageBuffer ) { m_RegShadow[ Reg_Command ] |= RegBit_FIFOCache; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); long XEnd = long( m_ExposureNumX ); long SkipC = long( m_ExposureSkipC ); for (long i = 0; i < m_ExposureSkipR; i++) { if( InternalReadLine( false, SkipC, XEnd, NULL ) ) return 1; } long YEnd = long( m_ExposureNumY ); unsigned short* pLineBuffer = pImageBuffer; for (long i = 0; i < YEnd; i++) { if ( InternalReadLine( true, SkipC, XEnd, pLineBuffer ) ) return 1; pLineBuffer += XEnd; } m_RegShadow[ Reg_Command ] &= !RegBit_FIFOCache; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); return 0; } // Returns 0 if successful, 1 if Line_Done poll timed out. long CCameraIO::InternalReadLine( bool KeepData, long SkipC, long XEnd, unsigned short* pLineBuffer ) { struct apIOparam request; int retval, status; ///////////////////////////////////// // Clock out the line m_RegShadow[ Reg_Command ] |= RegBit_StartNextLine; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= !RegBit_StartNextLine; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// request.reg = RegISA_ImageData; request.param1=(unsigned long)&retval; request.param2=(int)m_PPRepeat; for (long j = 0; j < SkipC; j++) status=ioctl(fileHandle,APPPI_READ_USHORT,(unsigned long)&request); if ( KeepData ) { for (long j = 0; j < XEnd; j++) { status=ioctl(fileHandle,APPPI_READ_USHORT,(unsigned long)&request); *pLineBuffer++ = (unsigned short)retval; } } else { for (long j = 0; j < XEnd; j++) status=ioctl(fileHandle,APPPI_READ_USHORT,(unsigned long)&request); } ///////////////////////////////////// // Assert done reading line m_RegShadow[ Reg_Command ] |= RegBit_DoneReading; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= !RegBit_DoneReading; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// ///////////////////////////////////// // Wait until camera is done clocking clock_t StopTime = clock() + CLOCKS_PER_SEC; // wait at most one second while ( true ) { unsigned short val = 0; Read( Reg_Status, val ); if ( ( val & RegBit_LineDone ) != 0 ) break;// Line done clock_t CurrentTime = clock(); if ( CurrentTime > StopTime ) return 1; // Timed out } return 0; } indi-0.5/src/apogee/ApnCamData_CCD4710LS5.cpp0000644000175000017500000005556010610474646016131 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4710LS5.cpp: Implementation file for the CApnCamData_CCD4710LS5 class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD4710LS5.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD4710LS5::CApnCamData_CCD4710LS5() { } CApnCamData_CCD4710LS5::~CApnCamData_CCD4710LS5() { } void CApnCamData_CCD4710LS5::Initialize() { strcpy( m_Sensor, "CCD4710LS5" ); strcpy( m_CameraModel, "47" ); m_CameraId = 28; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1072; m_ImagingColumns = 1024; m_ClampColumns = 24; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 24; m_TotalRows = 1027; m_ImagingRows = 1024; m_UnderscanRows = 3; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 13; m_PixelSizeY = 13; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD4710LS5::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 247; unsigned short Pattern[NumElements] = { 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0005, 0x0004 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/CameraIO_LinuxISA.cpp0000644000175000017500000002260210610474646016012 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // CameraIO.cpp: implementation of the CCameraIO class. // ////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #define HANDLE int #define FALSE 0 #define DWORD long #define _ASSERT assert #define REALTIME_PRIORITY_CLASS 1 #define GetCurrentProcess getpid #define LOBYTE(x) ((x) & 0xff) #define HIBYTE(x) ((x >> 8) & 0xff) #define MIRQ1 0x21 #define MIRQ2 0xA1 #include "time.h" //#include "tcl.h" //#include "ccd.h" #include "CameraIO_Linux.h" #include "ApogeeLinux.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// void CCameraIO::InitDefaults() { //////////////////////////////////////////////////////////// // Camera Settings m_HighPriority = true; m_PPRepeat = 1; m_DataBits = 16; m_FastShutter = false; m_MaxBinX = 8; m_MaxBinY = 63; m_MaxExposure = 10485.75; m_MinExposure = 0.01; m_GuiderRelays = false; m_Timeout = 2.0; //////////////////////////////////////////////////////////// // Cooler Settings m_TempControl = true; m_TempCalibration = 160; m_TempScale = 2.1; //////////////////////////////////////////////////////////// // Exposure Settings m_BinX = 1; m_BinY = 1; m_StartX = 0; m_StartY = 0; m_NumX = 1; m_NumY = 1; //////////////////////////////////////////////////////////// // Geometry Settings m_Columns = 0; m_Rows = 0; m_SkipC = 0; m_SkipR = 0; m_HFlush = 1; m_VFlush = 1; m_BIC = 4; m_BIR = 4; m_ImgColumns = 0; m_ImgRows = 0; //////////////////////////////////////////////////////////// // CCD Settings memset( m_Sensor, 0, 256 ); m_Color = false; m_Noise = 0.0; m_Gain = 0.0; m_PixelXSize = 0.0; m_PixelYSize = 0.0; //////////////////////////////////////////////////////////// // Internal variables fileHandle = 0; m_RegisterOffset = 0; m_Interface = Camera_Interface_ISA; m_SensorType = Camera_SensorType_CCD; } bool CCameraIO::InitDriver(unsigned short camnum) { char deviceName[64]; sprintf(deviceName,"%s%d",APOGEE_ISA_DEVICE,camnum); fileHandle = ::open(deviceName,O_RDONLY); if (fileHandle == -1) return false; return true; } long CCameraIO::Write( unsigned short reg, unsigned short val ) { int status; struct apIOparam request; unsigned short realreg = ( reg << 1 ) & 0xE; // limit input to our address range request.reg = realreg; request.param1=(int)val; status=ioctl(fileHandle,APISA_WRITE_USHORT,(unsigned long)&request); return 0; } long CCameraIO::Read( unsigned short reg, unsigned short& val ) { unsigned short realreg; int retval, status; struct apIOparam request; switch ( reg ) { case Reg_ImageData: realreg = RegISA_ImageData; break; case Reg_TempData: realreg = RegISA_TempData; break; case Reg_Status: realreg = RegISA_Status; break; case Reg_CommandReadback: realreg = RegISA_CommandReadback; break; default: assert( 1 ); // application program bug val = 0; return 0; } request.reg = realreg; request.param1=(unsigned long)&retval; status=ioctl(fileHandle,APISA_READ_USHORT,(unsigned long)&request); val = (unsigned short)retval; return 0; } // Returns 0 if successful, 1 if Line_Done poll timed out. long CCameraIO::ReadLine( long SkipPixels, long Pixels,unsigned short* pLineBuffer ) { int j; int retval, status; struct apIOparam request; if ( !m_TDI ) { ///////////////////////////////////// // Clock out the line m_RegShadow[ Reg_Command ] |= RegBit_StartNextLine; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_StartNextLine; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// } request.reg = RegISA_ImageData; request.param1=(unsigned long)&retval; for (j = 0; j < SkipPixels; j++) { status=ioctl(fileHandle,APISA_READ_USHORT,(unsigned long)&request); } for (j = 0; j < Pixels; j++) { status=ioctl(fileHandle,APISA_READ_USHORT,(unsigned long)&request); *pLineBuffer++ = (unsigned short)retval; } ///////////////////////////////////// // Assert done reading line m_RegShadow[ Reg_Command ] |= RegBit_DoneReading; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= ~RegBit_DoneReading; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// if ( !m_TDI ) { ///////////////////////////////////// // Wait until camera is done clock_t StopTime = clock() + CLOCKS_PER_SEC; // wait at most one second while ( true ) { unsigned short val = 0; Read( Reg_Status, val ); if ( ( val & RegBit_LineDone ) != 0 ) break;// Line done if ( clock() > StopTime ) return 1; // Timed out } } return 0; } long CCameraIO::ReadImage( unsigned short* pImageBuffer ) { m_RegShadow[ Reg_Command ] |= RegBit_FIFOCache; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); long XEnd = long( m_ExposureNumX ); long SkipC = long( m_ExposureSkipC ); for (long i = 0; i < m_ExposureSkipR; i++) { if( InternalReadLine( false, SkipC, XEnd, NULL ) ) return 1; } long YEnd = long( m_ExposureNumY ); unsigned short* pLineBuffer = pImageBuffer; for (long i = 0; i < YEnd; i++) { if ( InternalReadLine( true, SkipC, XEnd, pLineBuffer ) ) return 1; pLineBuffer += XEnd; } m_RegShadow[ Reg_Command ] &= !RegBit_FIFOCache; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); return 0; } // Returns 0 if successful, 1 if Line_Done poll timed out. long CCameraIO::InternalReadLine( bool KeepData, long SkipC, long XEnd, unsigned short* pLineBuffer ) { struct apIOparam request; int retval, status; ///////////////////////////////////// // Clock out the line m_RegShadow[ Reg_Command ] |= RegBit_StartNextLine; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= !RegBit_StartNextLine; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// request.reg = RegISA_ImageData; request.param1=(unsigned long)&retval; for (long j = 0; j < SkipC; j++) status=ioctl(fileHandle,APISA_READ_USHORT,(unsigned long)&request); if ( KeepData ) { for (long j = 0; j < XEnd; j++) { status=ioctl(fileHandle,APISA_READ_USHORT,(unsigned long)&request); *pLineBuffer++ = (unsigned short)retval; } } else { for (long j = 0; j < XEnd; j++) status=ioctl(fileHandle,APISA_READ_USHORT,(unsigned long)&request); } ///////////////////////////////////// // Assert done reading line m_RegShadow[ Reg_Command ] |= RegBit_DoneReading; // set bit to 1 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); m_RegShadow[ Reg_Command ] &= !RegBit_DoneReading; // set bit to 0 Write( Reg_Command, m_RegShadow[ Reg_Command ] ); ///////////////////////////////////// ///////////////////////////////////// // Wait until camera is done clocking clock_t StopTime = clock() + CLOCKS_PER_SEC; // wait at most one second while ( true ) { unsigned short val = 0; Read( Reg_Status, val ); if ( ( val & RegBit_LineDone ) != 0 ) break;// Line done clock_t CurrentTime = clock(); if ( CurrentTime > StopTime ) return 1; // Timed out } return 0; } indi-0.5/src/apogee/ApnCamData_CCD4710HS.cpp0000644000175000017500000005474010610474646016037 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4710HS.cpp: Implementation file for the CApnCamData_CCD4710HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD4710HS.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD4710HS::CApnCamData_CCD4710HS() { } CApnCamData_CCD4710HS::~CApnCamData_CCD4710HS() { } void CApnCamData_CCD4710HS::Initialize() { strcpy( m_Sensor, "CCD4710HS" ); strcpy( m_CameraModel, "47" ); m_CameraId = 11; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1072; m_ImagingColumns = 1024; m_ClampColumns = 24; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 24; m_TotalRows = 1027; m_ImagingRows = 1024; m_UnderscanRows = 3; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 13; m_PixelSizeY = 13; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD4710HS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 247; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_TH7899.cpp0000644000175000017500000006012310610474646015543 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_TH7899.cpp: Implementation file for the CApnCamData_TH7899 class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_TH7899.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_TH7899::CApnCamData_TH7899() { } CApnCamData_TH7899::~CApnCamData_TH7899() { } void CApnCamData_TH7899::Initialize() { strcpy( m_Sensor, "TH7899" ); strcpy( m_CameraModel, "10" ); m_CameraId = 14; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 2110; m_ImagingColumns = 2048; m_ClampColumns = 25; m_PreRoiSkipColumns = 5; m_PostRoiSkipColumns = 5; m_OverscanColumns = 27; m_TotalRows = 2054; m_ImagingRows = 2048; m_UnderscanRows = 3; m_OverscanRows = 3; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 14; m_PixelSizeY = 14; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 100; m_DefaultOffsetTwelveBit = 255; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_TH7899::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 18; unsigned short Pattern[NumElements] = { 0x0000, 0x0018, 0x0018, 0x001A, 0x001A, 0x0012, 0x0012, 0x0016, 0x0016, 0x0006, 0x0006, 0x000E, 0x000E, 0x000C, 0x000C, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_CCD4240LS.cpp0000644000175000017500000005573710610474646016050 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4240LS.cpp: Implementation file for the CApnCamData_CCD4240LS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD4240LS.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD4240LS::CApnCamData_CCD4240LS() { } CApnCamData_CCD4240LS::~CApnCamData_CCD4240LS() { } void CApnCamData_CCD4240LS::Initialize() { strcpy( m_Sensor, "CCD4240LS" ); strcpy( m_CameraModel, "42" ); m_CameraId = 17; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 2148; m_ImagingColumns = 2048; m_ClampColumns = 50; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 50; m_TotalRows = 2052; m_ImagingRows = 2048; m_UnderscanRows = 2; m_OverscanRows = 2; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 600; m_PixelSizeX = 13.5; m_PixelSizeY = 13.5; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD4240LS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 247; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnCamData_CCD4710LS2.h0000644000175000017500000000336610610474640015562 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4710LS2.h: Interface file for the CApnCamData_CCD4710LS2 class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD4710LS2 : public CApnCamData { public: CApnCamData_CCD4710LS2(); virtual ~CApnCamData_CCD4710LS2(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_CCD7700LS.cpp0000644000175000017500000005271610610474646016046 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD7700LS.cpp: Implementation file for the CApnCamData_CCD7700LS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD7700LS.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD7700LS::CApnCamData_CCD7700LS() { } CApnCamData_CCD7700LS::~CApnCamData_CCD7700LS() { } void CApnCamData_CCD7700LS::Initialize() { strcpy( m_Sensor, "CCD7700LS" ); strcpy( m_CameraModel, "77" ); m_CameraId = 26; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 527; m_ImagingColumns = 512; m_ClampColumns = 15; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 0; m_TotalRows = 512; m_ImagingRows = 512; m_UnderscanRows = 0; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 24; m_PixelSizeY = 24; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD7700LS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 61; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x000A, 0x000A, 0x000A, 0x000A, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/CameraIO_Linux.h0000644000175000017500000004457610610474640015132 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // CameraIO.h: interface for the CCameraIO class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_CAMERAIO_H__A2882C82_7CFB_11D4_9155_0060676644C1__INCLUDED_) #define AFX_CAMERAIO_H__A2882C82_7CFB_11D4_9155_0060676644C1__INCLUDED_ #include "Apogee.h" enum Camera_Interface{ Camera_Interface_ISA = 0, Camera_Interface_PPI, Camera_Interface_PCI }; enum Camera_SensorType{ Camera_SensorType_CCD = 0, Camera_SensorType_CMOS }; const long MAXCOLUMNS = 16383; const long MAXROWS = 16383; const long MAXHBIN = 8; const long MAXVBIN = 255; // Number of write only registers const long NumWriteRegisters = 8; const long RegISA_Command = 0x000; // Register 1 in ISA firmware const long Reg_Command = 0; // Register 1 shadow const unsigned short RegBit_TDIMode = 0x1; // Bit 0 const unsigned short RegBit_StartTimer = 0x2; // Bit 1 const unsigned short RegBit_ShutterOverride = 0x4; // Bit 2 const unsigned short RegBit_ResetSystem = 0x8; // Bit 3 const unsigned short RegBit_FIFOCache = 0x10; // Bit 4 const unsigned short RegBit_TriggerEnable = 0x20; // Bit 5 const unsigned short RegBit_StopFlushing = 0x40; // Bit 6 const unsigned short RegBit_ShutterEnable = 0x80; // Bit 7 const unsigned short RegBit_CoolerShutdown = 0x100; // Bit 8 const unsigned short RegBit_DoneReading = 0x200; // Bit 9 const unsigned short RegBit_TimerLoad = 0x400; // Bit 10 const unsigned short RegBit_StartNextLine = 0x800; // Bit 11 const unsigned short RegBit_StartFlushing = 0x1000; // Bit 12 const unsigned short RegBit_Focus = 0x2000; // Bit 13 const unsigned short RegBit_CableLength = 0x4000; // Bit 14 const unsigned short RegBit_CoolerEnable = 0x8000; // Bit 15 const long RegISA_Timer = 0x002; // Register 2 in ISA firmware const long Reg_Timer = 1; // Register 2 shadow const unsigned short RegBitShift_Timer = 0; // Bit 0 const unsigned short RegBitMask_Timer = 0xFFFF; // 16 bits const long RegISA_VBinning = 0x004; // Register 3 in ISA firmware const long Reg_VBinning = 2; // Register 3 shadow const unsigned short RegBitShift_Timer2 = 0; // Bit 0 const unsigned short RegBitMask_Timer2 = 0xF; // 4 bits const unsigned short RegBitShift_VBinning = 0x8; // Bit 8 const unsigned short RegBitMask_VBinning = 0xFF; // 8 bits const long RegISA_AICCounter = 0x006; // Register 4 in ISA firmware const long Reg_AICCounter = 3; // Register 4 shadow const unsigned short RegBitShift_AICCounter = 0; // Bit 0 const unsigned short RegBitMask_AICCounter = 0xFFF; // 12 bits const unsigned short RegBitShift_Test2 = 0xC; // Bit 12 const unsigned short RegBitMask_Test2 = 0xF; // 4 bits const long RegISA_TempSetPoint = 0x008; // Register 5 in ISA firmware const long Reg_TempSetPoint = 4; // Register 5 shadow const unsigned short RegBitShift_TempSetPoint = 0; // Bit 0 const unsigned short RegBitMask_TempSetPoint = 0xFF;// 8 bits const unsigned short RegBitShift_PortControl = 0x8; // Bit 8 const unsigned short RegBitMask_PortControl = 0xFF; // 8 bits const long RegISA_PixelCounter = 0x00a; // Register 6 in ISA firmware const long Reg_PixelCounter = 5; // Register 6 shadow const unsigned short RegBitShift_PixelCounter = 0; // Bit 0 const unsigned short RegBitMask_PixelCounter = 0xFFF; // 12 bits const unsigned short RegBitShift_HBinning = 0xC; // Bit 12 const unsigned short RegBitMask_HBinning = 0x7; // 3 bits const unsigned short RegBit_LoopLock = 0x8000; // Bit 15 const long RegISA_LineCounter = 0x00c; // Register 7 in ISA firmware const long Reg_LineCounter = 6; // Register 7 shadow const unsigned short RegBitShift_LineCounter = 0; // Bit 0 const unsigned short RegBitMask_LineCounter = 0xFFF; // 12 bits const unsigned short RegBitShift_Mode = 0xC; // Bit 12 const unsigned short RegBitMask_Mode = 0xF; // 4 bits const long RegISA_BICCounter = 0x00e; // Register 8 in ISA firmware const long Reg_BICCounter = 7; // Register 8 shadow const unsigned short RegBitShift_BICCounter = 0; // Bit 0 const unsigned short RegBitMask_BICCounter = 0xFFF; // 12 bits const unsigned short RegBitShift_Test = 0xC; // Bit 12 const unsigned short RegBitMask_Test = 0xF; // 4 bits const long RegISA_ImageData = 0x000; // Register 9 in ISA firmware const long Reg_ImageData = 8; // Register 9 const unsigned short RegBitShift_ImageData = 0; // Bit 0 const unsigned short RegBitMask_ImageData = 0xFFFF; // 16 bits const long RegISA_TempData = 0x002; // Register 10 in ISA firmware const long Reg_TempData = 9; // Register 10 const unsigned short RegBitShift_TempData = 0; // Bit 0 const unsigned short RegBitMask_TempData = 0xFF; // 8 bits const long RegISA_Status = 0x006; // Register 11 in firmware const long Reg_Status = 10; // Register 11 const unsigned short RegBit_Exposing = 0x1; // Bit 0 const unsigned short RegBit_LineDone = 0x2; // Bit 1 const unsigned short RegBit_CacheReadOK = 0x4; // Bit 2 const unsigned short RegBit_TempAtMin = 0x10; // Bit 4 const unsigned short RegBit_TempAtMax = 0x20; // Bit 5 const unsigned short RegBit_ShutdownComplete = 0x40;// Bit 6 const unsigned short RegBit_TempAtSetPoint = 0x80; // Bit 7 const unsigned short RegBit_GotTrigger = 0x400; // Bit 10 const unsigned short RegBit_FrameDone = 0x800; // Bit 11 const unsigned short RegBit_LoopbackTest = 0x8000; // Bit 15 const long RegISA_CommandReadback = 0x008; // Register 12 in ISA firmware const long Reg_CommandReadback = 11; // Register 12 // Use RegBit offsets from Reg_Command const long RegPCI_Command = 0x000; // Register 1 in PCI firmware const long RegPCI_CommandRead = 0x020; const long RegPCI_Timer = 0x004; // Register 2 in PCI firmware const long RegPCI_TimerRead = 0x024; const long RegPCI_VBinning = 0x008; // Register 3 in PCI firmware const long RegPCI_VBinningRead = 0x028; const long RegPCI_AICCounter = 0x00C; // Register 4 in PCI firmware const long RegPCI_AICCounterRead = 0x02C; const long RegPCI_TempSetPoint = 0x010; // Register 5 in PCI firmware const long RegPCI_TempSetPointRead = 0x030; const long RegPCI_PixelCounter = 0x014; // Register 6 in PCI firmware const long RegPCI_PixelCounterRead = 0x034; const long RegPCI_LineCounter = 0x018; // Register 7 in PCI firmware const long RegPCI_LineCounterRead = 0x038; const long RegPCI_BICCounter = 0x01C; // Register 8 in PCI firmware const long RegPCI_BICCounterRead = 0x03C; const long RegPCI_ImageData = 0x000; // Register 9 in PCI firmware const long RegPCI_TempData = 0x004; // Register 10 in PCI firmware const long RegPCI_Status = 0x00C; // Register 11 in firmware const long RegPCI_CommandReadback = 0x010; // Register 12 in PCI firmware class CCameraIO { public: CCameraIO(); virtual ~CCameraIO(); //////////////////////////////////////////////////////////// // Low level read write methods - Overridables bool InitDriver(unsigned short camnum); long ReadLine( long SkipPixels, long Pixels, unsigned short* pLineBuffer ); long Write( unsigned short reg, unsigned short val ); long Read( unsigned short reg, unsigned short& val ); //////////////////////////////////////////////////////////// // Camera Settings Camera_Status read_Status(); // Current camera state // <0: error codes // 0: idle // 1: flushing // 2: waiting for trigger // 3: exposing // 4: reading // 5: downloading // 6: line ready // 7: image ready bool read_Present(); // True if camera is present, false otherwise. bool read_Shutter(); // Current shutter state, true = open, false = closed. void write_Shutter( bool val ); bool read_ForceShutterOpen(); // True: Forces shutter permanently open. False: allows void write_ForceShutterOpen( bool val ); // normal shutter operation. bool read_LongCable(); // Long cable mode. void write_LongCable( bool val ); short read_Mode(); // First four bits map to Mode bits used for void write_Mode( short val ); // special functions or camera configurations. short read_TestBits(); // First four bits to Test bits used for void write_TestBits( short val ); // troubleshooting. short read_Test2Bits(); // First four bits map to Test2 bits used for void write_Test2Bits( short val ); // special functions or camera configurations. bool read_FastReadout(); // Fast readout mode (used for focusing). void write_FastReadout( bool val ); // True means fast focus is on bool read_UseTrigger(); // Triggered exposure mode. void write_UseTrigger( bool val ); // True means triggered exposure is on. bool m_HighPriority; // Bost thread priority level during download short m_PPRepeat; // Delay used on parallel port systems. short m_DataBits; // Digitization resolution, 8 - 18. bool m_FastShutter; // Capable of 0.001 sec exposure resolution bool m_GuiderRelays; // Capable of outputting autoguider signals short m_MaxBinX, m_MaxBinY; // Maximum binning factors double m_MaxExposure; // Maximum exposure length double m_MinExposure; // Minimum exposure length double m_Timeout; // camera polling timeout value //////////////////////////////////////////////////////////// // Cooler Settings // N.B. DAC units = ( m_TempScale * CoolerSetPoint (deg. C ) ) + m_TempCalibration; // N.B. Temperature (deg. C) = (DAC units - m_TempCalibration) / m_TempScale double read_CoolerSetPoint(); // Returns/sets setpoint temperature in degrees void write_CoolerSetPoint( double val ); // Celcius. Camera_CoolerStatus read_CoolerStatus(); // Returns current cooler status Camera_CoolerMode read_CoolerMode(); // Returns/sets current cooler operation mode. void write_CoolerMode( Camera_CoolerMode val ); double read_Temperature(); // Current temperature in degrees Celcius. bool m_TempControl; // Temperature can be externally controlled short m_TempCalibration; // Temperature calibration factor. double m_TempScale; // Temperature scaling factor. //////////////////////////////////////////////////////////// // Exposure Settings // The following variables are latched in Expose method, until next Reset or GetImage short m_BinX, m_BinY; // Horizontal and vertical binning. short m_StartX, m_StartY; // Zero based subframe start position in unbinned pixels. short m_NumX, m_NumY; // Subframe size in binned pixels. //////////////////////////////////////////////////////////// // Geometry Settings // The following variables are latched in Expose method, until next Reset or GetImage short m_Columns, m_Rows; // Total columns/rows on CCD (physical). short m_ImgColumns, m_ImgRows; // Unbinned columns/rows in imaging area short m_SkipC, m_SkipR; // Deleted data columns/rows not to be displayed or saved short m_HFlush, m_VFlush; // Horizontal/Vertical flush binning. short m_BIC, m_BIR; // Before Image Column/Row count (dark non-imaging pixels). //////////////////////////////////////////////////////////// // CCD Settings char m_Sensor[ 256 ]; // Sensor model installed in camera (i.e. Sensor = SITe 502). bool m_Color; // Sensor has color dyes double m_Noise; // Read out noise in e-. double m_Gain; // Gain in e-/ADU units. double m_PixelXSize; // Size of pixel in X direction in micrometers. double m_PixelYSize; // Size of pixel in Y direction in micrometers. //////////////////////////////////////////////////////////// // System methods // Resets camera to idle state, will terminate current exposure. void Reset(); // Mask user requested set of IRQS // void MaskIrqs(); // Restore default IRQ mask // void UnmaskIrqs(); // Starts flushing the camera (which should be the normal idle state) // If Rows is non-negative, only the specified number of rows are flushed, // in which case the method will return only when flushing is completed. void Flush( short Rows = -1 ); // Output byte to auxillary output port (e.g. for driving guider relays). void AuxOutput( unsigned char val ); // Write a 16 bit value to register 1 to 8. void RegWrite( short reg, unsigned short val ); // Read a 16 bit value from register 9 to 12. void RegRead( short reg, unsigned short& val ); // Move the filterwheel to the home position - failure indicates no filterwheel //attached or broken filterwheel bool FilterHome(); // Move filterwheel to the given slot void FilterSet( short Slot ); //////////////////////////////////////////////////////////// // Normal exposure methods // The Duration parameter is the exposure time in seconds. The Light parameter controls // the status of the shutter during the exposure, Light = True opens the shutter, Light // = False closes the shutter. Returns immediately after invocation, poll the CameraStatus // property to determine the start time of a triggered exposure and the end of an exposure. bool Expose( double Duration, bool Light ); // Returns the pImageData parameter which is a pointer to unsigned short data with NumX*NumY // elements. Can be overridden if necessary virtual bool GetImage( unsigned short* pImageData, short& xSize, short& ySize ); /*virtual bool BufferImage(char *bufferName );*/ //////////////////////////////////////////////////////////// // Drift scan methods // Begins clocking and digitization of a single line of data beginning with a vertical clock // sequence and ending with a buffer full of line data. Poll the CameraStatus property to // determine when the data is ready for download. bool DigitizeLine(); // Returns the pLineData parameter which is a pointer to unsigned short data with NumX elements. bool GetLine( unsigned short* pLineData, short& xSize ); /* TODO enable this back after removing some deps */ /*bool BufferDriftScan(char *bufferName, int delay, int rowCount, int nblock , int npipe);*/ //////////////////////////////////////////////////////////// // Easy to use methods // Combination of the Expose and GetImage methods. Blocks calling thread for duration // of exposure and readout. bool Snap( double Duration, bool Light, unsigned short* pImageData, short& xSize, short& ySize ); // Internal variables to keep track of things that can not be read from the firmware // directly, or are a combination of firmware setting bool m_TDI; // Time drift integration mode bool m_WaitingforTrigger; // camera is waiting for external trigger bool m_WaitingforImage; // camera is exposing and wiating for an to available bool m_WaitingforLine; // camera is clocking and digitizing a row of data short m_RegisterOffset; // Offset from base address used in parallel port systems. short m_FilterPosition; // Current filter position short m_FilterStepPos; // Current filter position in our internal array bool m_Shutter; // Last known shutter state Camera_Status m_Status; // Last known camera status Camera_Interface m_Interface; // String acronyms may be used in INI file. // 0 or ISA: Industry Standard Architecture bus // 1 or PPI: Parallel Port Interface // 2 or PCI: Peripheral Component Interface Camera_SensorType m_SensorType; // 0 or CCD: Charge Coupled Device // 1 or CMOS: Complementary Metal-Oxide-Silicon Camera_CoolerStatus m_CoolerStatus; // Last known cooler status. unsigned int m_IRQMask; // Set of IRQs masked on user request // 0: Off // 1: Ramping to set point // 2: Correcting // 3: Ramping to ambient // 4: At ambient // 5: Max cooling limit // 6: Min cooling limit // 7: At set point // Latched public variables used during Exposure..GetImage sequence short m_ExposureBinX, m_ExposureBinY; // Horizontal and vertical binning. short m_ExposureStartX, m_ExposureStartY; // Subframe start position in unbinned pixels. short m_ExposureNumX, m_ExposureNumY; // Subframe size in binned pixels. short m_ExposureColumns, m_ExposureRows; // Total columns/rows on CCD (physical). short m_ExposureSkipC, m_ExposureSkipR; // Deleted data columns/rows not to be displayed or saved to disk. short m_ExposureHFlush, m_ExposureVFlush; // Horizontal/Vertical flush binning. short m_ExposureBIC, m_ExposureBIR; // Before Image Column/Row count (dark non-imaging pixels). unsigned short m_ExposureAIC; // Calculated After Image Column count (dark non-imaging pixels). unsigned short m_ExposureRemainingLines; // Number of lines to be clocked out by GetImage unsigned short m_ExposureAIR; // Number of lines to be flushed after GetImage //////////////////////////////////////////////////////////// // Write register shadow variables unsigned short m_RegShadow[ NumWriteRegisters ]; unsigned short m_FastShutterBits_Mode; // Mask to enable fast shutter mode unsigned short m_FastShutterBits_Test; // Mask to enable fast shutter mode //////////////////////////////////////////////////////////// // Internal helper routines void LoadLineCounter( unsigned short rows ); void LoadColumnLayout( unsigned short aic, unsigned short bic, unsigned short pixels ); void LoadTimerAndBinning( double Duration, unsigned short HBin, unsigned short VBin ); void StartFlushing(); void StopFlushing(); void InitDefaults(); #ifndef WITHPPI long ReadImage(short unsigned int *); long InternalReadLine(bool, long int, long int, unsigned short *); #endif private: unsigned short m_BaseAddressp2; unsigned int saveIRQS; int fileHandle; #ifdef WITHPPI inline void RegisterSelect( unsigned short reg ); inline unsigned short INPW(); inline void OUTPW( unsigned short val ); #endif }; #endif // !defined(AFX_CAMERAIO_H__A2882C82_7CFB_11D4_9155_0060676644C1__INCLUDED_) indi-0.5/src/apogee/stdafx.h0000644000175000017500000000236110610474640013606 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #if !defined(STDAFX__INCLUDED_) #define STDAFX__INCLUDED_ #ifdef __linux__ #include #include #include #include #define ULONG unsigned long #define USHORT unsigned short #define PUSHORT unsigned short * #define BYTE unsigned char #define DWORD long #define BOOLEAN unsigned long #define INTERNET_OPEN_TYPE_DIRECT 1 #define INTERNET_FLAG_NO_CACHE_WRITE 1 #define INTERNET_FLAG_KEEP_CONNECTION 1 #define Sleep(x) usleep(1000*x) #endif #endif indi-0.5/src/apogee/ApnCamData_CCD3011LS.h0000644000175000017500000000336110610474640015464 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD3011LS.h: Interface file for the CApnCamData_CCD3011LS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD3011LS : public CApnCamData { public: CApnCamData_CCD3011LS(); virtual ~CApnCamData_CCD3011LS(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_CCD4710LS5.h0000644000175000017500000000453710610474640015566 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /*************************************************************************** * * * 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. * * * ***************************************************************************/ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4710LS5.h: Interface file for the CApnCamData_CCD4710LS5 class. // ///////////////////////////////////////////////////////////// #include "ApnCamData.h" class CApnCamData_CCD4710LS5 : public CApnCamData { public: CApnCamData_CCD4710LS5(); virtual ~CApnCamData_CCD4710LS5(); void Initialize(); private: void set_vpattern(); void set_hpattern_clamp_sixteen(); void set_hpattern_skip_sixteen(); void set_hpattern_roi_sixteen(); void set_hpattern_clamp_twelve(); void set_hpattern_skip_twelve(); void set_hpattern_roi_twelve(); void set_hpattern( APN_HPATTERN_FILE *Pattern, unsigned short Mask, unsigned short BinningLimit, unsigned short RefNumElements, unsigned short SigNumElements, unsigned short BinNumElements[], unsigned short RefPatternData[], unsigned short SigPatternData[], unsigned short BinPatternData[][APN_MAX_PATTERN_ENTRIES] ); }; indi-0.5/src/apogee/ApnCamData_CCD4720LS.cpp0000644000175000017500000005223410610474646016040 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD4720LS.cpp: Implementation file for the CApnCamData_CCD4720LS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD4720LS.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD4720LS::CApnCamData_CCD4720LS() { } CApnCamData_CCD4720LS::~CApnCamData_CCD4720LS() { } void CApnCamData_CCD4720LS::Initialize() { strcpy( m_Sensor, "CCD4720LS" ); strcpy( m_CameraModel, "4720" ); m_CameraId = 24; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 1072; m_ImagingColumns = 1024; m_ClampColumns = 24; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 24; m_TotalRows = 2057; m_ImagingRows = 1024; m_UnderscanRows = 1033; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = true; m_RowOffsetBinning = 1033; m_HFlushDisable = false; m_ShutterCloseDelay = 0; m_PixelSizeX = 13; m_PixelSizeY = 13; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 1.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD4720LS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 23; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/apogee/ApnSerial_USB.cpp0000644000175000017500000000423610610474646015250 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // ApnSerial_USB.cpp: implementation of the CApnSerial_USB class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "apogee.h" #include "ApnSerial_USB.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CApnSerial_USB::CApnSerial_USB() { } CApnSerial_USB::~CApnSerial_USB() { } bool CApnSerial_USB::InitPort( unsigned long CamIdA, unsigned short CamIdB, unsigned short SerialId ) { return true; } bool CApnSerial_USB::ClosePort() { return true; } bool CApnSerial_USB::GetBaudRate( unsigned long *BaudRate ) { return true; } bool CApnSerial_USB::SetBaudRate( unsigned long BaudRate ) { return true; } bool CApnSerial_USB::GetFlowControl( Apn_SerialFlowControl *FlowControl ) { return true; } bool CApnSerial_USB::SetFlowControl( Apn_SerialFlowControl FlowControl ) { return true; } bool CApnSerial_USB::GetParity( Apn_SerialParity *Parity ) { return true; } bool CApnSerial_USB::SetParity( Apn_SerialParity Parity ) { return true; } bool CApnSerial_USB::Read( char *ReadBuffer, unsigned short *ReadCount ) { return true; } bool CApnSerial_USB::Write( char *WriteBuffer, unsigned short WriteCount ) { return true; } indi-0.5/src/apogee/ApnCamData_CCD5520HS.cpp0000644000175000017500000005573410610474646016043 0ustar jrjr/* Apogee Control Library Copyright (C) 2001-2006 Dave Mills (rfactory@theriver.com) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ///////////////////////////////////////////////////////////// // // ApnCamData_CCD5520HS.cpp: Implementation file for the CApnCamData_CCD5520HS class. // ///////////////////////////////////////////////////////////// #include "ApnCamData_CCD5520HS.h" #include #include #include ///////////////////////////////////////////////////////////// // Construction/Destruction ///////////////////////////////////////////////////////////// CApnCamData_CCD5520HS::CApnCamData_CCD5520HS() { } CApnCamData_CCD5520HS::~CApnCamData_CCD5520HS() { } void CApnCamData_CCD5520HS::Initialize() { strcpy( m_Sensor, "CCD5520HS" ); strcpy( m_CameraModel, "55" ); m_CameraId = 23; m_InterlineCCD = false; m_SupportsSerialA = true; m_SupportsSerialB = true; m_SensorTypeCCD = true; m_TotalColumns = 804; m_ImagingColumns = 770; m_ClampColumns = 17; m_PreRoiSkipColumns = 0; m_PostRoiSkipColumns = 0; m_OverscanColumns = 17; m_TotalRows = 1152; m_ImagingRows = 1152; m_UnderscanRows = 0; m_OverscanRows = 0; m_VFlushBinning = 4; m_EnableSingleRowOffset = false; m_RowOffsetBinning = 1; m_HFlushDisable = false; m_ShutterCloseDelay = 20; m_PixelSizeX = 22.5; m_PixelSizeY = 22.5; m_Color = false; m_ReportedGainSixteenBit = 2; m_MinSuggestedExpTime = 20.0; m_CoolingSupported = true; m_RegulatedCoolingSupported = true; m_TempSetPoint = -20.0; m_TempRampRateOne = 1000; m_TempRampRateTwo = 2000; m_TempBackoffPoint = 2.0; m_DefaultGainTwelveBit = 300; m_DefaultOffsetTwelveBit = 100; m_DefaultRVoltage = 1000; set_vpattern(); set_hpattern_clamp_sixteen(); set_hpattern_skip_sixteen(); set_hpattern_roi_sixteen(); set_hpattern_clamp_twelve(); set_hpattern_skip_twelve(); set_hpattern_roi_twelve(); } void CApnCamData_CCD5520HS::set_vpattern() { const unsigned short Mask = 0x0; const unsigned short NumElements = 247; unsigned short Pattern[NumElements] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x000A, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000 }; m_VerticalPattern.Mask = Mask; m_VerticalPattern.NumElements = NumElements; m_VerticalPattern.PatternData = (unsigned short *)malloc(NumElements * sizeof(unsigned short)); for ( int i=0; iMask = Mask; Pattern->BinningLimit = BinningLimit; Pattern->RefNumElements = RefNumElements; Pattern->SigNumElements = SigNumElements; if ( RefNumElements > 0 ) { Pattern->RefPatternData = (unsigned short *)malloc(RefNumElements * sizeof(unsigned short)); for ( i=0; iRefPatternData[i] = RefPatternData[i]; } } if ( SigNumElements > 0 ) { Pattern->SigPatternData = (unsigned short *)malloc(SigNumElements * sizeof(unsigned short)); for ( i=0; iSigPatternData[i] = SigPatternData[i]; } } if ( BinningLimit > 0 ) { for ( i=0; iBinNumElements[i] = BinNumElements[i]; Pattern->BinPatternData[i] = (unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short)); for ( j=0; jBinPatternData[i][j] = BinPatternData[i][j]; } } } } indi-0.5/src/indi_lpi.cpp0000644000175000017500000000650110610474326013200 0ustar jrjr/* Meade LPI Experimental driver Copyright (C) 2005 by Jasem Mutlaq This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "v4ldriver.h" class Meade_LPI : public V4L_Driver { public: Meade_LPI(); ~Meade_LPI(); #ifdef HAVE_LINUX_VIDEODEV2_H void connectCamera(void); #endif }; Meade_LPI::Meade_LPI() : V4L_Driver() { } Meade_LPI::~Meade_LPI() { } #ifdef HAVE_LINUX_VIDEODEV2_H void Meade_LPI::connectCamera() { char errmsg[ERRMSGSIZ]; switch (PowerS[0].s) { case ISS_ON: if (v4l_base->connectCam(PortT[0].text, errmsg, V4L2_PIX_FMT_SBGGR8, 352, 288) < 0) { PowerSP.s = IPS_IDLE; PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; IDSetSwitch(&PowerSP, "Error: unable to open device"); IDLog("Error: %s\n", errmsg); return; } /* Sucess! */ PowerS[0].s = ISS_ON; PowerS[1].s = ISS_OFF; PowerSP.s = IPS_OK; IDSetSwitch(&PowerSP, "Meade LPI is online. Retrieving basic data."); v4l_base->registerCallback(newFrame, this); V4LFrame->compressedFrame = (unsigned char *) malloc (sizeof(unsigned char) * 1); IDLog("Meade LPI is online. Retrieving basic data.\n"); getBasicData(); break; case ISS_OFF: PowerS[0].s = ISS_OFF; PowerS[1].s = ISS_ON; PowerSP.s = IPS_IDLE; free(V4LFrame->compressedFrame); V4LFrame->compressedFrame = NULL; v4l_base->disconnectCam(); IDSetSwitch(&PowerSP, "Meade LPI is offline."); break; } } #endif Meade_LPI *MainCam = NULL; /* Main and only camera */ /* send client definitions of all properties */ void ISInit() { if (MainCam == NULL) { MainCam = new Meade_LPI(); MainCam->initProperties("Meade LPI"); MainCam->initCamBase(); } } void ISGetProperties (const char *dev) { ISInit(); MainCam->ISGetProperties(dev); } void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { ISInit(); MainCam->ISNewSwitch(dev, name, states, names, n); } void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) { ISInit(); MainCam->ISNewText(dev, name, texts, names, n); } void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) { ISInit(); MainCam->ISNewNumber(dev, name, values, names, n); } void ISNewBLOB (const char */*dev*/, const char */*name*/, int */*sizes[]*/, char **/*blobs[]*/, char **/*formats[]*/, char **/*names[]*/, int /*n*/) { // We use this if we're receiving binary data from the client. Most likely we won't for this driver. } indi-0.5/src/indidrivermain.c0000644000175000017500000007755510610474331014072 0ustar jrjr#if 0 INDI Copyright (C) 2003-2006 Elwood C. Downey Modified by Jasem Mutlaq (2003-2006) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif /* main() for one INDI driver process. * Drivers define IS*() functions we call to deliver INDI XML arriving on stdin. * Drivers call ID*() functions to send INDI XML commands to stdout. * Drivers call IE*() functions to build an event-driver program. * Drivers call IU*() functions to perform various common utility tasks. * Troubles are reported on stderr then we exit. * * This requires liblilxml. */ #include #include #include #include #include #include #include #include #include #include "lilxml.h" #include "base64.h" #include "eventloop.h" #include "indidevapi.h" #include "indicom.h" #include "observer.h" static void usage(void); static void clientMsgCB(int fd, void *arg); static int dispatch (XMLEle *root, char msg[]); static int crackDN (XMLEle *root, char **dev, char **name, char msg[]); static int isPropDefined(const char *property_name); const char *pstateStr(IPState s); const char *sstateStr(ISState s); const char *ruleStr(ISRule r); const char *permStr(IPerm p); static int nroCheck; /* # of elements in roCheck */ static int verbose; /* chatty */ char *me; /* a.out name */ static LilXML *clixml; /* XML parser context */ /* insure RO properties are never modified. RO Sanity Check */ typedef struct { char propName[MAXINDINAME]; IPerm perm; } ROSC; static ROSC *roCheck; int main (int ac, char *av[]) { #ifndef _WIN32 setgid( getgid() ); setuid( getuid() ); if (geteuid() != getuid()) exit(255); #endif /* save handy pointer to our base name */ for (me = av[0]; av[0][0]; av[0]++) if (av[0][0] == '/') me = &av[0][1]; /* crack args */ while (--ac && (*++av)[0] == '-') while (*++(*av)) switch (*(*av)) { case 'v': /* verbose */ verbose++; break; default: usage(); } /* ac remaining args starting at av[0] */ if (ac > 0) usage(); /* init */ clixml = newLilXML(); addCallback (0, clientMsgCB, NULL); nroCheck = 0; roCheck = NULL; /* service client */ eventLoop(); /* eh?? */ fprintf (stderr, "%s: inf loop ended\n", me); return (1); } /* Return 1 is property is already cached, 0 otherwise */ static int isPropDefined(const char *property_name) { int i=0; for (i=0; i < nroCheck; i++) if (!strcmp(property_name, roCheck[i].propName)) return 1; return 0; } /* functions we define that drivers may call */ /* tell client to create a text vector property */ void IDDefText (const ITextVectorProperty *tvp, const char *fmt, ...) { int i; ROSC *SC; printf ("device); printf (" name='%s'\n", tvp->name); printf (" label='%s'\n", tvp->label); printf (" group='%s'\n", tvp->group); printf (" state='%s'\n", pstateStr(tvp->s)); printf (" perm='%s'\n", permStr(tvp->p)); printf (" timeout='%g'\n", tvp->timeout); printf (" timestamp='%s'\n", timestamp()); if (fmt) { va_list ap; va_start (ap, fmt); printf (" message='"); vprintf (fmt, ap); printf ("'\n"); va_end (ap); } printf (">\n"); for (i = 0; i < tvp->ntp; i++) { IText *tp = &tvp->tp[i]; printf (" name); printf (" label='%s'>\n", tp->label); printf (" %s\n", tp->text ? tp->text : ""); printf (" \n"); } printf ("\n"); if (!isPropDefined(tvp->name)) { /* Add this property to insure proper sanity check */ roCheck = roCheck ? (ROSC *) realloc ( roCheck, sizeof(ROSC) * (nroCheck+1)) : (ROSC *) malloc ( sizeof(ROSC)); SC = &roCheck[nroCheck++]; strcpy(SC->propName, tvp->name); SC->perm = tvp->p; } fflush (stdout); } /* tell client to create a new numeric vector property */ void IDDefNumber (const INumberVectorProperty *n, const char *fmt, ...) { int i; ROSC *SC; printf ("device); printf (" name='%s'\n", n->name); printf (" label='%s'\n", n->label); printf (" group='%s'\n", n->group); printf (" state='%s'\n", pstateStr(n->s)); printf (" perm='%s'\n", permStr(n->p)); printf (" timeout='%g'\n", n->timeout); printf (" timestamp='%s'\n", timestamp()); if (fmt) { va_list ap; va_start (ap, fmt); printf (" message='"); vprintf (fmt, ap); printf ("'\n"); va_end (ap); } printf (">\n"); for (i = 0; i < n->nnp; i++) { INumber *np = &n->np[i]; printf (" name); printf (" label='%s'\n", np->label); printf (" format='%s'\n", np->format); printf (" min='%g'\n", np->min); printf (" max='%g'\n", np->max); printf (" step='%g'>\n", np->step); printf (" %g\n", np->value); printf (" \n"); } printf ("\n"); if (!isPropDefined(n->name)) { /* Add this property to insure proper sanity check */ roCheck = roCheck ? (ROSC *) realloc ( roCheck, sizeof(ROSC) * (nroCheck+1)) : (ROSC *) malloc ( sizeof(ROSC)); SC = &roCheck[nroCheck++]; strcpy(SC->propName, n->name); SC->perm = n->p; } fflush (stdout); } /* tell client to create a new switch vector property */ void IDDefSwitch (const ISwitchVectorProperty *s, const char *fmt, ...) { int i; ROSC *SC; printf ("device); printf (" name='%s'\n", s->name); printf (" label='%s'\n", s->label); printf (" group='%s'\n", s->group); printf (" state='%s'\n", pstateStr(s->s)); printf (" perm='%s'\n", permStr(s->p)); printf (" rule='%s'\n", ruleStr (s->r)); printf (" timeout='%g'\n", s->timeout); printf (" timestamp='%s'\n", timestamp()); if (fmt) { va_list ap; va_start (ap, fmt); printf (" message='"); vprintf (fmt, ap); printf ("'\n"); va_end (ap); } printf (">\n"); for (i = 0; i < s->nsp; i++) { ISwitch *sp = &s->sp[i]; printf (" name); printf (" label='%s'>\n", sp->label); printf (" %s\n", sstateStr(sp->s)); printf (" \n"); } printf ("\n"); if (!isPropDefined(s->name)) { /* Add this property to insure proper sanity check */ roCheck = roCheck ? (ROSC *) realloc ( roCheck, sizeof(ROSC) * (nroCheck+1)) : (ROSC *) malloc ( sizeof(ROSC)); SC = &roCheck[nroCheck++]; strcpy(SC->propName, s->name); SC->perm = s->p; } fflush (stdout); } /* tell client to create a new lights vector property */ void IDDefLight (const ILightVectorProperty *lvp, const char *fmt, ...) { int i; printf ("device); printf (" name='%s'\n", lvp->name); printf (" label='%s'\n", lvp->label); printf (" group='%s'\n", lvp->group); printf (" state='%s'\n", pstateStr(lvp->s)); printf (" timestamp='%s'\n", timestamp()); if (fmt) { va_list ap; va_start (ap, fmt); printf (" message='"); vprintf (fmt, ap); printf ("'\n"); va_end (ap); } printf (">\n"); for (i = 0; i < lvp->nlp; i++) { ILight *lp = &lvp->lp[i]; printf (" name); printf (" label='%s'>\n", lp->label); printf (" %s\n", pstateStr(lp->s)); printf (" \n"); } printf ("\n"); fflush (stdout); } /* tell client to create a new BLOB vector property */ void IDDefBLOB (const IBLOBVectorProperty *b, const char *fmt, ...) { int i; ROSC *SC; printf ("device); printf (" name='%s'\n", b->name); printf (" label='%s'\n", b->label); printf (" group='%s'\n", b->group); printf (" state='%s'\n", pstateStr(b->s)); printf (" perm='%s'\n", permStr(b->p)); printf (" timeout='%g'\n", b->timeout); printf (" timestamp='%s'\n", timestamp()); if (fmt) { va_list ap; va_start (ap, fmt); printf (" message='"); vprintf (fmt, ap); printf ("'\n"); va_end (ap); } printf (">\n"); for (i = 0; i < b->nbp; i++) { IBLOB *bp = &b->bp[i]; printf (" name); printf (" label='%s'\n", bp->label); printf (" />\n"); } printf ("\n"); if (!isPropDefined(b->name)) { /* Add this property to insure proper sanity check */ roCheck = roCheck ? (ROSC *) realloc ( roCheck, sizeof(ROSC) * (nroCheck+1)) : (ROSC *) malloc ( sizeof(ROSC)); SC = &roCheck[nroCheck++]; strcpy(SC->propName, b->name); SC->perm = b->p; } fflush (stdout); } /* tell client to update an existing text vector property */ void IDSetText (const ITextVectorProperty *tvp, const char *fmt, ...) { int i; printf ("device); printf (" name='%s'\n", tvp->name); printf (" state='%s'\n", pstateStr(tvp->s)); printf (" timeout='%g'\n", tvp->timeout); printf (" timestamp='%s'\n", timestamp()); if (fmt) { va_list ap; va_start (ap, fmt); printf (" message='"); vprintf (fmt, ap); printf ("'\n"); va_end (ap); } printf (">\n"); for (i = 0; i < tvp->ntp; i++) { IText *tp = &tvp->tp[i]; printf (" \n", tp->name); printf (" %s\n", tp->text ? tp->text : ""); printf (" \n"); } printf ("\n"); fflush (stdout); } /* tell client to update an existing numeric vector property */ void IDSetNumber (const INumberVectorProperty *nvp, const char *fmt, ...) { int i; printf ("device); printf (" name='%s'\n", nvp->name); printf (" state='%s'\n", pstateStr(nvp->s)); printf (" timeout='%g'\n", nvp->timeout); printf (" timestamp='%s'\n", timestamp()); if (fmt) { va_list ap; va_start (ap, fmt); printf (" message='"); vprintf (fmt, ap); printf ("'\n"); va_end (ap); } printf (">\n"); for (i = 0; i < nvp->nnp; i++) { INumber *np = &nvp->np[i]; printf (" \n", np->name); printf (" %.10g\n", np->value); printf (" \n"); } printf ("\n"); fflush (stdout); } /* tell client to update an existing switch vector property */ void IDSetSwitch (const ISwitchVectorProperty *svp, const char *fmt, ...) { int i; printf ("device); printf (" name='%s'\n", svp->name); printf (" state='%s'\n", pstateStr(svp->s)); printf (" timeout='%g'\n", svp->timeout); printf (" timestamp='%s'\n", timestamp()); if (fmt) { va_list ap; va_start (ap, fmt); printf (" message='"); vprintf (fmt, ap); printf ("'\n"); va_end (ap); } printf (">\n"); for (i = 0; i < svp->nsp; i++) { ISwitch *sp = &svp->sp[i]; printf (" \n", sp->name); printf (" %s\n", sstateStr(sp->s)); printf (" \n"); } printf ("\n"); fflush (stdout); } /* tell client to update an existing lights vector property */ void IDSetLight (const ILightVectorProperty *lvp, const char *fmt, ...) { int i; printf ("device); printf (" name='%s'\n", lvp->name); printf (" state='%s'\n", pstateStr(lvp->s)); printf (" timestamp='%s'\n", timestamp()); if (fmt) { va_list ap; va_start (ap, fmt); printf (" message='"); vprintf (fmt, ap); printf ("'\n"); va_end (ap); } printf (">\n"); for (i = 0; i < lvp->nlp; i++) { ILight *lp = &lvp->lp[i]; printf (" \n", lp->name); printf (" %s\n", pstateStr(lp->s)); printf (" \n"); } printf ("\n"); fflush (stdout); } /* tell client to update an existing BLOB vector property */ void IDSetBLOB (const IBLOBVectorProperty *bvp, const char *fmt, ...) { int i; printf ("device); printf (" name='%s'\n", bvp->name); printf (" state='%s'\n", pstateStr(bvp->s)); printf (" timeout='%g'\n", bvp->timeout); printf (" timestamp='%s'\n", timestamp()); if (fmt) { va_list ap; va_start (ap, fmt); printf (" message='"); vprintf (fmt, ap); printf ("'\n"); va_end (ap); } printf (">\n"); for (i = 0; i < bvp->nbp; i++) { IBLOB *bp = &bvp->bp[i]; char *encblob; int j, l; printf (" name); printf (" size='%d'\n", bp->size); printf (" format='%s'>\n", bp->format); encblob = malloc (4*bp->bloblen/3+4); l = to64frombits(encblob, bp->blob, bp->bloblen); for (j = 0; j < l; j += 72) printf ("%.72s\n", encblob+j); free (encblob); printf (" \n"); } printf ("\n"); fflush (stdout); } /* tell client to update min/max elements of an existing number vector property */ void IUUpdateMinMax(INumberVectorProperty *nvp) { int i; printf ("device); printf (" name='%s'\n", nvp->name); printf (" state='%s'\n", pstateStr(nvp->s)); printf (" timeout='%g'\n", nvp->timeout); printf (" timestamp='%s'\n", timestamp()); printf (">\n"); for (i = 0; i < nvp->nnp; i++) { INumber *np = &nvp->np[i]; printf (" name); printf (" min='%g'\n", np->min); printf (" max='%g'\n", np->max); printf (" step='%g'\n", np->step); printf(">\n"); printf (" %g\n", np->value); printf (" \n"); } printf ("\n"); fflush (stdout); } /* send client a message for a specific device or at large if !dev */ void IDMessage (const char *dev, const char *fmt, ...) { printf ("\n"); fflush (stdout); } /* tell Client to delete the property with given name on given device, or * entire device if !name */ void IDDelete (const char *dev, const char *name, const char *fmt, ...) { printf ("\n"); fflush (stdout); } /* "INDI" wrappers to the more generic eventloop facility. */ int IEAddCallback (int readfiledes, IE_CBF *fp, void *p) { return (addCallback (readfiledes, (CBF*)fp, p)); } void IERmCallback (int callbackid) { rmCallback (callbackid); } int IEAddTimer (int millisecs, IE_TCF *fp, void *p) { return (addTimer (millisecs, (TCF*)fp, p)); } void IERmTimer (int timerid) { rmTimer (timerid); } int IEAddWorkProc (IE_WPF *fp, void *p) { return (addWorkProc ((WPF*)fp, p)); } void IERmWorkProc (int workprocid) { rmWorkProc (workprocid); } /* find a member of an IText vector, else NULL */ IText * IUFindText (const ITextVectorProperty *tvp, const char *name) { int i; for (i = 0; i < tvp->ntp; i++) if (strcmp (tvp->tp[i].name, name) == 0) return (&tvp->tp[i]); fprintf (stderr, "No IText '%s' in %s.%s\n",name,tvp->device,tvp->name); return (NULL); } /* find a member of an INumber vector, else NULL */ INumber * IUFindNumber(const INumberVectorProperty *nvp, const char *name) { int i; for (i = 0; i < nvp->nnp; i++) if (strcmp (nvp->np[i].name, name) == 0) return (&nvp->np[i]); fprintf(stderr,"No INumber '%s' in %s.%s\n",name,nvp->device,nvp->name); return (NULL); } /* find a member of an ISwitch vector, else NULL */ ISwitch * IUFindSwitch(const ISwitchVectorProperty *svp, const char *name) { int i; for (i = 0; i < svp->nsp; i++) if (strcmp (svp->sp[i].name, name) == 0) return (&svp->sp[i]); fprintf(stderr,"No ISwitch '%s' in %s.%s\n",name,svp->device,svp->name); return (NULL); } /* find an ON member of an ISwitch vector, else NULL. * N.B. user must make sense of result with ISRule in mind. */ ISwitch * IUFindOnSwitch(const ISwitchVectorProperty *svp) { int i; for (i = 0; i < svp->nsp; i++) if (svp->sp[i].s == ISS_ON) return (&svp->sp[i]); /*fprintf(stderr, "No ISwitch On in %s.%s\n", svp->device, svp->name);*/ return (NULL); } /* Set all switches to off */ void IUResetSwitches(const ISwitchVectorProperty *svp) { int i; for (i = 0; i < svp->nsp; i++) svp->sp[i].s = ISS_OFF; } /* Update property switches in accord with states and names. */ int IUUpdateSwitches(ISwitchVectorProperty *svp, ISState *states, char *names[], int n) { int i=0; ISwitch *sp; char sn[MAXINDINAME]; /* store On switch name */ if (svp->r == ISR_1OFMANY) { sp = IUFindOnSwitch(svp); if (sp) strncpy(sn, sp->name, MAXINDINAME); IUResetSwitches(svp); } for (i = 0; i < n ; i++) { sp = IUFindSwitch(svp, names[i]); if (!sp) { svp->s = IPS_IDLE; IDSetSwitch(svp, "Error: %s is not a member of %s property.", names[i], svp->name); return -1; } sp->s = states[i]; } /* Consistency checks for ISR_1OFMANY after update. */ if (svp->r == ISR_1OFMANY) { int t_count=0; for (i=0; i < svp->nsp; i++) { if (svp->sp[i].s == ISS_ON) t_count++; } if (t_count != 1) { IUResetSwitches(svp); sp = IUFindSwitch(svp, sn); if (sp) sp->s = ISS_ON; svp->s = IPS_IDLE; IDSetSwitch(svp, "Error: invalid state switch for property %s. %s.", svp->name, t_count == 0 ? "No switch is on" : "Too many switches are on"); return -1; } } return 0; } /* Update property numbers in accord with values and names */ int IUUpdateNumbers(INumberVectorProperty *nvp, double values[], char *names[], int n) { int i=0; INumber *np; for (i = 0; i < n; i++) { np = IUFindNumber(nvp, names[i]); if (!np) { nvp->s = IPS_IDLE; IDSetNumber(nvp, "Error: %s is not a member of %s property.", names[i], nvp->name); return -1; } if (values[i] < np->min || values[i] > np->max) { nvp->s = IPS_IDLE; IDSetNumber(nvp, "Error: Invalid range. Valid range is from %g to %g", np->min, np->max); return -1; } } /* First loop checks for error, second loop set all values atomically*/ for (i=0; i < n; i++) { np = IUFindNumber(nvp, names[i]); np->value = values[i]; } return 0; } /* Update property text in accord with texts and names */ int IUUpdateTexts(ITextVectorProperty *tvp, char * texts[], char *names[], int n) { int i=0; IText *tp; for (i = 0; i < n; i++) { tp = IUFindText(tvp, names[i]); if (!tp) { tvp->s = IPS_IDLE; IDSetText(tvp, "Error: %s is not a member of %s property.", names[i], tvp->name); return -1; } } /* First loop checks for error, second loop set all values atomically*/ for (i=0; i < n; i++) { tp = IUFindText(tvp, names[i]); IUSaveText(tp, texts[i]); } return 0; } /* save malloced copy of newtext in tp->text, reusing if not first time */ void IUSaveText (IText *tp, const char *newtext) { /* seed for realloc */ if (tp->text == NULL) tp->text = malloc (1); /* copy in fresh string */ tp->text = strcpy (realloc (tp->text, strlen(newtext)+1), newtext); } void IUFillSwitch(ISwitch *sp, const char *name, const char * label, ISState s) { strcpy(sp->name, name); strcpy(sp->label, label); sp->s = s; sp->svp = NULL; sp->aux = NULL; } void IUFillNumber(INumber *np, const char *name, const char * label, const char *format, double min, double max, double step, double value) { strcpy(np->name, name); strcpy(np->label, label); strcpy(np->format, format); np->min = min; np->max = max; np->step = step; np->value = value; np->nvp = NULL; np->aux0 = NULL; np->aux1 = NULL; } void IUFillText(IText *tp, const char *name, const char * label, const char *initialText) { strcpy(tp->name, name); strcpy(tp->label, label); tp->text = NULL; tp->tvp = NULL; tp->aux0 = NULL; tp->aux1 = NULL; IUSaveText(tp, initialText); } void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char * dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s) { strcpy(svp->device, dev); strcpy(svp->name, name); strcpy(svp->label, label); strcpy(svp->group, group); strcpy(svp->timestamp, ""); svp->p = p; svp->r = r; svp->timeout = timeout; svp->s = s; svp->sp = sp; svp->nsp = nsp; } void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char * dev, const char *name, const char *label, const char* group, IPerm p, double timeout, IPState s) { strcpy(nvp->device, dev); strcpy(nvp->name, name); strcpy(nvp->label, label); strcpy(nvp->group, group); strcpy(nvp->timestamp, ""); nvp->p = p; nvp->timeout = timeout; nvp->s = s; nvp->np = np; nvp->nnp = nnp; } void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char * dev, const char *name, const char *label, const char* group, IPerm p, double timeout, IPState s) { strcpy(tvp->device, dev); strcpy(tvp->name, name); strcpy(tvp->label, label); strcpy(tvp->group, group); strcpy(tvp->timestamp, ""); tvp->p = p; tvp->timeout = timeout; tvp->s = s; tvp->tp = tp; tvp->ntp = ntp; } /* print usage message and exit (1) */ static void usage(void) { fprintf (stderr, "Usage: %s [options]\n", me); fprintf (stderr, "Purpose: INDI Device driver framework.\n"); fprintf (stderr, "Options:\n"); fprintf (stderr, " -v : more verbose to stderr\n"); exit (1); } /* callback when INDI client message arrives on stdin. * collect and dispatch when see outter element closure. * exit if OS trouble or see incompatable INDI version. * arg is not used. */ static void clientMsgCB (int fd, void *arg) { char buf[1024], msg[1024], *bp; int nr; arg=arg; /* one read */ nr = read (fd, buf, sizeof(buf)); if (nr < 0) { fprintf (stderr, "%s: %s\n", me, strerror(errno)); exit(1); } if (nr == 0) { fprintf (stderr, "%s: EOF\n", me); exit(1); } /* crack and dispatch when complete */ for (bp = buf; nr-- > 0; bp++) { XMLEle *root = readXMLEle (clixml, *bp, msg); if (root) { if (dispatch (root, msg) < 0) fprintf (stderr, "%s dispatch error: %s\n", me, msg); delXMLEle (root); } else if (msg[0]) fprintf (stderr, "%s XML error: %s\n", me, msg); } } /* crack the given INDI XML element and call driver's IS* entry points as they * are recognized. * return 0 if ok else -1 with reason in msg[]. * N.B. exit if getProperties does not proclaim a compatible version. */ static int dispatch (XMLEle *root, char msg[]) { XMLEle *epx; int n; int i=0; if (verbose) prXMLEle (stderr, root, 0); /* check tag in surmised decreasing order of likelyhood */ if (!strcmp (tagXMLEle(root), "newNumberVector")) { static double *doubles; static char **names; static int maxn; char *dev, *name; /* pull out device and name */ if (crackDN (root, &dev, &name, msg) < 0) return (-1); /* seed for reallocs */ if (!doubles) { doubles = (double *) malloc (1); names = (char **) malloc (1); } /* pull out each name/value pair */ for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) { if (strcmp (tagXMLEle(epx), "oneNumber") == 0) { XMLAtt *na = findXMLAtt (epx, "name"); if (na) { if (n >= maxn) { /* grow for this and another */ int newsz = (maxn=n+1)*sizeof(double); doubles = (double *) realloc(doubles,newsz); newsz = maxn*sizeof(char *); names = (char **) realloc (names, newsz); } if (f_scansexa (pcdataXMLEle(epx), &doubles[n]) < 0) IDMessage (dev,"%s: Bad format %s", name, pcdataXMLEle(epx)); else names[n++] = valuXMLAtt(na); } } } /* insure property is not RO */ for (i=0; i < nroCheck; i++) { if (!strcmp(roCheck[i].propName, name)) { if (roCheck[i].perm == IP_RO) return -1; } } /* invoke driver if something to do, but not an error if not */ if (n > 0) ISNewNumber (dev, name, doubles, names, n); else IDMessage(dev,"%s: newNumberVector with no valid members",name); return (0); } if (!strcmp (tagXMLEle(root), "newSwitchVector")) { static ISState *states; static char **names; static int maxn; char *dev, *name; /* pull out device and name */ if (crackDN (root, &dev, &name, msg) < 0) return (-1); /* seed for reallocs */ if (!states) { states = (ISState *) malloc (sizeof(void*)); names = (char **) malloc (sizeof(void*)); } /* pull out each name/state pair */ for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) { if (strcmp (tagXMLEle(epx), "oneSwitch") == 0) { XMLAtt *na = findXMLAtt (epx, "name"); if (na) { if (n >= maxn) { int newsz = (maxn=n+1)*sizeof(ISState); states = (ISState *) realloc(states, newsz); newsz = maxn*sizeof(char *); names = (char **) realloc (names, newsz); } if (strcmp (pcdataXMLEle(epx),"On") == 0) { states[n] = ISS_ON; names[n] = valuXMLAtt(na); n++; } else if (strcmp (pcdataXMLEle(epx),"Off") == 0) { states[n] = ISS_OFF; names[n] = valuXMLAtt(na); n++; } else IDMessage (dev, "%s: must be On or Off: %s", name, pcdataXMLEle(epx)); } } } /* insure property is not RO */ for (i=0; i < nroCheck; i++) { if (!strcmp(roCheck[i].propName, name)) { if (roCheck[i].perm == IP_RO) return -1; } } /* invoke driver if something to do, but not an error if not */ if (n > 0) ISNewSwitch (dev, name, states, names, n); else IDMessage(dev,"%s: newSwitchVector with no valid members",name); return (0); } if (!strcmp (tagXMLEle(root), "newTextVector")) { static char **texts; static char **names; static int maxn; char *dev, *name; /* pull out device and name */ if (crackDN (root, &dev, &name, msg) < 0) return (-1); /* seed for reallocs */ if (!texts) { texts = (char **) malloc (1); names = (char **) malloc (1); } /* pull out each name/text pair */ for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) { if (strcmp (tagXMLEle(epx), "oneText") == 0) { XMLAtt *na = findXMLAtt (epx, "name"); if (na) { if (n >= maxn) { int newsz = (maxn=n+1)*sizeof(char *); texts = (char **) realloc (texts, newsz); names = (char **) realloc (names, newsz); } texts[n] = pcdataXMLEle(epx); names[n] = valuXMLAtt(na); n++; } } } /* insure property is not RO */ for (i=0; i < nroCheck; i++) { if (!strcmp(roCheck[i].propName, name)) { if (roCheck[i].perm == IP_RO) return -1; } } /* invoke driver if something to do, but not an error if not */ if (n > 0) ISNewText (dev, name, texts, names, n); else IDMessage (dev, "%s: set with no valid members", name); return (0); } if (!strcmp (tagXMLEle(root), "newBLOBVector")) { static char **blobs; static char **names; static char **formats; static int *blobsizes; static int maxn; char *dev, *name; /* pull out device and name */ if (crackDN (root, &dev, &name, msg) < 0) return (-1); /* seed for reallocs */ if (!blobs) { blobs = (char **) malloc (sizeof(void*)); names = (char **) malloc (sizeof(void*)); formats = (char **) malloc (sizeof(void*)); blobsizes = (int *) malloc (sizeof(void*)); } /* pull out each name/BLOB pair */ for (n = 0, epx = nextXMLEle(root,1); epx; epx = nextXMLEle(root,0)) { if (strcmp (tagXMLEle(epx), "oneBLOB") == 0) { XMLAtt *na = findXMLAtt (epx, "name"); XMLAtt *fa = findXMLAtt (epx, "format"); XMLAtt *sa = findXMLAtt (epx, "size"); if (na && fa && sa) { if (n >= maxn) { int newsz = (maxn=n+1)*sizeof(char *); blobs = (char **) realloc (blobs, newsz); names = (char **) realloc (names, newsz); formats = (char **) realloc(formats,newsz); newsz = maxn*sizeof(int); blobsizes = (int *) realloc(blobsizes,newsz); } blobs[n] = pcdataXMLEle(epx); names[n] = valuXMLAtt(na); formats[n] = valuXMLAtt(fa); blobsizes[n] = atoi(valuXMLAtt(sa)); n++; } } } /* invoke driver if something to do, but not an error if not */ if (n > 0) ISNewBLOB (dev, name, blobsizes, blobs, formats, names, n); else IDMessage (dev, "%s: newBLOBVector with no valid members",name); return (0); } if (!strcmp (tagXMLEle(root), "getProperties")) { XMLAtt *ap; double v; /* check version */ ap = findXMLAtt (root, "version"); if (!ap) { fprintf (stderr, "%s: getProperties missing version\n", me); exit(1); } v = atof (valuXMLAtt(ap)); if (v > INDIV) { fprintf (stderr, "%s: client version %g > %g\n", me, v, INDIV); exit(1); } /* ok */ ap = findXMLAtt (root, "device"); ISGetProperties (ap ? valuXMLAtt(ap) : NULL); return (0); } else if (!processObservers(root)) return (0); sprintf (msg, "Unknown command: %s", tagXMLEle(root)); return(1); } /* pull out device and name attributes from root. * return 0 if ok else -1 with reason in msg[]. */ static int crackDN (XMLEle *root, char **dev, char **name, char msg[]) { XMLAtt *ap; ap = findXMLAtt (root, "device"); if (!ap) { sprintf (msg, "%s requires 'device' attribute", tagXMLEle(root)); return (-1); } *dev = valuXMLAtt(ap); ap = findXMLAtt (root, "name"); if (!ap) { sprintf (msg, "%s requires 'name' attribute", tagXMLEle(root)); return (-1); } *name = valuXMLAtt(ap); return (0); } /* return static string corresponding to the given property or light state */ const char * pstateStr (IPState s) { switch (s) { case IPS_IDLE: return ("Idle"); case IPS_OK: return ("Ok"); case IPS_BUSY: return ("Busy"); case IPS_ALERT: return ("Alert"); default: fprintf (stderr, "Impossible IPState %d\n", s); exit(1); } } /* return static string corresponding to the given switch state */ const char * sstateStr (ISState s) { switch (s) { case ISS_ON: return ("On"); case ISS_OFF: return ("Off"); default: fprintf (stderr, "Impossible ISState %d\n", s); exit(1); } } /* return static string corresponding to the given Rule */ const char * ruleStr (ISRule r) { switch (r) { case ISR_1OFMANY: return ("OneOfMany"); case ISR_ATMOST1: return ("AtMostOne"); case ISR_NOFMANY: return ("AnyOfMany"); default: fprintf (stderr, "Impossible ISRule %d\n", r); exit(1); } } /* return static string corresponding to the given IPerm */ const char * permStr (IPerm p) { switch (p) { case IP_RO: return ("ro"); case IP_WO: return ("wo"); case IP_RW: return ("rw"); default: fprintf (stderr, "Impossible IPerm %d\n", p); exit(1); } } indi-0.5/src/apogee_ppi.h0000644000175000017500000001102310610474336013162 0ustar jrjr#if 0 Apogee PPI INDI Interface for Apogee PPI Copyright (C) 2005 Jasem Mutlaq (mutlaqja AT ikarustech DOT com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #endif #ifndef APOGEE_PPI_H #define APOGEE_PPI_H #include #include #include #include #include #include #include #include #include #include "indidevapi.h" #include "eventloop.h" #include "indicom.h" #include "apogee/CameraIO_Linux.h" #define mydev "Apogee PPI" #define COMM_GROUP "Communication" #define EXPOSE_GROUP "Expose" #define IMAGE_GROUP "Image Settings" #define DATA_GROUP "Data Channel" #define POLLMS 1000 /* Polling time (ms) */ #define TEMP_THRESHOLD .25 /* Differential temperature threshold (C)*/ #define MAX_PIXELS 4096 #define MAXHBIN 8 #define MAXVBIN 64 #define MIN_CCD_TEMP -60 #define MAX_CCD_TEMP 40 #define MAXCOLUMNS 16383 #define MAXROWS 16383 #define MAXTOTALCOLUMNS 16383 #define MAXTOTALROWS 16383 #define FILENAMESIZ 2048 #define LIBVERSIZ 1024 #define PREFIXSIZ 64 #define PIPEBUFSIZ 8192 #define FRAME_ILEN 64 #define getBigEndian(p) ( ((p & 0xff) << 8) | (p >> 8)) class ApogeeCam { public: ApogeeCam(); ~ApogeeCam(); /* INDI Functions that must be called from indidrivermain */ void ISGetProperties (const char *dev); void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n); void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); void ISPoll(); private: /* Structs */ struct { short width; short height; int frameType; int expose; double temperature; int binX, binY; unsigned short *img; } APGFrame; enum { LIGHT_FRAME , BIAS_FRAME, DARK_FRAME, FLAT_FRAME }; /* Switches */ ISwitch PowerS[2]; ISwitch *ApogeeModelS; ISwitch FrameTypeS[4]; /* Numbers */ INumber FrameN[4]; INumber BinningN[2]; INumber ExposeTimeN[1]; INumber TemperatureN[1]; INumber DataChannelN[1]; /* BLOBs */ IBLOB imageB; /* Switch vectors */ ISwitchVectorProperty PowerSP; /* Connection switch */ ISwitchVectorProperty ApogeeModelSP; /* Apogee Model */ ISwitchVectorProperty FrameTypeSP; /* Frame type */ /* Number vectors */ INumberVectorProperty FrameNP; /* Frame specs */ INumberVectorProperty BinningNP; /* Binning */ INumberVectorProperty ExposeTimeNP; /* Exposure */ INumberVectorProperty TemperatureNP; /* Temperature control */ /* BLOB vectors */ IBLOBVectorProperty imageBP; /* Data stream */ /* Other */ static int streamTimerID; /* Stream ID */ double targetTemp; /* Target temperature */ CCameraIO *cam; /* Apogee Camera object */ /* Functions */ /* General */ void initProperties(); bool loadXMLModel(); bool initCamera(); /* CCD */ void getBasicData(void); void handleExposure(void *); void connectCCD(void); void uploadFile(char * filename); int writeFITS(char *filename, char errmsg[]); int setImageArea(char errmsg[]); void grabImage(void); int isCCDConnected(void); /* Power */ int checkPowerS(ISwitchVectorProperty *sp); int checkPowerN(INumberVectorProperty *np); int checkPowerT(ITextVectorProperty *tp); /* Helper functions */ int manageDefaults(char errmsg[]); int getOnSwitch(ISwitchVectorProperty *sp); //FITS_HDU_LIST * create_fits_header (FITS_FILE *ofp, uint width, uint height, uint bpp); unsigned short hextoi(char* instr); double min(); double max(); }; #endif indi-0.5/src/lx200generic.h0000644000175000017500000000515510610474336013265 0ustar jrjr/* LX200 Generic Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef LX200GENERIC_H #define LX200GENERIC_H #include "indidevapi.h" #include "indicom.h" #define POLLMS 1000 /* poll period, ms */ #define mydev "LX200 Generic" /* The device name */ class LX200Generic { public: LX200Generic(); virtual ~LX200Generic(); virtual void ISGetProperties (const char *dev); virtual void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); virtual void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n); virtual void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); virtual void ISPoll (); virtual void getBasicData(); int checkPower(INumberVectorProperty *np); int checkPower(ISwitchVectorProperty *sp); int checkPower(ITextVectorProperty *tp); void handleError(ISwitchVectorProperty *svp, int err, const char *msg); void handleError(INumberVectorProperty *nvp, int err, const char *msg); void handleError(ITextVectorProperty *tvp, int err, const char *msg); bool isTelescopeOn(void); void connectTelescope(); void slewError(int slewCode); void getAlignment(); int handleCoordSet(); int getOnSwitch(ISwitchVectorProperty *sp); void setCurrentDeviceName(const char * devName); void correctFault(); void enableSimulation(bool enable); void updateTime(); void updateLocation(); void mountSim(); static void updateFocusTimer(void *p); int fd; protected: int timeFormat; int currentSiteNum; int trackingMode; double JD; double currentRA; double currentDEC; double targetRA; double targetDEC; double lastRA; double lastDEC; bool fault; bool simulation; char thisDevice[64]; int currentSet; int lastSet; }; void changeLX200GenericDeviceName(const char * newName); void changeAllDeviceNames(const char *newName); #endif indi-0.5/src/lx200gps.h0000644000175000017500000000256510610474336012444 0ustar jrjr#ifndef LX200GPS_H #define LX200GPS_H /* LX200 GPS Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "lx200_16.h" class LX200GPS : public LX200_16 { public: LX200GPS(); ~LX200GPS() {} void ISGetProperties (const char *dev); void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n); void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); void ISPoll (); void getBasicData(); }; void changeLX200GPSDeviceName(const char *newName); #endif indi-0.5/src/lx200autostar.h0000644000175000017500000000264010610474336013507 0ustar jrjr/* LX200 Autostar Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef LX200AUTOSTAR_H #define LX200AUTOSTAR_H #include "lx200generic.h" class LX200Autostar : public LX200Generic { public: LX200Autostar(); ~LX200Autostar() {} void ISGetProperties (const char *dev); void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n); void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); void ISPoll (); void getBasicData(); }; void changeLX200AutostarDeviceName(const char *newName); #endif indi-0.5/src/.cvsignore0000644000175000017500000000026310605175713012706 0ustar jrjr.libs .deps *.o *.a *.la *.lo indiserver celestrongps lx200generic Makefile Makefile.in mountsim fliccd v4ldriver v4lphilips fliwheel temma apogee_ppi sbigccd apmount meade_lpi indi-0.5/src/v4lphilips.h0000644000175000017500000000456010610474336013160 0ustar jrjr/* Phlips webcam INDI driver Copyright (C) 2003-2005 by Jasem Mutlaq This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 2005.04.29 JM: There is no need for this file for Video 4 Linux 2. It is kept for V4L 1 compatibility. */ #ifndef V4LPHILIPS_H #define V4LPHILIPS_H #ifndef HAVE_LINUX_VIDEODEV2_H #include "webcam/v4l1_pwc.h" #endif #include "v4ldriver.h" class V4L_Philips : public V4L_Driver { public: V4L_Philips(); ~V4L_Philips(); /* INDI Functions that must be called from indidrivermain */ void ISGetProperties (const char *dev); void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n); void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); void initCamBase(); void initProperties(const char *dev); void connectCamera(void); private: /* Switches */ ISwitch BackLightS[2]; ISwitch AntiFlickerS[2]; ISwitch NoiseReductionS[4]; ISwitch CamSettingS[3]; ISwitch WhiteBalanceModeS[5]; /* Nmubers */ INumber WhiteBalanceN[2]; INumber ShutterSpeedN[1]; /* Switch Vectors */ ISwitchVectorProperty BackLightSP; ISwitchVectorProperty AntiFlickerSP; ISwitchVectorProperty NoiseReductionSP; ISwitchVectorProperty CamSettingSP; ISwitchVectorProperty WhiteBalanceModeSP; /* Number Vectors */ INumberVectorProperty WhiteBalanceNP; INumberVectorProperty ShutterSpeedNP; #ifndef HAVE_LINUX_VIDEODEV2_H V4L1_PWC * v4l_pwc; void updateV4L1Controls(); void getBasicData(void); #endif }; #endif indi-0.5/src/robofocusdriver.c0000644000175000017500000002544010610474331014265 0ustar jrjr#if 0 Robofocus Driver Copyright (C) 2006 Markus Wildi, markus.wildi@datacomm.ch This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301 USA #endif #include #include #include #include "indicom.h" #include "indidevapi.h" #include "indiapi.h" #include "robofocusdriver.h" /********************************************************************** * Communication **********************************************************************/ int portRFRead(int fd, char *buf, int nbytes, int timeout) { int bytesRead = 0; int totalBytesRead = 0; int err; char *tbuf= buf ; while (nbytes > 0) { if ( (err = tty_timeout(fd, timeout)) < 0 ) return err; bytesRead = read(fd, tbuf, nbytes); if (bytesRead < 0 ) return -1; if(( tbuf[0]== 'I')|| ( tbuf[0]== 'O')){ /*fprintf(stderr, "Moving\n") ;*/ tbuf[0]=0 ; usleep(100000) ; } else { tbuf += bytesRead; totalBytesRead++; nbytes -= bytesRead; } } /* fprintf(stderr, "READ : (%s,%d), %d\n", buf, 9, totalBytesRead) ; */ /* fprintf(stderr, "READ : ") ; */ /* for(i=0; i < 9; i++) { */ /* fprintf(stderr, "0x%2x ", (unsigned char)buf[i]) ; */ /* } */ /* fprintf(stderr, "\n") ; */ return 9; } int portRFWrite(int fd, const char * buf) { int nbytes=9 ; int totalBytesWritten=0 ; int bytesWritten = 0; while (nbytes > 0) { bytesWritten = write(fd, buf, nbytes); if (bytesWritten < 0) return -1; buf += bytesWritten; nbytes -= bytesWritten; } /* Returns the # of bytes written */ return (totalBytesWritten); } unsigned char calsum(char *rf_cmd) { unsigned char val= 0 ; int i=0 ; for(i=0; i < 8; i++) { val = val + (unsigned char) rf_cmd[i] ; } return val % 256 ; } unsigned char chksum(char *rf_cmd) { char substr[255] ; unsigned char val= 0 ; int i= 0 ; for(i=0; i < 8; i++) { substr[i]=rf_cmd[i] ; } val = calsum( substr) ; if( val== (unsigned char) rf_cmd[8]) { } else { fprintf(stderr, "Wrong (%s,%d), %x != %x\n", rf_cmd, strlen(rf_cmd), val, (unsigned char) rf_cmd[8]) ; } return val ; } /********************************************************************** * Commands **********************************************************************/ int commRF(int fd, char *rf_cmd) { int read_ret=0, check_ret=0; char rf_cmd_cks[32] ; unsigned char val= 0 ; int nbytes= 9 ; int i ; val = calsum( rf_cmd ) ; for(i=0; i < 8; i++) { rf_cmd_cks[i]= rf_cmd[i] ; } rf_cmd_cks[8]= val ; rf_cmd_cks[9]= 0 ; /* fprintf(stderr, "WRITE: ") ; */ /* for(i=0; i < 9; i++) { */ /* fprintf(stderr, "0x%2x ", rf_cmd_cks[i]) ; */ /* } */ /* fprintf(stderr, "\n") ; */ if(portRFWrite(fd, rf_cmd_cks) < 0) return -1; read_ret= portRFRead(fd, rf_cmd, nbytes, RF_TIMEOUT) ; if (read_ret < 1) return read_ret; check_ret= chksum(rf_cmd) ; rf_cmd[ read_ret- 1] = 0 ; return 0; } int updateRFPosition(int fd, double *value) { float temp ; char rf_cmd[32] ; int ret_read_tmp ; strcpy(rf_cmd, "FG000000" ) ; if ((ret_read_tmp= commRF(fd, rf_cmd)) < 0){ return ret_read_tmp; } if (sscanf(rf_cmd, "FD%6f", &temp) < 1){ return -1; } *value = (double) temp; return 0; } int updateRFTemperature(int fd, double *value) { float temp ; char rf_cmd[32] ; int ret_read_tmp ; strcpy(rf_cmd, "FT000000" ) ; if ((ret_read_tmp= commRF(fd, rf_cmd)) < 0) return ret_read_tmp; if (sscanf(rf_cmd, "FT%6f", &temp) < 1) return -1; *value = (double) temp/2.- 273.15; return 0; } int updateRFBacklash(int fd, double *value) { float temp ; char rf_cmd[32] ; char vl_tmp[4] ; int ret_read_tmp ; int sign= 0 ; if(*value== BACKLASH_READOUT) { strcpy(rf_cmd, "FB000000" ) ; } else { rf_cmd[0]= 'F' ; rf_cmd[1]= 'B' ; if( *value > 0) { rf_cmd[2]= '3' ; } else { *value= - *value ; rf_cmd[2]= '2' ; } rf_cmd[3]= '0' ; rf_cmd[4]= '0' ; if(*value > 99) { sprintf( vl_tmp, "%3d", (int) *value) ; } else if(*value > 9) { sprintf( vl_tmp, "0%2d", (int) *value) ; } else { sprintf( vl_tmp, "00%1d", (int) *value) ; } rf_cmd[5]= vl_tmp[0] ; rf_cmd[6]= vl_tmp[1] ; rf_cmd[7]= vl_tmp[2] ; } if ((ret_read_tmp= commRF(fd, rf_cmd)) < 0) return ret_read_tmp; if (sscanf(rf_cmd, "FB%1d%5f", &sign, &temp) < 1) return -1; *value = (double) temp ; if(( sign== 2) && ( *value > 0)) { *value = - (*value) ; } return 0; } int updateRFFirmware(int fd, char *rf_cmd) { int ret_read_tmp ; strcpy(rf_cmd, "FV000000" ) ; if ((ret_read_tmp= commRF(fd, rf_cmd)) < 0) return ret_read_tmp; return 0; } int updateRFMotorSettings(int fd, double *duty, double *delay, double *ticks) { char rf_cmd[32] ; int ret_read_tmp ; if(( *duty== 0 ) && (*delay== 0) && (*ticks== 0) ){ strcpy(rf_cmd, "FC000000" ) ; } else { rf_cmd[0]= 'F' ; rf_cmd[1]= 'C' ; rf_cmd[2]= (char) *duty ; rf_cmd[3]= (char) *delay ; rf_cmd[4]= (char) *ticks ; rf_cmd[5]= '0' ; rf_cmd[6]= '0' ; rf_cmd[7]= '0' ; rf_cmd[8]= 0 ; } if ((ret_read_tmp= commRF(fd, rf_cmd)) < 0) return ret_read_tmp; *duty= (float) rf_cmd[2] ; *delay= (float) rf_cmd[3] ; *ticks= (float) rf_cmd[4] ; return 0; } int updateRFPositionRelativeInward(int fd, double *value) { char rf_cmd[32] ; int ret_read_tmp ; float temp ; rf_cmd[0]= 0 ; if(*value > 9999) { sprintf( rf_cmd, "FI0%5d", (int) *value) ; } else if(*value > 999) { sprintf( rf_cmd, "FI00%4d", (int) *value) ; } else if(*value > 99) { sprintf( rf_cmd, "FI000%3d", (int) *value) ; } else if(*value > 9) { sprintf( rf_cmd, "FI0000%2d", (int) *value) ; } else { sprintf( rf_cmd, "FI00000%1d", (int) *value) ; } if ((ret_read_tmp= commRF(fd, rf_cmd)) < 0) return ret_read_tmp; if (sscanf(rf_cmd, "FD0%5f", &temp) < 1) return -1; *value = (double) temp ; return 0; } int updateRFPositionRelativeOutward(int fd, double *value) { char rf_cmd[32] ; int ret_read_tmp ; float temp ; rf_cmd[0]= 0 ; if(*value > 9999) { sprintf( rf_cmd, "FO0%5d", (int) *value) ; } else if(*value > 999) { sprintf( rf_cmd, "FO00%4d", (int) *value) ; } else if(*value > 99) { sprintf( rf_cmd, "FO000%3d", (int) *value) ; } else if(*value > 9) { sprintf( rf_cmd, "FO0000%2d", (int) *value) ; } else { sprintf( rf_cmd, "FO00000%1d", (int) *value) ; } if ((ret_read_tmp= commRF(fd, rf_cmd)) < 0) return ret_read_tmp; if (sscanf(rf_cmd, "FD0%5f", &temp) < 1) return -1; *value = (double) temp ; return 0; } int updateRFPositionAbsolute(int fd, double *value) { char rf_cmd[32] ; int ret_read_tmp ; float temp ; rf_cmd[0]= 0 ; if(*value > 9999) { sprintf( rf_cmd, "FG0%5d", (int) *value) ; } else if(*value > 999) { sprintf( rf_cmd, "FG00%4d", (int) *value) ; } else if(*value > 99) { sprintf( rf_cmd, "FG000%3d", (int) *value) ; } else if(*value > 9) { sprintf( rf_cmd, "FG0000%2d", (int) *value) ; } else { sprintf( rf_cmd, "FG00000%1d", (int) *value) ; } if ((ret_read_tmp= commRF(fd, rf_cmd)) < 0) return ret_read_tmp; if (sscanf(rf_cmd, "FD0%5f", &temp) < 1) return -1; *value = (double) temp ; return 0; } int updateRFPowerSwitches(int fd, int s, int new_sn, int *cur_s1LL, int *cur_s2LR, int *cur_s3RL, int *cur_s4RR) { char rf_cmd[32] ; char rf_cmd_tmp[32] ; int ret_read_tmp ; int i = 0 ; /* Get first the status */ strcpy(rf_cmd_tmp, "FP000000" ) ; if ((ret_read_tmp= commRF(fd, rf_cmd_tmp)) < 0) return ret_read_tmp ; for(i= 0; i < 9; i++) { rf_cmd[i]= rf_cmd_tmp[i] ; } if( rf_cmd[new_sn + 4]== '2') { rf_cmd[new_sn + 4]= '1' ; } else { rf_cmd[new_sn + 4]= '2' ; } /* if( s== ISS_ON) { */ /* rf_cmd[new_sn + 4]= '2' ; */ /* } else { */ /* rf_cmd[new_sn + 4]= '1' ; */ /* } */ rf_cmd[8]= 0 ; if ((ret_read_tmp= commRF(fd, rf_cmd)) < 0) return ret_read_tmp ; *cur_s1LL= *cur_s2LR= *cur_s3RL= *cur_s4RR= ISS_OFF ; if(rf_cmd[4]== '2' ) { *cur_s1LL= ISS_ON ; } if(rf_cmd[5]== '2' ) { *cur_s2LR= ISS_ON ; } if(rf_cmd[6]== '2' ) { *cur_s3RL= ISS_ON ; } if(rf_cmd[7]== '2' ) { *cur_s4RR= ISS_ON ; } return 0 ; } int updateRFMaxPosition(int fd, double *value) { float temp ; char rf_cmd[32] ; char vl_tmp[6] ; int ret_read_tmp ; char waste[1] ; if(*value== MAXTRAVEL_READOUT) { strcpy(rf_cmd, "FL000000" ) ; } else { rf_cmd[0]= 'F' ; rf_cmd[1]= 'L' ; rf_cmd[2]= '0' ; if(*value > 9999) { sprintf( vl_tmp, "%5d", (int) *value) ; } else if(*value > 999) { sprintf( vl_tmp, "0%4d", (int) *value) ; } else if(*value > 99) { sprintf( vl_tmp, "00%3d", (int) *value) ; } else if(*value > 9) { sprintf( vl_tmp, "000%2d", (int) *value) ; } else { sprintf( vl_tmp, "0000%1d", (int) *value) ; } rf_cmd[3]= vl_tmp[0] ; rf_cmd[4]= vl_tmp[1] ; rf_cmd[5]= vl_tmp[2] ; rf_cmd[6]= vl_tmp[3] ; rf_cmd[7]= vl_tmp[4] ; rf_cmd[8]= 0 ; } if ((ret_read_tmp= commRF(fd, rf_cmd)) < 0) return ret_read_tmp; if (sscanf(rf_cmd, "FL%1c%5f", waste, &temp) < 1) return -1; *value = (double) temp ; return 0; } int updateRFSetPosition(int fd, double *value) { char rf_cmd[32] ; char vl_tmp[6] ; int ret_read_tmp ; rf_cmd[0]= 'F' ; rf_cmd[1]= 'S' ; rf_cmd[2]= '0' ; if(*value > 9999) { sprintf( vl_tmp, "%5d", (int) *value) ; } else if(*value > 999) { sprintf( vl_tmp, "0%4d", (int) *value) ; } else if(*value > 99) { sprintf( vl_tmp, "00%3d", (int) *value) ; } else if(*value > 9) { sprintf( vl_tmp, "000%2d", (int) *value) ; } else { sprintf( vl_tmp, "0000%1d", (int) *value) ; } rf_cmd[3]= vl_tmp[0] ; rf_cmd[4]= vl_tmp[1] ; rf_cmd[5]= vl_tmp[2] ; rf_cmd[6]= vl_tmp[3] ; rf_cmd[7]= vl_tmp[4] ; rf_cmd[8]= 0 ; if ((ret_read_tmp= commRF(fd, rf_cmd)) < 0) return ret_read_tmp; return 0; } indi-0.5/src/base64.c0000644000175000017500000001552510610474331012137 0ustar jrjr#if 0 INDI Copyright (C) 2003 Elwood C. Downey This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Adapted from code written by Eric S. Raymond #endif /* Pair of functions to convert to/from base64. * Also can be used to build a standalone utility and a loopback test. * see http://www.faqs.org/rfcs/rfc3548.html */ /** \file base64.c \brief Pair of functions to convert to/from base64. */ #include #include "base64.h" static const char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; #define BAD (-1) static const char base64val[] = { BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD,BAD, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,BAD,BAD, BAD,BAD,BAD,BAD, BAD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,BAD, BAD,BAD,BAD,BAD, BAD, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,BAD, BAD,BAD,BAD,BAD }; #define DECODE64(c) (isascii(c) ? base64val[c] : BAD) /* convert inlen raw bytes at in to base64 string (NUL-terminated) at out. * out size should be at least 4*inlen/3 + 4. * return length of out (sans trailing NUL). */ int to64frombits(unsigned char *out, const unsigned char *in, int inlen) { unsigned char *out0 = out; for (; inlen >= 3; inlen -= 3) { *out++ = base64digits[in[0] >> 2]; *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)]; *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; *out++ = base64digits[in[2] & 0x3f]; in += 3; } if (inlen > 0) { unsigned char fragment; *out++ = base64digits[in[0] >> 2]; fragment = (in[0] << 4) & 0x30; if (inlen > 1) fragment |= in[1] >> 4; *out++ = base64digits[fragment]; *out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c]; *out++ = '='; } *out = '\0'; return (out-out0); } /* convert base64 at in to raw bytes out, returning count or <0 on error. * base64 may contain any embedded whitespace. * out should be at least 3/4 the length of in. */ int from64tobits(char *out, const char *in) { int len = 0; register unsigned char digit1, digit2, digit3, digit4; do { do {digit1 = *in++;} while (isspace(digit1)); if (DECODE64(digit1) == BAD) return(-1); do {digit2 = *in++;} while (isspace(digit2)); if (DECODE64(digit2) == BAD) return(-2); do {digit3 = *in++;} while (isspace(digit3)); if (digit3 != '=' && DECODE64(digit3) == BAD) return(-3); do {digit4 = *in++;} while (isspace(digit4)); if (digit4 != '=' && DECODE64(digit4) == BAD) return(-4); *out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4); ++len; if (digit3 != '=') { *out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2); ++len; if (digit4 != '=') { *out++ = ((DECODE64(digit3) << 6) & 0xc0) | DECODE64(digit4); ++len; } } while (isspace(*in)) in++; } while (*in && digit4 != '='); return (len); } #ifdef BASE64_PROGRAM /* standalone program that converts to/from base64. * cc -o base64 -DBASE64_PROGRAM base64.c */ #include #include #include static void usage (char *me) { fprintf (stderr, "Purpose: convert stdin to/from base64 on stdout\n"); fprintf (stderr, "Usage: %s {-t,-f}\n", me); exit (1); } int main (int ac, char *av[]) { int to64 = 1; /* decide whether to or from base64 */ if (ac == 2 && strcmp (av[1], "-f") == 0) to64 = 0; else if (ac != 1 && (ac != 2 || strcmp (av[1], "-t"))) usage (av[0]); if (to64) { unsigned char *rawin, *b64; int i, n, nrawin, nb64; /* read raw on stdin until EOF */ rawin = malloc(4096); nrawin = 0; while ((n = fread (rawin+nrawin, 1, 4096, stdin)) > 0) rawin = realloc (rawin, (nrawin+=n)+4096); /* convert to base64 */ b64 = malloc (4*nrawin/3+4); nb64 = to64frombits(b64, rawin, nrawin); /* pretty print */ for (i = 0; i < nb64; i += 72) printf ("%.*s\n", 72, b64+i); } else { unsigned char *raw, *b64; int n, nraw, nb64; /* read base64 on stdin until EOF */ b64 = malloc(4096); nb64 = 0; while ((n = fread (b64+nb64, 1, 4096, stdin)) > 0) b64 = realloc (b64, (nb64+=n)+4096); b64[nb64] = '\0'; /* convert to raw */ raw = malloc (3*nb64/4); nraw = from64tobits(raw, b64); if (nraw < 0) { fprintf (stderr, "base64 conversion error: %d\n", nraw); return (1); } /* write */ fwrite (raw, 1, nraw, stdout); } return (0); } #endif #ifdef LOOPBACK_TEST /* standalone test that reads binary on stdin, converts to base64 and back, * then compares. exit 0 if compares the same else 1 */ #include #include #include int main (int ac, char *av[]) { unsigned char *rawin, *b64, *rawback; int n, nrawin, nrawback, nb64; /* read raw on stdin until EOF */ rawin = malloc(4096); nrawin = 0; while ((n = fread (rawin+nrawin, 1, 4096, stdin)) > 0) rawin = realloc (rawin, (nrawin+=n)+4096); /* convert to base64 */ b64 = malloc (4*nrawin*3 + 4); nb64 = to64frombits(b64, rawin, nrawin); /* convert back to raw */ rawback = malloc (3*nb64/4); nrawback = from64tobits(rawback, b64); if (nrawback < 0) { fprintf (stderr, "base64 error: %d\n", nrawback); return(1); } if (nrawback != nrawin) { fprintf (stderr, "base64 back length %d != %d\n", nrawback, nrawin); return(1); } /* compare */ if (memcmp (rawback, rawin, nrawin)) { fprintf (stderr, "compare error\n"); return (1); } /* success */ return (0); } #endif /* For RCS Only -- Do Not Edit */ static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile$ $Date: 2006-09-30 14:19:41 +0300 (Sat, 30 Sep 2006) $ $Revision: 590506 $ $Name: $"}; indi-0.5/src/orionatlas.h0000644000175000017500000000466610610474336013244 0ustar jrjr/* Celestron GPS Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef ORIONATLAS_H #define ORIONATLAS_H #include "indidevapi.h" #include "indicom.h" #define RADEC 1 #define AZALT 2 class OrionAtlas { typedef fd_set telfds; public: OrionAtlas(); virtual ~OrionAtlas() {} virtual void ISGetProperties (const char *dev); virtual void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n); virtual void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n); virtual void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); virtual void ISPoll (); virtual void getBasicData(); int checkPower(INumberVectorProperty *np); int checkPower(ISwitchVectorProperty *sp); int checkPower(ITextVectorProperty *tp); void powerTelescope(); void log(const char *fmt,...); // void slewError(int slewCode); // int handleCoordSet(); // int getOnSwitch(ISwitchVectorProperty *sp); private: int timeFormat; int CheckConnectTel(void); int ConnectTel(char *port); void DisconnectTel(void); int GetCoords(int System=RADEC|AZALT); // Retrieve coordinates from scope void UpdateCoords(int System=RADEC|AZALT); // Retrieve coordinates and update INumbers int MoveScope(int System, double Coord1, double Coord2); // move the scope int TelPortFD; int TelConnectFlag; double returnRA; /* Last update of RA */ double returnDec; /* Last update of Dec */ double returnAz; double returnAlt; //double lat,lon; int readn(int fd, unsigned char *ptr, int nbytes, int sec); int writen(int fd, unsigned char *ptr, int nbytes); int telstat(int fd,int sec,int usec); bool Updating; }; #endif indi-0.5/configure.in0000644000175000017500000000736110610504211012417 0ustar jrjrAC_INIT(configure.in) AM_CONFIG_HEADER(config.h) rm -f config.h >&/dev/null touch config.h AC_CANONICAL_HOST AC_CANONICAL_TARGET AC_LANG_CPLUSPLUS AC_PROG_CXX AC_PROG_CC AM_PROG_LIBTOOL AM_INIT_AUTOMAKE(indi, 0.5) timezone_int=no AC_TRY_COMPILE( #include , daylight = 0; timezone = 0; , AC_DEFINE(TIMEZONE_IS_INT,1,[The symbol timezone is an int, not a function]) , AC_DEFINE(TIMEZONE_IS_INT,0,[The symbol timezone is an int, not a function]) ) # INDI driver for the FLI CCD case "${host_os}" in *linux* ) OSDIR=linux ;; *bsd* ) OSDIR=bsd ;; * ) OSDIR=null ;; esac # This variable to is check for the availability of libusb have_libusb="no" dnl --enable-libusb=PATH AC_ARG_ENABLE(libusb, AC_HELP_STRING([--enable-libusb=PATH],[libusb path (default /usr)]), [ case ${enableval} in "" | "yes" | "YES") ;; "no" | "NO") use_libusb=false ;; *) CPPFLAGS="$CPPFLAGS -I${enableval}/include" LDFLAGS="$LDFLAGS -L${enableval}/lib" ;; esac ] ) dnl check if libusb is available if test "${use_libusb}" != false ; then AC_SUBST(LIBUSB) AC_CHECK_HEADERS(usb.h, [have_libusb="yes"], [ AC_MSG_WARN([usb.h not found, use --enable-libusb=PATH. Otherwise, INDI will compile without Apogee & SBIG USB support.]) ]) ac_save_LIBS="$LIBS" LIBS="$LIBS $COREFOUNDATION $IOKIT" AC_CHECK_LIB(usb, usb_init, [LIBUSB="$LIBUSB -lusb" have_libusb="yes"], [ AC_MSG_WARN([libusb not found. INDI will compile without Apogee & SBIG USB support.]) ]) LIBS="$ac_save_LIBS" fi have_cfitsio=false AC_LANG_PUSH(C) LDFLAGS="$LDFLAGS -lm -lz" AC_CHECK_LIB(cfitsio, ffppx, [ LIBS="-lcfitsio $LIBS"], [ EXTRA_SUBDIR="cfitsio" LIBCFITSIO="cfitsio/libcfitsio.la"]) AC_SUBST(LIBCFITSIO) AC_SUBST(EXTRA_SUBDIR) LDFLAGS="-lusb $LDFLAGS" AC_CHECK_LIB(sbigudrv, SBIGUnivDrvCommand, [ have_libsbigudrv=true LIBSBIGUDRV="-lsbigudrv"], [ have_libsbigudrv=false LIBSBIGUDRV="libsbigudrv.la"]) AC_SUBST(LIBSBIGUDRV) AC_LANG_POP(C) dnl check if v4l2 is available have_v4l2=false case "$target" in *-*-linux*) AC_ARG_ENABLE(v4l2, [AC_HELP_STRING([--disable-v4l2], [disable V4L2 interface for INDI])], [ case "${enableval}" in no) disable_v4l2=yes ;; yes) disable_v4l2=no ;; *) AC_MSG_ERROR(bad value ${enableval} for --disable-v4l2) ;; esac], [disable_v4l2=no]) if test x$disable_v4l2 = xno; then AC_CHECK_TYPE([struct v4l2_buffer], [have_v4l2=true], [have_v4l2=false], [#include #include ]) if test x$have_v4l2 = xfalse; then KERNEL_VERSION=`uname -r` AC_CHECK_FILE(/lib/modules/$KERNEL_VERSION/build/include/linux/videodev2.h, [have_v4l2=true], [AC_MSG_WARN([]) AC_MSG_WARN([]) AC_MSG_WARN([We cannot locate videodev2.h in /usr/include/linux]) AC_MSG_WARN([This file is responsible for V4L2 in INDI]) AC_MSG_WARN([INDI will be compiled with legacy V4L 1 support.])] AC_MSG_WARN([]) AC_MSG_WARN([])) fi else have_v4l2=false fi ;; *) ;; esac if test x$have_v4l2 = xtrue; then AC_DEFINE(HAVE_LINUX_VIDEODEV2_H, 1, [Define to 1 if you have the header file.]) fi AM_CONDITIONAL(BSD, test x$OSDIR = xbsd) AM_CONDITIONAL(LINUX, test x$OSDIR = xlinux) AM_CONDITIONAL(NULL, test x$OSDIR = xnull) AM_CONDITIONAL(HAVE_LIBUSB, test x$have_libusb = xyes) AM_CONDITIONAL(HAVE_V4L2, test x$have_v4l2 = xtrue) AM_CONDITIONAL(HAVE_LIBSBIGUDRV, test x$have_libsbigudrv = xtrue) AC_OUTPUT(Makefile src/Makefile src/fli/Makefile src/webcam/Makefile src/apogee/Makefile src/cfitsio/Makefile) indi-0.5/install-sh0000755000175000017500000001273610605175720012131 0ustar jrjr#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 indi-0.5/README.drivers0000644000175000017500000000775310605175720012465 0ustar jrjr============================================= = INDI Drivers Knowledge Base ============================================= Introduction ============ The goal of the INDI Drivers Knowledge Base is to establish a repository that addresses driver-specific issues and problems. You can find more up to date information on INDI drivers from the following sources: 1. INDI Device Profiles: http://indi.sf.net/devices.html 2. INDI Wiki: http://wiki.kde.org/tiki-index.php?page=indi Telescopes ========== + Meade - Slew Precision: Meade scopes do not report back a successful slew (Meade claim they do, but they don't). Normally, the user hears a beep when slew is complete. However, clients and scripts need to know when the slew is over. Furthermore, you can't hear any beeps if you're controlling the telescope remotely! The solution to this is to continously monitor the target coordinates against the telescope's current coordinate during slew. When the two coordinates are 'close enough', we declare a successful slew. This 'close enough' value was hardcoded in previous versions in INDI, but they are user-adjustable now. The default value for RA and DEC is 3 arcminutes. Setting the values too low might result in endless busy state during slew. Set the values to reflect your instruments precision capabilities. The 3 arcminute value is the average value determined from experience. Please not that the Slew Precision parameter has NO EFFECT what so ever on your telescope slew accuracy or precision, it is merely used to indicate when a successful slew is completed. - Track Precision: Tracking is indentical to slewing for sidereal objects. For non-sidereal objects (e.g. planets), the telescope need to continously follow the object as it crosses the sky. For LX200 Classic telescopes, it is possible to ask the scope to track a specific solar system object. However, in all other models, such facitliy does not exist. It is therefore neccesary to manually track non-sideral objects. But continiously issuing 'slew' commands will result in jerky scope motion. To compensate for that, we set an upper limit for the difference between our target coordinates and the current telescope coordinates. If this limit is exceeded, then we tell the scope to slew. The default values for track precision are 3 arcminutes. If you set the values too low, your telescope motion will be jerky and unstable. If you set the values too high, the object might move significantly in the eye piece, if not completely out of it. + Celestron + Meade-Compatible For all Meade-Compatible telescopes, use the lx200basic driver to obtain basic control over your particular controller. It is not recommended to use other LX200* drivers as your controller might or might not support Meade's command set. + DCS CCDs ==== + FLI (Finger Lakes Instruments) - FLI driver require read and write access to your USB subsystem. There are two methods to accomplish this: 1. Run fliccd driver as root or setuid your fliccd (chmod +s fliccd). 2. Allow your user write privileges to the USB sub system by mounting /proc/bus/usb with the proper user and group permissions. + SBIG (Santa Barbara ....) + Apogee Focusers ======== + Meade LX200GPS Microfocuser + Meade 1206 Primary Mirror Focuser + JMI NGF Series + JMI MOTOFOCUS + Robo Focus Filter Wheels ============= + FLI Filter Wheel + SBIG CWF + TruTechnology Filter Wheel Video ===== + Video 4 Linux I, II + Philips Webcam + SBIG STV + Meade Lunar Planetary Imager (Experimental) - Exposure: You need to have Kernel 2.6.16+ if you want to take long exposures (1 second or more) with the LPI. To obtain long exposures under 2.6.16+, you need to modify a module paramter for the SN9Cxxx drivers. As root, perform the following: [root@localhost #] cd /sys/class/video4linux/video0 [root@localhost #] echo 16 > frame_timeout This will increase the timeout for the driver to up to 16 seconds. You can experiment with different values, but 16 seconds is Meade's LPI 'advertised' limit. indi-0.5/mkinstalldirs0000755000175000017500000000133010605175720012717 0ustar jrjr#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs,v 1.1.1.1 2003/09/15 18:45:21 slovin Exp $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here indi-0.5/config.sub0000755000175000017500000007567610605175720012124 0ustar jrjr#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2005-07-08' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | ms1 \ | msp430 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m32c) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | ms1-* \ | msp430-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa-* \ | ymp-* \ | z8k-*) ;; m32c-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16c) basic_machine=cr16c-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: indi-0.5/depcomp0000755000175000017500000002752510605175720011504 0ustar jrjr#! /bin/sh # depcomp - compile a program generating dependencies as side-effects # Copyright 1999, 2000 Free Software Foundation, Inc. # 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, 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. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # `libtool' can also be set to `yes' or `no'. depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. This file always lives in the current directory. # Also, the AIX compiler puts `$object:' at the start of each line; # $object doesn't have directory information. stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" outname="$stripped.o" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; tru64) # The Tru64 AIX compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. tmpdepfile1="$object.d" tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'` if test "$libtool" = yes; then "$@" -Wc,-MD else "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" else tmpdepfile="$tmpdepfile2" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a space and a tab in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. test -z "$dashmflag" && dashmflag=-M ( IFS=" " case " $* " in *" --mode=compile "*) # this is libtool, let us make it quiet for arg do # cycle over the arguments case "$arg" in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) # X makedepend ( shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift;; -*) ;; *) set fnord "$@" "$arg"; shift;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tail +3 "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. ( IFS=" " case " $* " in *" --mode=compile "*) for arg do # cycle over the arguments case $arg in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the proprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. ( IFS=" " case " $* " in *" --mode=compile "*) for arg do # cycle over the arguments case $arg in "--mode=compile") # insert --quiet before "--mode=compile" set fnord "$@" --quiet shift # fnord ;; esac set fnord "$@" "$arg" shift # fnord shift # "$arg" done ;; esac "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" ) & proc=$! "$@" stat=$? wait "$proc" if test "$stat" != 0; then exit $stat; fi rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 indi-0.5/ltconfig0000755000175000017500000024552510605175720011664 0ustar jrjr#! /bin/sh # ltconfig - Create a system-specific libtool. # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 # Free Software Foundation, Inc. # Originally by Gordon Matzigkeit , 1996 # # This file 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. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # A lot of this script is taken from autoconf-2.10. # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} echo=echo if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then # Yippee, $echo works! : else # Restart under the correct shell. exec "$SHELL" "$0" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat </dev/null`} case X$UNAME in *-DOS) PATH_SEPARATOR=';' ;; *) PATH_SEPARATOR=':' ;; esac fi # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if (echo_test_string="`eval $cmd`") 2>/dev/null && echo_test_string="`eval $cmd`" && (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then break fi done fi if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" for dir in $PATH /usr/ucb; do if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then echo="$dir/echo" break fi done IFS="$save_ifs" if test "X$echo" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. echo='print -r' elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running ltconfig again with it. ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}" export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"} else # Try using printf. echo='printf %s\n' if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL" export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL echo="$CONFIG_SHELL $0 --fallback-echo" elif echo_testing_string=`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then echo="$CONFIG_SHELL $0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then break fi prev="$cmd" done if test "$prev" != 'sed 50q "$0"'; then echo_test_string=`eval $prev` export echo_test_string exec "${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}}" "$0" ${1+"$@"} else # Oops. We lost completely, so just stick with echo. echo=echo fi fi fi fi fi # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='sed -e s/^X//' sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # The name of this program. progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'` # Constants: PROGRAM=ltconfig PACKAGE=libtool VERSION=1.4a TIMESTAMP=" (1.641.2.206mm 2001/04/03 21:47:47)" ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' rm="rm -f" help="Try \`$progname --help' for more information." # Global variables: default_ofile=libtool can_build_shared=yes enable_shared=yes # All known linkers require a `.a' archive for static linking (except M$VC, # which needs '.lib'). enable_static=yes enable_fast_install=yes enable_dlopen=unknown enable_win32_dll=no pic_mode=default ltmain= silent= srcdir= ac_config_guess= ac_config_sub= host= build=NONE nonopt=NONE ofile="$default_ofile" verify_host=yes tagname= with_gcc=no with_gnu_ld=no need_locks=yes ac_ext=c libext=a cache_file= max_cmd_len= ## Dependencies to place before and after the object being linked: predep_objects= postdep_objects= predeps= postdeps= compiler_lib_search_path= ## Link characteristics: allow_undefined_flag= no_undefined_flag= need_lib_prefix=unknown need_version=unknown # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments archive_cmds= archive_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= striplib= old_striplib= export_dynamic_flag_spec= whole_archive_flag_spec= thread_safe_flag_spec= hardcode_into_libs=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_direct=no hardcode_minus_L=no hardcode_shlibpath_var=unsupported runpath_var= link_all_deplibs=unknown always_export_symbols=no export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an egrep regular expression of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms="_GLOBAL_OFFSET_TABLE_" # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. extract_expsyms_cmds= ## Tools: old_AR="$AR" old_AR_FLAGS="$AR_FLAGS" old_CC="$CC" old_CFLAGS="$CFLAGS" old_CPPFLAGS="$CPPFLAGS" old_LDFLAGS="$LDFLAGS" old_LIBS="$LIBS" old_MAGIC_CMD="$MAGIC_CMD" old_LD="$LD" old_LN_S="$LN_S" old_LTCC="$LTCC" old_NM="$NM" old_RANLIB="$RANLIB" old_STRIP="$STRIP" old_AS="$AS" old_DLLTOOL="$DLLTOOL" old_OBJDUMP="$OBJDUMP" old_OBJEXT="$OBJEXT" old_EXEEXT="$EXEEXT" old_reload_flag="$reload_flag" old_deplibs_check_method="$deplibs_check_method" old_file_magic_cmd="$file_magic_cmd" # Parse the command line options. args= prev= for option do case $option in -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac # If the previous option needs an argument, assign it. if test -n "$prev"; then eval "$prev=\$option" prev= continue fi case $option in --help) cat <&2 echo "$help" 1>&2 exit 1 ;; *) if test -z "$ltmain"; then ltmain="$option" elif test -z "$host"; then # This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1 # if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then # echo "$progname: warning \`$option' is not a valid host type" 1>&2 # fi host="$option" else echo "$progname: too many arguments" 1>&2 echo "$help" 1>&2 exit 1 fi ;; esac done if test -z "$ltmain"; then echo "$progname: you must specify a LTMAIN file" 1>&2 echo "$help" 1>&2 exit 1 fi if test ! -f "$ltmain"; then echo "$progname: \`$ltmain' does not exist" 1>&2 echo "$help" 1>&2 exit 1 fi if test -n "$tagname"; then # Check whether tagname contains only valid characters case `$echo "X$tagname" | $Xsed -e 's/[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]//g'` in "") ;; *) echo "$progname: invalid tag name: $tagname" 1>&2 exit 1 ;; esac if grep "^### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$ofile" > /dev/null; then echo "$progname: tag name $tagname already exists" 1>&2 exit 1 fi if test ! -f "$ofile"; then echo "$progname: warning: output file \`$ofile' does not exist" 1>&2 fi if test -z "$LTCC"; then eval "`$SHELL $ofile --config | grep '^LTCC='`" if test -z "$LTCC"; then echo "$progname: warning: output file \`$ofile' does not look like a libtool script" 1>&2 else echo "$progname: warning: using \`LTCC=$LTCC', extracted from \`$ofile'" 1>&2 fi fi fi # Quote any args containing shell metacharacters. ltconfig_args= for arg do case $arg in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ltconfig_args="$ltconfig_args '$arg'" ;; *) ltconfig_args="$ltconfig_args $arg" ;; esac done # A relevant subset of AC_INIT. # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 5 compiler messages saved in config.log # 6 checking for... messages and results if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>>./config.log # NLS nuisances. # Only set LANG and LC_ALL to C if already set. # These must not be set unconditionally because not all systems understand # e.g. LANG=C (notably SCO). if test "X${LC_ALL+set}" = Xset; then LC_ALL=C; export LC_ALL; fi if test "X${LANG+set}" = Xset; then LANG=C; export LANG; fi if test -n "$cache_file" && test -r "$cache_file" && test -f "$cache_file"; then echo "loading cache $cache_file within ltconfig" . $cache_file fi if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi if test -z "$srcdir"; then # Assume the source directory is the same one as the path to LTMAIN. srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'` test "$srcdir" = "$ltmain" && srcdir=. fi trap "$rm conftest*; exit 1" 1 2 15 if test "$verify_host" = yes; then # Check for config.guess and config.sub. ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/config.guess; then ac_aux_dir=$ac_dir break fi done if test -z "$ac_aux_dir"; then echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2 echo "$help" 1>&2 exit 1 fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub # Make sure we can run config.sub. if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then : else echo "$progname: cannot run $ac_config_sub" 1>&2 echo "$help" 1>&2 exit 1 fi echo $ac_n "checking host system type""... $ac_c" 1>&6 host_alias=$host case $host_alias in "") # Force config.guess to use the C compiler. # CC_FOR_BUILD overrides the CC variable in config.guess but I had # problems with it so do it this way for now. CC="$LTCC" if host_alias=`$SHELL $ac_config_guess`; then : else echo "$progname: cannot guess host type; you must specify one" 1>&2 echo "$help" 1>&2 exit 1 fi # Restore the C compiler. CC="$old_CC" ;; esac host=`$SHELL $ac_config_sub $host_alias` echo "$ac_t$host" 1>&6 # Make sure the host verified. test -z "$host" && exit 1 # Check for the build system type echo $ac_n "checking build system type... $ac_c" 1>&6 build_alias=$build case $build_alias in NONE) case $nonopt in NONE) build_alias=$host_alias ;; *) build_alias=$nonopt ;; esac ;; esac build=`$SHELL $ac_config_sub $build_alias` build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$build" 1>&6 elif test -z "$host"; then echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2 echo "$help" 1>&2 exit 1 else host_alias=$host build_alias=$host_alias build=$host fi if test x"$host" != x"$build"; then ac_tool_prefix=${host_alias}- else ac_tool_prefix= fi host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` # Transform linux* to *-*-linux-gnu*, to support old configure scripts. case $host_os in linux-gnu*) ;; linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` esac case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" fi # Source the script associated with the $tagname tag configuration. if test -n "$tagname"; then . $ltmain else # FIXME: We should use a variable here # Configure for a C compiler . $srcdir/ltcf-c.sh fi # Set sane defaults for various variables test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru test -z "$AS" && AS=as test -z "$CC" && CC=cc test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$MAGIC_CMD" && MAGIC_CMD=file test -z "$LD" && LD=ld test -z "$LN_S" && LN_S="ln -s" test -z "$NM" && NM=nm test -z "$OBJDUMP" && OBJDUMP=objdump test -z "$RANLIB" && RANLIB=: test -z "$STRIP" && STRIP=: test -z "$objext" && objext=o echo $ac_n "checking for objdir... $ac_c" 1>&6 rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. objdir=_libs fi rmdir .libs 2>/dev/null echo "$ac_t$objdir" 1>&6 # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # Allow CC to be a program name with arguments. set dummy $CC compiler="$2" # We assume here that the value for ac_cv_prog_cc_pic will not be cached # in isolation, and that seeing it set (from the cache) indicates that # the associated values are set (in the cache) correctly too. echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6 echo "$progname:678:checking for $compiler option to produce PIC" 1>&5 if test -z "$ac_cv_prog_cc_pic"; then echo "$ac_t"none 1>&6 else echo "$ac_t""$ac_cv_prog_cc_pic" 1>&6 # Check to make sure the pic_flag actually works. echo $ac_n "checking if $compiler PIC flag $ac_cv_prog_cc_pic works... $ac_c" 1>&6 echo "$progname:687:checking that $compiler PIC flag $ac_cv_prog_cc_pic works." 1>&5 if test "X${ac_cv_prog_cc_pic_works+set}" = Xset && \ test "X${ac_cv_prog_cc_pic_works}" != X; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_prog_cc_pic_works=yes $rm conftest* echo $lt_simple_compile_test_code > conftest.$ac_ext save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $ac_cv_prog_cc_pic -DPIC" if { (eval echo $progname:697: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then # Append any warnings to the config.log. cat conftest.err 1>&5 case $host_os in hpux9* | hpux10* | hpux11*) # On HP-UX, both CC and GCC only warn that PIC is supported... then # they create non-PIC objects. So, if there were any warnings, we # assume that PIC is not supported. if test -s conftest.err; then ac_cv_prog_cc_pic_works=no ac_cv_prog_cc_can_build_shared=no ac_cv_prog_cc_pic= else ac_cv_prog_cc_pic_works=yes ac_cv_prog_cc_pic=" $ac_cv_prog_cc_pic" fi ;; *) ac_cv_prog_cc_pic_works=yes ac_cv_prog_cc_pic=" $ac_cv_prog_cc_pic" ;; esac else # Append any errors to the config.log. cat conftest.err 1>&5 ac_cv_prog_cc_pic_works=no ac_cv_prog_cc_can_build_shared=no ac_cv_prog_cc_pic= fi CFLAGS="$save_CFLAGS" $rm conftest* fi # Belt *and* braces to stop my trousers falling down: if test "X$ac_cv_prog_cc_pic_works" = Xno; then ac_cv_prog_cc_pic= ac_cv_prog_cc_can_build_shared=no fi echo "$ac_t""$ac_cv_prog_cc_pic_works" 1>&6 fi # Check for any special shared library compilation flags. if test -n "$ac_cv_prog_cc_shlib"; then echo "$progname: warning: \`$CC' requires \`$ac_cv_prog_cc_shlib' to build shared libraries" 1>&2 if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$ac_cv_prog_cc_shlib[ ]" >/dev/null; then : else echo "$progname: add \`$ac_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" 1>&2 ac_cv_prog_cc_can_build_shared=no fi fi echo $ac_n "checking if $compiler static flag $ac_cv_prog_cc_static works... $ac_c" 1>&6 echo "$progname:749: checking if $compiler static flag $ac_cv_prog_cc_static works" >&5 if test "X${ac_cv_prog_cc_static_works+set}" = Xset && \ test "X${ac_cv_prog_cc_static_works}" != X; then echo $ac_n "(cached) $ac_c" 1>&6 else $rm conftest* echo $lt_simple_link_test_code > conftest.$ac_ext save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $ac_cv_prog_cc_static" if { (eval echo $progname:758: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then ac_cv_prog_cc_static_works=yes else ac_cv_prog_cc_static_works=no ac_cv_prog_cc_static= fi LDFLAGS="$save_LDFLAGS" $rm conftest* fi # Belt *and* braces to stop my trousers falling down: if test "X$ac_cv_prog_cc_static_works" = Xno; then ac_cv_prog_cc_static= fi echo "$ac_t""$ac_cv_prog_cc_static_works" 1>&6 pic_flag="$ac_cv_prog_cc_pic" special_shlib_compile_flags="$ac_cv_prog_cc_shlib" wl="$ac_cv_prog_cc_wl" link_static_flag="$ac_cv_prog_cc_static" no_builtin_flag="$ac_cv_prog_cc_no_builtin" can_build_shared="$ac_cv_prog_cc_can_build_shared" # find the maximum length of command line arguments echo "$progname:780: finding the maximum length of command line arguments" 1>&5 echo $ac_n "finding the maximum length of command line arguments... $ac_c" 1>&6 if test "${lt_cv_sys_max_cmd_len+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else i=0 testring="ABCDEF" while test `$CONFIG_SHELL $0 --fallback-echo "X$testring" >/dev/null 2>&1` == `echo "X$testring" >/dev/null 2>&1` && new_result=`expr "X$testring" : ".*" 2>&1` && lt_cv_sys_max_cmd_len=$new_result && test $i != 32 # 1 MB should be enough do i=`expr $i + 1` testring=$testring$testring done testring= # add a significant safety factor because C++ compilers can tack on massive amounts # of additional arguments before passing them to the linker. 1/4 should be good. len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len - $len` fi echo "$progname:@lineno@: result: $lt_cv_sys_max_cmd_len" 1>&5 echo "${ac_t}$lt_cv_sys_max_cmd_len" 1>&6 if test -n $lt_cv_sys_max_cmd_len ; then max_cmd_len=$lt_cv_sys_max_cmd_len else max_cmd_len=none fi # Check to see if options -o and -c are simultaneously supported by compiler echo $ac_n "checking if $compiler supports -c -o file.$objext... $ac_c" 1>&6 if test "${lt_cv_compiler_c_o+set}" = set; then echo $ac_n "(cached) $ac_c" 1>&6 else $rm -r conftest 2>/dev/null mkdir conftest cd conftest $rm conftest* echo $lt_simple_compile_test_code > conftest.$ac_ext mkdir out # According to Tom Tromey, Ian Lance Taylor reported there are C compilers # that will create temporary files in the current directory regardless of # the output directory. Thus, making CWD read-only will cause this test # to fail, enabling locking or at least warning the user not to do parallel # builds. chmod -w . save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -o out/conftest2.$objext" echo "$progname:829: checking if $compiler supports -c -o file.$objext" >&5 if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$objext; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings if test -s out/conftest.err; then lt_cv_compiler_c_o=no else lt_cv_compiler_c_o=yes fi else # Append any errors to the config.log. cat out/conftest.err 1>&5 lt_cv_compiler_c_o=no fi CFLAGS="$save_CFLAGS" chmod u+w . $rm conftest* out/* rmdir out cd .. rmdir conftest $rm -r conftest 2>/dev/null fi compiler_c_o=$lt_cv_compiler_c_o echo "${ac_t}$compiler_c_o" 1>&6 # Check to see if we can do hard links to lock some files if needed hard_links="nottested" if test "$compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6 hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no echo "$ac_t$hard_links" 1>&6 $rm conftest* if test "$hard_links" = no; then echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2 need_locks=warn fi else need_locks=no fi if test "$with_gcc" = yes; then # Check to see if options -fno-rtti -fno-exceptions are supported by compiler echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6 $rm conftest* echo $lt_simple_compile_test_code > conftest.$ac_ext save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" echo "$progname:883: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 if { (eval echo $progname:884: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then echo "$ac_t"no 1>&6 compiler_rtti_exceptions=no else echo "$ac_t"yes 1>&6 compiler_rtti_exceptions=yes fi else # Append any errors to the config.log. cat conftest.err 1>&5 compiler_rtti_exceptions=no echo "$ac_t"no 1>&6 fi CFLAGS="$save_CFLAGS" $rm conftest* if test "$compiler_rtti_exceptions" = "yes"; then no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' else no_builtin_flag=' -fno-builtin' fi fi # See if the linker supports building shared libraries. echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6 echo "$ac_t$ld_shlibs" 1>&6 test "$ld_shlibs" = no && can_build_shared=no # Check hardcoding attributes. echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6 hardcode_action= if test -n "$hardcode_libdir_flag_spec" || \ test -n "$runpath_var"; then # We can hardcode non-existant directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$hardcode_shlibpath_var" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi echo "$ac_t$hardcode_action" 1>&6 echo $ac_n "checking whether stripping libraries is possible... $ac_c" 1>&6 if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" echo "${ac_t}yes" 1>&6 else echo "${ac_t}no" 1>&6 fi case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' test -z "$deplibs_check_method" && deplibs_check_method=unknown # PORTME Fill in your ld.so characteristics library_names_spec= libname_spec='lib$name' soname_spec= postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6 case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}.so$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}.so$major' ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' shlibpath_var=LD_LIBRARY_PATH else # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. # We preserve .a as extension for shared libraries though AIX4.2 # and later linker supports .so if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so instead of # lib.a to let people know that these are not typical AIX shared libraries. library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' # We want symlinks to be created for the different names. version_type=linux else # We preserve .a as extension for shared libraries though AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}.so$major.o' fi # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | egrep '(GNU)' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' fi shlibpath_var=LIBPATH deplibs_check_method=pass_all # Put the right runpath into libraries. hardcode_into_libs=yes case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then : else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. can_build_shared=no fi ;; esac fi ;; amigaos*) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' ;; beos*) library_names_spec='${libname}.so' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; bsdi4*) version_type=linux need_version=no library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' soname_spec='${libname}${release}.so$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" export_dynamic_flag_spec=-rdynamic # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32*) version_type=windows need_version=no need_lib_prefix=no case $with_gcc,$host_os in yes,cygwin*) library_names_spec='$libname.dll.a' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | [sed -e 's/[.]/-/g']`${versuffix}.dll' postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog .libs/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll; $rm \$dlpath' ;; yes,mingw*) library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"` ;; yes,pw32*) library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' ;; *) library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${versuffix}.`test .$module = .yes && echo so || echo dylib` ${libname}${release}${major}.$`test .$module = .yes && echo so || echo dylib` ${libname}.`test .$module = .yes && echo so || echo dylib`' soname_spec='${libname}${release}${major}.`test .$module = .yes && echo so || echo dylib`' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd*) objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; *) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' soname_spec='${libname}${release}.so$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. dynamic_linker="$host_os dld.sl" version_type=sunos hardcode_into_libs=all need_lib_prefix=no need_version=no shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' soname_spec='${libname}${release}.sl$major' # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; irix5* | irix6*) version_type=irix need_lib_prefix=no need_version=no soname_spec='${libname}${release}.so$major' library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' case $host_os in irix5*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ;; # No shared lib support for Linux oldld, aout, or coff. linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) dynamic_linker=no ;; # This must be Linux ELF. linux-gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' soname_spec='${libname}${release}.so$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' need_version=yes else library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' soname_spec='${libname}${release}.so$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; openbsd*) version_type=sunos if test "$with_gnu_ld" = yes; then need_lib_prefix=no need_version=no fi library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH # OpenBSD 2.7 the overriding is needed for fast-install shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' need_lib_prefix=no library_names_spec='$libname.dll $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_version=no soname_spec='${libname}${release}.so' library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; sco3.2v5*) version_type=osf soname_spec='${libname}${release}.so$major' library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' shlibpath_var=LD_LIBRARY_PATH ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' soname_spec='${libname}${release}.so$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) version_type=linux library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' soname_spec='${libname}${release}.so$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; uts4*) version_type=linux library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' soname_spec='${libname}${release}.so$major' shlibpath_var=LD_LIBRARY_PATH ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' soname_spec='${libname}${release}.so$major' shlibpath_var=LD_LIBRARY_PATH ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' soname_spec='$libname.so.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; *) dynamic_linker=no ;; esac echo "$ac_t$dynamic_linker" 1>&6 test "$dynamic_linker" = no && can_build_shared=no # Check for command to grab the raw symbol name followed by C symbol from nm. echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6 # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Transform the above into a raw symbol and a C symbol. symxfrm='\1 \2\3 \3' # Transform an extracted symbol line into a proper C declaration global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32*) symcode='[ABCDGISTW]' ;; hpux*) # Its linker distinguishes data from code symbols global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'" ;; irix*) symcode='[BCDEGRST]' ;; solaris* | sysv5*) symcode='[BDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # Handle CRLF in mingw tool chain opt_cr= case $host_os in mingw*) opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # If we're using GNU nm, then use its standard symbol codes. if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then symcode='[ABCDGISTW]' fi # Try without a prefix undercore, then with it. for ac_symprfx in "" "_"; do # Write the raw and C identifiers. global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" # Check to see that the pipe works correctly. pipe_works=no $rm conftest* cat > conftest.$ac_ext <&5 if { (eval echo $progname:1424: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then # Now try to grab the symbols. nlist=conftest.nm if { echo "$progname:1427: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if egrep ' nm_test_var$' "$nlist" >/dev/null; then if egrep ' nm_test_func$' "$nlist" >/dev/null; then cat < conftest.$ac_ext #ifdef __cplusplus extern "C" { #endif EOF # Now generate the symbol file. eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' cat <> conftest.$ac_ext #if defined (__STDC__) && __STDC__ # define lt_ptr_t void * #else # define lt_ptr_t char * # define const #endif /* The mapping between symbol names and symbols. */ const struct { const char *name; lt_ptr_t address; } lt_preloaded_symbols[] = { EOF sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.$ac_ext cat <<\EOF >> conftest.$ac_ext {0, (lt_ptr_t) 0} }; #ifdef __cplusplus } #endif EOF # Now try linking the two files. mv conftest.$objext conftstm.$objext save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="conftstm.$objext" CFLAGS="$CFLAGS$no_builtin_flag" if { (eval echo $progname:1479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then pipe_works=yes else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi LIBS="$save_LIBS" else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi $rm conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else global_symbol_pipe= fi done if test "$pipe_works" = yes; then echo "${ac_t}ok" 1>&6 else echo "${ac_t}failed" 1>&6 fi if test -z "$global_symbol_pipe"; then global_symbol_to_cdecl= fi # Report the final consequences. echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6 # Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in # configure.in, otherwise build static only libraries. case $host_os in cygwin* | mingw* | pw32* | os2*) if test x$can_build_shared = xyes; then test x$enable_win32_dll = xno && can_build_shared=no echo "checking if package supports dlls... $can_build_shared" 1>&6 fi ;; esac echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6 test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix4* | aix5*) test "$enable_shared" = yes && enable_static=no ;; esac echo "$ac_t$enable_shared" 1>&6 # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes echo "checking whether to build static libraries... $enable_static" 1>&6 if test "$hardcode_action" = relink; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$with_gcc" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi # Check whether we must set pic_mode to default test -z "$pic_flag" && pic_mode=default if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else if test "X${lt_cv_dlopen+set}" != Xset; then lt_cv_dlopen=no lt_cv_dlopen_libs= echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 echo "$progname:1583: checking for dlopen in -ldl" >&5 if test "X${ac_cv_lib_dl_dlopen+set}" = Xset; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_dl_dlopen=yes else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_lib_dl_dlopen=no fi rm -f conftest* LIBS="$ac_save_LIBS" fi if test "X$ac_cv_lib_dl_dlopen" = Xyes; then echo "$ac_t""yes" 1>&6 lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dlopen""... $ac_c" 1>&6 echo "$progname:1622: checking for dlopen" >&5 if test "X${ac_cv_func_dlopen+set}" = Xset; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_dlopen) || defined (__stub___dlopen) choke me #else dlopen(); #endif ; return 0; } EOF if { (eval echo $progname:1652: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_dlopen=yes else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_func_dlopen=no fi rm -f conftest* fi if test "X$ac_cv_func_dlopen" = Xyes; then echo "$ac_t""yes" 1>&6 lt_cv_dlopen="dlopen" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dlopen in -lsvld""... $ac_c" 1>&6 echo "$progname:1669: checking for dlopen in -lsvld" >&5 if test "X${ac_cv_lib_svld_dlopen+set}" = Xset; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsvld $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_svld_dlopen=yes else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_lib_svld_dlopen=no fi rm -f conftest* LIBS="$ac_save_LIBS" fi if test "X$ac_cv_lib_svld_dlopen" = Xyes; then echo "$ac_t""yes" 1>&6 lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6 echo "$progname:1708: checking for dld_link in -ldld" >&5 if test "X${ac_cv_lib_dld_dld_link+set}" = Xset; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldld $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_dld_dld_link=yes else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_lib_dld_dld_link=no fi rm -f conftest* LIBS="$ac_save_LIBS" fi if test "X$ac_cv_lib_dld_dld_link" = Xyes; then echo "$ac_t""yes" 1>&6 lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for shl_load""... $ac_c" 1>&6 echo "$progname:1747: checking for shl_load" >&5 if test "X${ac_cv_func_shl_load+set}" = Xset; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_shl_load) || defined (__stub___shl_load) choke me #else shl_load(); #endif ; return 0; } EOF if { (eval echo $progname:1777: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_shl_load=yes else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_func_shl_load=no fi rm -f conftest* fi if test "X$ac_cv_func_shl_load" = Xyes; then echo "$ac_t""yes" 1>&6 lt_cv_dlopen="shl_load" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 echo "$progname:1795: checking for shl_load in -ldld" >&5 if test "X${ac_cv_lib_dld_shl_load+set}" = Xset; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldld $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_lib_dld_shl_load=yes else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_lib_dld_shl_load=no fi rm -f conftest* LIBS="$ac_save_LIBS" fi if test "X$ac_cv_lib_dld_shl_load" = Xyes; then echo "$ac_t""yes" 1>&6 lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else echo "$ac_t""no" 1>&6 fi fi fi fi fi fi fi if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) for ac_hdr in dlfcn.h; do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "$progname:1863: checking for $ac_hdr" >&5 if eval "test \"`echo 'X$''{'ac_cv_header_$ac_safe'+set}'`\" = Xset"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int fnord = 0; int main () { return(0); } EOF ac_try="$ac_compile >/dev/null 2>conftest.out" { (eval echo $progname:1874: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 fi done if test "x$ac_cv_header_dlfcn_h" = xyes; then CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" fi eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" LIBS="$lt_cv_dlopen_libs $LIBS" echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6 echo "$progname:1902: checking whether a program can dlopen itself" >&5 if test "X${lt_cv_dlopen_self+set}" = Xset; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then lt_cv_dlopen_self=cross else cat > conftest.$ac_ext < #endif #include #ifdef RTLD_GLOBAL # define LTDL_GLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LTDL_GLOBAL DL_GLOBAL # else # define LTDL_GLOBAL 0 # endif #endif /* We may have to define LTDL_LAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LTDL_LAZY_OR_NOW # ifdef RTLD_LAZY # define LTDL_LAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LTDL_LAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LTDL_LAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LTDL_LAZY_OR_NOW DL_NOW # else # define LTDL_LAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42; } int main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); return 1;} EOF if { (eval echo $progname:1957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then lt_cv_dlopen_self=yes else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* lt_cv_dlopen_self=no fi rm -fr conftest* fi fi echo "$ac_t""$lt_cv_dlopen_self" 1>&6 if test "$lt_cv_dlopen_self" = yes; then LDFLAGS="$LDFLAGS $link_static_flag" echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6 echo "$progname:1976: checking whether a statically linked program can dlopen itself" >&5 if test "X${lt_cv_dlopen_self_static+set}" = Xset; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then lt_cv_dlopen_self_static=cross else cat > conftest.$ac_ext < #endif #include #ifdef RTLD_GLOBAL # define LTDL_GLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LTDL_GLOBAL DL_GLOBAL # else # define LTDL_GLOBAL 0 # endif #endif /* We may have to define LTDL_LAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LTDL_LAZY_OR_NOW # ifdef RTLD_LAZY # define LTDL_LAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LTDL_LAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LTDL_LAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LTDL_LAZY_OR_NOW DL_NOW # else # define LTDL_LAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42; } int main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); return 1; } EOF if { (eval echo $progname:2031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then lt_cv_dlopen_self_static=yes else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* lt_cv_dlopen_self_static=no fi rm -fr conftest* fi fi echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6 fi ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi # Copy echo and quote the copy, instead of the original, because it is # used later. ltecho="$echo" if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then ltecho="$CONFIG_SHELL \$0 --fallback-echo" fi LTSHELL="$SHELL" LTCONFIG_VERSION="$VERSION" # Only quote variables if we're using ltmain.sh. case $ltmain in *.sh) # Now quote all the things that may contain metacharacters. for var in ltecho old_AR old_AR_FLAGS old_CC old_LTCC old_CFLAGS old_CPPFLAGS \ old_MAGIC_CMD old_LD old_LDFLAGS old_LIBS \ old_LN_S old_NM old_RANLIB old_STRIP \ old_AS old_DLLTOOL old_OBJDUMP \ old_OBJEXT old_EXEEXT old_reload_flag \ old_deplibs_check_method old_file_magic_cmd \ AR AR_FLAGS CC LTCC LD LN_S NM LTSHELL LTCONFIG_VERSION \ reload_flag reload_cmds wl \ pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ thread_safe_flag_spec whole_archive_flag_spec libname_spec \ library_names_spec soname_spec \ RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \ postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \ predep_objects postdep_objects predeps postdeps compiler_lib_search_path \ old_striplib striplib file_magic_cmd export_symbols_cmds \ deplibs_check_method allow_undefined_flag no_undefined_flag \ finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ hardcode_libdir_flag_spec hardcode_libdir_separator \ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ compiler_c_o need_locks exclude_expsyms include_expsyms; do case $var in reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ old_postinstall_cmds | old_postuninstall_cmds | \ export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ postinstall_cmds | postuninstall_cmds | \ finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) # Double-quote double-evaled strings. eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" ### testsuite: skip nested quoting test ;; *) eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" ### testsuite: skip nested quoting test ;; esac done case $ltecho in *'\$0 --fallback-echo"') ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ;; esac if test -z "$tagname"; then trap "$rm \"$ofile\"; exit 1" 1 2 15 echo "creating $ofile" $rm "$ofile" cat < "$ofile" #! $SHELL # `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) # NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh. # # Copyright (C) 1996-2000 Free Software Foundation, Inc. # Originally by Gordon Matzigkeit , 1996 # # 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. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="sed -e s/^X//" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi # The names of the tagged configurations supported by this script. available_tags= ### BEGIN LIBTOOL CONFIG EOF else echo "appending configuration tag \"$tagname\" to $ofile" echo "### BEGIN LIBTOOL TAG CONFIG: $tagname" >> "$ofile" fi cfgfile="$ofile" ;; *) # Double-quote the variables that need it (for aesthetics). for var in old_AR old_AR_FLAGS old_CC old_LTCC old_CFLAGS old_CPPFLAGS \ old_MAGIC_CMD old_LD old_LDFLAGS old_LIBS \ old_LN_S old_NM old_RANLIB old_STRIP \ old_AS old_DLLTOOL old_OBJDUMP \ old_OBJEXT old_EXEEXT old_reload_flag \ old_deplibs_check_method old_file_magic_cmd; do eval "$var=\\\"\$var\\\"" done # Just create a config file. cfgfile="$ofile.cfg" if test -z "$tagname"; then trap "$rm \"$cfgfile\"; exit 1" 1 2 15 echo "creating $cfgfile" $rm "$cfgfile" cat < "$cfgfile" # `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file. # Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) ### BEGIN LIBTOOL CONFIG EOF else echo "appending to $cfgfile" echo "### BEGIN LIBTOOL TAG CONFIG: $tagname" >> "$ofile" fi ;; esac cat <> "$cfgfile" # Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # # AR=$old_AR AR_FLAGS=$old_AR_FLAGS LTCC=$old_LTCC CC=$old_CC \\ # CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\ # MAGIC_CMD=$old_MAGIC_CMD LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\ # LN_S=$old_LN_S NM=$old_NM RANLIB=$old_RANLIB STRIP=$old_STRIP \\ # AS=$old_AS DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP \\ # objext=$old_OBJEXT exeext=$old_EXEEXT reload_flag=$old_reload_flag \\ # deplibs_check_method=$old_deplibs_check_method \\ # file_magic_cmd=$old_file_magic_cmd \\ # $0$ltconfig_args # # Compiler and other test output produced by $progname, useful for # debugging $progname, is in ./config.log if it exists. # The version of $progname that generated this script. LTCONFIG_VERSION=$LTCONFIG_VERSION # Shell to use when invoking shell scripts. SHELL=$LTSHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$need_lc # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host # An echo program that does not interpret backslashes. echo=$ltecho # The archiver. AR=$AR AR_FLAGS=$AR_FLAGS # A C compiler. LTCC=$LTCC # A language-specific compiler. CC=$CC # Is the compiler the GNU C compiler? with_gcc=$with_gcc # The linker used to build libraries. LD=$LD # Whether we need hard or soft links. LN_S=$LN_S # A BSD-compatible nm program. NM=$NM # A symbol stripping program STRIP=$STRIP # Used to examine libraries when file_magic_cmd begins "file" MAGIC_CMD=$MAGIC_CMD # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$reload_flag reload_cmds=$reload_cmds # How to pass a linker flag through the compiler. wl=$wl # Object file suffix (normally "o"). objext="$objext" # Old archive suffix (normally "a"). libext="$libext" # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$pic_flag pic_mode=$pic_mode # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$compiler_c_o # Must we lock files when doing compilation ? need_locks=$need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$link_static_flag # Compiler flag to turn off builtin functions. no_builtin_flag=$no_builtin_flag # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$whole_archive_flag_spec # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$thread_safe_flag_spec # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$library_names_spec # The coded name of the library, if different from the real name. soname_spec=$soname_spec # Commands used to build and install an old-style archive. RANLIB=$RANLIB old_archive_cmds=$old_archive_cmds old_postinstall_cmds=$old_postinstall_cmds old_postuninstall_cmds=$old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$old_archive_from_expsyms_cmds # Commands used to build and install a shared archive. archive_cmds=$archive_cmds archive_expsym_cmds=$archive_expsym_cmds postinstall_cmds=$postinstall_cmds postuninstall_cmds=$postuninstall_cmds # Commands to strip libraries. old_striplib=$old_striplib striplib=$striplib # Dependencies to place before the objects being linked to create a # shared library. predep_objects=$predep_objects # Dependencies to place after the objects being linked to create a # shared library. postdep_objects=$postdep_objects # Dependencies to place before the objects being linked to create a # shared library. predeps=$predeps # Dependencies to place after the objects being linked to create a # shared library. postdeps=$postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$compiler_lib_search_path # Method to check whether dependent libraries are shared objects. deplibs_check_method=$deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$allow_undefined_flag # Flag that forces no undefined symbols. no_undefined_flag=$no_undefined_flag # Commands used to finish a libtool library installation in a directory. finish_cmds=$finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$global_symbol_to_cdecl # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$hardcode_libdir_separator # Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the # resulting binary. hardcode_direct=$hardcode_direct # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. variables_saved_for_relink="$variables_saved_for_relink" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Compile-time system search path for libraries sys_lib_search_path_spec=$sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$fix_srcfile_path" # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$export_symbols_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$extract_expsyms_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$exclude_expsyms # Symbols that must always be exported. include_expsyms=$include_expsyms EOF if test -z "$tagname"; then echo '### END LIBTOOL CONFIG' >> "$ofile" else echo "### END LIBTOOL TAG CONFIG: $tagname" >> "$ofile" fi case $ltmain in *.sh) echo >> "$ofile" if test -z "$tagname"; then case $host_os in aix3*) cat <<\EOF >> "$ofile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi EOF ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) cat <<'EOF' >> "$ofile" # This is a source program that is used to create dlls on Windows # Don't remove nor modify the starting and closing comments # /* ltdll.c starts here */ # #define WIN32_LEAN_AND_MEAN # #include # #undef WIN32_LEAN_AND_MEAN # #include # # #ifndef __CYGWIN__ # # ifdef __CYGWIN32__ # # define __CYGWIN__ __CYGWIN32__ # # endif # #endif # # #ifdef __cplusplus # extern "C" { # #endif # BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); # #ifdef __cplusplus # } # #endif # # #ifdef __CYGWIN__ # #include # DECLARE_CYGWIN_DLL( DllMain ); # #endif # HINSTANCE __hDllInstance_base; # # BOOL APIENTRY # DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) # { # __hDllInstance_base = hInst; # return TRUE; # } # /* ltdll.c ends here */ # This is a source program that is used to create import libraries # on Windows for dlls which lack them. Don't remove nor modify the # starting and closing comments # /* impgen.c starts here */ # /* Copyright (C) 1999-2000 Free Software Foundation, Inc. # # This file is part of GNU libtool. # # 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. # */ # # #include /* for printf() */ # #include /* for open(), lseek(), read() */ # #include /* for O_RDONLY, O_BINARY */ # #include /* for strdup() */ # # /* O_BINARY isn't required (or even defined sometimes) under Unix */ # #ifndef O_BINARY # #define O_BINARY 0 # #endif # # static unsigned int # pe_get16 (fd, offset) # int fd; # int offset; # { # unsigned char b[2]; # lseek (fd, offset, SEEK_SET); # read (fd, b, 2); # return b[0] + (b[1]<<8); # } # # static unsigned int # pe_get32 (fd, offset) # int fd; # int offset; # { # unsigned char b[4]; # lseek (fd, offset, SEEK_SET); # read (fd, b, 4); # return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); # } # # static unsigned int # pe_as32 (ptr) # void *ptr; # { # unsigned char *b = ptr; # return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); # } # # int # main (argc, argv) # int argc; # char *argv[]; # { # int dll; # unsigned long pe_header_offset, opthdr_ofs, num_entries, i; # unsigned long export_rva, export_size, nsections, secptr, expptr; # unsigned long name_rvas, nexp; # unsigned char *expdata, *erva; # char *filename, *dll_name; # # filename = argv[1]; # # dll = open(filename, O_RDONLY|O_BINARY); # if (dll < 1) # return 1; # # dll_name = filename; # # for (i=0; filename[i]; i++) # if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') # dll_name = filename + i +1; # # pe_header_offset = pe_get32 (dll, 0x3c); # opthdr_ofs = pe_header_offset + 4 + 20; # num_entries = pe_get32 (dll, opthdr_ofs + 92); # # if (num_entries < 1) /* no exports */ # return 1; # # export_rva = pe_get32 (dll, opthdr_ofs + 96); # export_size = pe_get32 (dll, opthdr_ofs + 100); # nsections = pe_get16 (dll, pe_header_offset + 4 +2); # secptr = (pe_header_offset + 4 + 20 + # pe_get16 (dll, pe_header_offset + 4 + 16)); # # expptr = 0; # for (i = 0; i < nsections; i++) # { # char sname[8]; # unsigned long secptr1 = secptr + 40 * i; # unsigned long vaddr = pe_get32 (dll, secptr1 + 12); # unsigned long vsize = pe_get32 (dll, secptr1 + 16); # unsigned long fptr = pe_get32 (dll, secptr1 + 20); # lseek(dll, secptr1, SEEK_SET); # read(dll, sname, 8); # if (vaddr <= export_rva && vaddr+vsize > export_rva) # { # expptr = fptr + (export_rva - vaddr); # if (export_rva + export_size > vaddr + vsize) # export_size = vsize - (export_rva - vaddr); # break; # } # } # # expdata = (unsigned char*)malloc(export_size); # lseek (dll, expptr, SEEK_SET); # read (dll, expdata, export_size); # erva = expdata - export_rva; # # nexp = pe_as32 (expdata+24); # name_rvas = pe_as32 (expdata+32); # # printf ("EXPORTS\n"); # for (i = 0; i> "$ofile" || (rm -f "$ofile"; exit 1) # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? chmod +x "$ofile" fi ;; *) # Compile the libtool program. echo "FIXME: would compile $ltmain" ;; esac # Update the list of available tags. if test -n "$tagname"; then # Extract list of available tagged configurations in $ofile. # Note that this assumes the entire list is on one line. available_tags=`grep "^available_tags=" $ofile | sed -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` # Append the new tag name to the list of available tags. available_tags="$available_tags $tagname" # Now substitute the updated of available tags. if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' ${ofile} > ${ofile}.new"; then mv ${ofile}.new ${ofile} chmod +x "$ofile" else rm -f ${ofile}.new echo "$progname: unable to update list of available tagged configurations." exit 1 fi fi # Don't cache tagged configuration! test -n "$cache_file" && test -z "$tagname" || exit 0 # AC_CACHE_SAVE trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache exit 0 # Local Variables: # mode:shell-script # sh-indentation:2 # End: indi-0.5/aclocal.m40000644000175000017500000077573410610536730012001 0ustar jrjr# generated automatically by aclocal 1.9.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # serial 48 AC_PROG_LIBTOOL # AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) # ----------------------------------------------------------- # If this macro is not defined by Autoconf, define it here. m4_ifdef([AC_PROVIDE_IFELSE], [], [m4_define([AC_PROVIDE_IFELSE], [m4_ifdef([AC_PROVIDE_$1], [$2], [$3])])]) # AC_PROG_LIBTOOL # --------------- AC_DEFUN([AC_PROG_LIBTOOL], [AC_REQUIRE([_AC_PROG_LIBTOOL])dnl dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. AC_PROVIDE_IFELSE([AC_PROG_CXX], [AC_LIBTOOL_CXX], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX ])]) dnl And a similar setup for Fortran 77 support AC_PROVIDE_IFELSE([AC_PROG_F77], [AC_LIBTOOL_F77], [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 ])]) dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [AC_LIBTOOL_GCJ], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [AC_LIBTOOL_GCJ], [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], [AC_LIBTOOL_GCJ], [ifdef([AC_PROG_GCJ], [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) ifdef([A][M_PROG_GCJ], [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) ifdef([LT_AC_PROG_GCJ], [define([LT_AC_PROG_GCJ], defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) ])])# AC_PROG_LIBTOOL # _AC_PROG_LIBTOOL # ---------------- AC_DEFUN([_AC_PROG_LIBTOOL], [AC_REQUIRE([AC_LIBTOOL_SETUP])dnl AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl # Prevent multiple expansion define([AC_PROG_LIBTOOL], []) ])# _AC_PROG_LIBTOOL # AC_LIBTOOL_SETUP # ---------------- AC_DEFUN([AC_LIBTOOL_SETUP], [AC_PREREQ(2.50)dnl AC_REQUIRE([AC_ENABLE_SHARED])dnl AC_REQUIRE([AC_ENABLE_STATIC])dnl AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_LD])dnl AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl AC_REQUIRE([AC_PROG_NM])dnl AC_REQUIRE([AC_PROG_LN_S])dnl AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl # Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! AC_REQUIRE([AC_OBJEXT])dnl AC_REQUIRE([AC_EXEEXT])dnl dnl AC_LIBTOOL_SYS_MAX_CMD_LEN AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE AC_LIBTOOL_OBJDIR AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl _LT_AC_PROG_ECHO_BACKSLASH case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='sed -e 1s/^X//' [sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] # Same as above, but do not quote variable references. [double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' # Constants: rm="rm -f" # Global variables: default_ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a ltmain="$ac_aux_dir/ltmain.sh" ofile="$default_ofile" with_gnu_ld="$lt_cv_prog_gnu_ld" AC_CHECK_TOOL(AR, ar, false) AC_CHECK_TOOL(RANLIB, ranlib, :) AC_CHECK_TOOL(STRIP, strip, :) old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru test -z "$AS" && AS=as test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$LD" && LD=ld test -z "$LN_S" && LN_S="ln -s" test -z "$MAGIC_CMD" && MAGIC_CMD=file test -z "$NM" && NM=nm test -z "$SED" && SED=sed test -z "$OBJDUMP" && OBJDUMP=objdump test -z "$RANLIB" && RANLIB=: test -z "$STRIP" && STRIP=: test -z "$ac_objext" && ac_objext=o # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then AC_PATH_MAGIC fi ;; esac AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], enable_win32_dll=yes, enable_win32_dll=no) AC_ARG_ENABLE([libtool-lock], [AC_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes AC_ARG_WITH([pic], [AC_HELP_STRING([--with-pic], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [pic_mode="$withval"], [pic_mode=default]) test -z "$pic_mode" && pic_mode=default # Use C for the default configuration in the libtool script tagname= AC_LIBTOOL_LANG_C_CONFIG _LT_AC_TAGCONFIG ])# AC_LIBTOOL_SETUP # _LT_AC_SYS_COMPILER # ------------------- AC_DEFUN([_LT_AC_SYS_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_AC_SYS_COMPILER # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. AC_DEFUN([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ]) # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. AC_DEFUN([_LT_COMPILER_BOILERPLATE], [ac_outfile=conftest.$ac_objext printf "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. AC_DEFUN([_LT_LINKER_BOILERPLATE], [ac_outfile=conftest.$ac_objext printf "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $rm conftest* ])# _LT_LINKER_BOILERPLATE # _LT_AC_SYS_LIBPATH_AIX # ---------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], [AC_LINK_IFELSE(AC_LANG_PROGRAM,[ aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'`; fi],[]) if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ])# _LT_AC_SYS_LIBPATH_AIX # _LT_AC_SHELL_INIT(ARG) # ---------------------- AC_DEFUN([_LT_AC_SHELL_INIT], [ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], [AC_DIVERT_PUSH(NOTICE)]) $1 AC_DIVERT_POP ])# _LT_AC_SHELL_INIT # _LT_AC_PROG_ECHO_BACKSLASH # -------------------------- # Add some code to the start of the generated configure script which # will find an echo command which doesn't interpret backslashes. AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], [_LT_AC_SHELL_INIT([ # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` ;; esac echo=${ECHO-echo} if test "X[$]1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X[$]1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then # Yippee, $echo works! : else # Restart under the correct shell. exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} fi if test "X[$]1" = X--fallback-echo; then # used as fallback echo shift cat </dev/null 2>&1 && unset CDPATH if test -z "$ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if (echo_test_string=`eval $cmd`) 2>/dev/null && echo_test_string=`eval $cmd` && (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null then break fi done fi if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then echo="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$echo" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. echo='print -r' elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} else # Try using printf. echo='printf %s\n' if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL echo="$CONFIG_SHELL [$]0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then echo="$CONFIG_SHELL [$]0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "[$]0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} else # Oops. We lost completely, so just stick with echo. echo=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. ECHO=$echo if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" fi AC_SUBST(ECHO) ])])# _LT_AC_PROG_ECHO_BACKSLASH # _LT_AC_LOCK # ----------- AC_DEFUN([_LT_AC_LOCK], [AC_ARG_ENABLE([libtool-lock], [AC_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line __oline__ "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) LD="${LD-ld} -64" ;; esac ;; esac fi rm -rf conftest* ;; AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], [*-*-cygwin* | *-*-mingw* | *-*-pw32*) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; ]) esac need_locks="$enable_libtool_lock" ])# _LT_AC_LOCK # AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [AC_REQUIRE([LT_AC_PROG_SED]) AC_CACHE_CHECK([$1], [$2], [$2=no ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $rm conftest* ]) if test x"[$]$2" = xyes; then ifelse([$5], , :, [$5]) else ifelse([$6], , :, [$6]) fi ])# AC_LIBTOOL_COMPILER_OPTION # AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ------------------------------------------------------------ # Check whether the given compiler option works AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" printf "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $rm conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then ifelse([$4], , :, [$4]) else ifelse([$5], , :, [$5]) fi ])# AC_LIBTOOL_LINKER_OPTION # AC_LIBTOOL_SYS_MAX_CMD_LEN # -------------------------- AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [# find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ = "XX$teststring") >/dev/null 2>&1 && new_result=`expr "X$teststring" : ".*" 2>&1` && lt_cv_sys_max_cmd_len=$new_result && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done teststring= # Add a significant safety factor because C++ compilers can tack on massive # amounts of additional arguments before passing them to the linker. # It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi ])# AC_LIBTOOL_SYS_MAX_CMD_LEN # _LT_AC_CHECK_DLFCN # ------------------ AC_DEFUN([_LT_AC_CHECK_DLFCN], [AC_CHECK_HEADERS(dlfcn.h)dnl ])# _LT_AC_CHECK_DLFCN # _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # --------------------------------------------------------------------- AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], [AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif #ifdef __cplusplus extern "C" void exit (int); #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); exit (status); }] EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_AC_TRY_DLOPEN_SELF # AC_LIBTOOL_DLOPEN_SELF # ---------------------- AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_AC_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_AC_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi ])# AC_LIBTOOL_DLOPEN_SELF # AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) # --------------------------------- # Check to see if options -c and -o are simultaneously supported by compiler AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], [AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $rm -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out printf "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files $rm out/* && rmdir out cd .. rmdir conftest $rm conftest* ]) ])# AC_LIBTOOL_PROG_CC_C_O # AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) # ----------------------------------------- # Check to see if we can do hard links to lock some files if needed AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_REQUIRE([_LT_AC_LOCK])dnl hard_links="nottested" if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi ])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS # AC_LIBTOOL_OBJDIR # ----------------- AC_DEFUN([AC_LIBTOOL_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir ])# AC_LIBTOOL_OBJDIR # AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) # ---------------------------------------------- # Check hardcoding attributes. AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_AC_TAGVAR(hardcode_action, $1)= if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existant directories. if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_AC_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_AC_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_AC_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi ])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH # AC_LIBTOOL_SYS_LIB_STRIP # ------------------------ AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], [striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi ])# AC_LIBTOOL_SYS_LIB_STRIP # AC_LIBTOOL_SYS_DYNAMIC_LINKER # ----------------------------- # PORTME Fill in your ld.so characteristics AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_MSG_CHECKING([dynamic linker characteristics]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix4* | aix5*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` else sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' fi sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; kfreebsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='GNU ld.so' ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[123]]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; freebsd*) # from 4.6 on shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix3*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; knetbsd*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='GNU ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; nto-qnx*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no export_dynamic_flag_spec='${wl}-Blargedynsym' runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' shlibpath_overrides_runpath=no else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' shlibpath_overrides_runpath=yes case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi ])# AC_LIBTOOL_SYS_DYNAMIC_LINKER # _LT_AC_TAGCONFIG # ---------------- AC_DEFUN([_LT_AC_TAGCONFIG], [AC_ARG_WITH([tags], [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], [include additional configurations @<:@automatic@:>@])], [tagnames="$withval"]) if test -f "$ltmain" && test -n "$tagnames"; then if test ! -f "${ofile}"; then AC_MSG_WARN([output file `$ofile' does not exist]) fi if test -z "$LTCC"; then eval "`$SHELL ${ofile} --config | grep '^LTCC='`" if test -z "$LTCC"; then AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) else AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) fi fi if test -z "$LTCFLAGS"; then eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" fi # Extract list of available tagged configurations in $ofile. # Note that this assumes the entire list is on one line. available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for tagname in $tagnames; do IFS="$lt_save_ifs" # Check whether tagname contains only valid characters case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in "") ;; *) AC_MSG_ERROR([invalid tag name: $tagname]) ;; esac if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null then AC_MSG_ERROR([tag name \"$tagname\" already exists]) fi # Update the list of available tags. if test -n "$tagname"; then echo appending configuration tag \"$tagname\" to $ofile case $tagname in CXX) if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_LIBTOOL_LANG_CXX_CONFIG else tagname="" fi ;; F77) if test -n "$F77" && test "X$F77" != "Xno"; then AC_LIBTOOL_LANG_F77_CONFIG else tagname="" fi ;; GCJ) if test -n "$GCJ" && test "X$GCJ" != "Xno"; then AC_LIBTOOL_LANG_GCJ_CONFIG else tagname="" fi ;; RC) AC_LIBTOOL_LANG_RC_CONFIG ;; *) AC_MSG_ERROR([Unsupported tag name: $tagname]) ;; esac # Append the new tag name to the list of available tags. if test -n "$tagname" ; then available_tags="$available_tags $tagname" fi fi done IFS="$lt_save_ifs" # Now substitute the updated list of available tags. if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then mv "${ofile}T" "$ofile" chmod +x "$ofile" else rm -f "${ofile}T" AC_MSG_ERROR([unable to update list of available tagged configurations.]) fi fi ])# _LT_AC_TAGCONFIG # AC_LIBTOOL_DLOPEN # ----------------- # enable checks for dlopen support AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) ])# AC_LIBTOOL_DLOPEN # AC_LIBTOOL_WIN32_DLL # -------------------- # declare package support for building win32 DLLs AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) ])# AC_LIBTOOL_WIN32_DLL # AC_ENABLE_SHARED([DEFAULT]) # --------------------------- # implement the --enable-shared flag # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. AC_DEFUN([AC_ENABLE_SHARED], [define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl AC_ARG_ENABLE([shared], [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]AC_ENABLE_SHARED_DEFAULT) ])# AC_ENABLE_SHARED # AC_DISABLE_SHARED # ----------------- # set the default shared flag to --disable-shared AC_DEFUN([AC_DISABLE_SHARED], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl AC_ENABLE_SHARED(no) ])# AC_DISABLE_SHARED # AC_ENABLE_STATIC([DEFAULT]) # --------------------------- # implement the --enable-static flag # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. AC_DEFUN([AC_ENABLE_STATIC], [define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl AC_ARG_ENABLE([static], [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]AC_ENABLE_STATIC_DEFAULT) ])# AC_ENABLE_STATIC # AC_DISABLE_STATIC # ----------------- # set the default static flag to --disable-static AC_DEFUN([AC_DISABLE_STATIC], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl AC_ENABLE_STATIC(no) ])# AC_DISABLE_STATIC # AC_ENABLE_FAST_INSTALL([DEFAULT]) # --------------------------------- # implement the --enable-fast-install flag # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. AC_DEFUN([AC_ENABLE_FAST_INSTALL], [define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl AC_ARG_ENABLE([fast-install], [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) ])# AC_ENABLE_FAST_INSTALL # AC_DISABLE_FAST_INSTALL # ----------------------- # set the default to --disable-fast-install AC_DEFUN([AC_DISABLE_FAST_INSTALL], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl AC_ENABLE_FAST_INSTALL(no) ])# AC_DISABLE_FAST_INSTALL # AC_LIBTOOL_PICMODE([MODE]) # -------------------------- # implement the --with-pic flag # MODE is either `yes' or `no'. If omitted, it defaults to `both'. AC_DEFUN([AC_LIBTOOL_PICMODE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl pic_mode=ifelse($#,1,$1,default) ])# AC_LIBTOOL_PICMODE # AC_PROG_EGREP # ------------- # This is predefined starting with Autoconf 2.54, so this conditional # definition can be removed once we require Autoconf 2.54 or later. m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], [AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi]) EGREP=$ac_cv_prog_egrep AC_SUBST([EGREP]) ])]) # AC_PATH_TOOL_PREFIX # ------------------- # find a file program which can recognise shared library AC_DEFUN([AC_PATH_TOOL_PREFIX], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="ifelse([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi ])# AC_PATH_TOOL_PREFIX # AC_PATH_MAGIC # ------------- # find a file program which can recognise a shared library AC_DEFUN([AC_PATH_MAGIC], [AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# AC_PATH_MAGIC # AC_PROG_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([AC_PROG_LD], [AC_ARG_WITH([gnu-ld], [AC_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no]) AC_REQUIRE([LT_AC_PROG_SED])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix3*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux*) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; nto-qnx*) lt_cv_deplibs_check_method=unknown ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown ])# AC_DEPLIBS_CHECK_METHOD # AC_PROG_NM # ---------- # find the pathname to a BSD-compatible name lister AC_DEFUN([AC_PROG_NM], [AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm fi]) NM="$lt_cv_path_NM" ])# AC_PROG_NM # AC_CHECK_LIBM # ------------- # check for math library AC_DEFUN([AC_CHECK_LIBM], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac ])# AC_CHECK_LIBM # AC_LIBLTDL_CONVENIENCE([DIRECTORY]) # ----------------------------------- # sets LIBLTDL to the link flags for the libltdl convenience library and # LTDLINCL to the include flags for the libltdl header and adds # --enable-ltdl-convenience to the configure arguments. Note that # AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, # it is assumed to be `libltdl'. LIBLTDL will be prefixed with # '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/' # (note the single quotes!). If your package is not flat and you're not # using automake, define top_builddir and top_srcdir appropriately in # the Makefiles. AC_DEFUN([AC_LIBLTDL_CONVENIENCE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl case $enable_ltdl_convenience in no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; "") enable_ltdl_convenience=yes ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; esac LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) # For backwards non-gettext consistent compatibility... INCLTDL="$LTDLINCL" ])# AC_LIBLTDL_CONVENIENCE # AC_LIBLTDL_INSTALLABLE([DIRECTORY]) # ----------------------------------- # sets LIBLTDL to the link flags for the libltdl installable library and # LTDLINCL to the include flags for the libltdl header and adds # --enable-ltdl-install to the configure arguments. Note that # AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, # and an installed libltdl is not found, it is assumed to be `libltdl'. # LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with # '${top_srcdir}/' (note the single quotes!). If your package is not # flat and you're not using automake, define top_builddir and top_srcdir # appropriately in the Makefiles. # In the future, this macro may have to be called after AC_PROG_LIBTOOL. AC_DEFUN([AC_LIBLTDL_INSTALLABLE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl AC_CHECK_LIB(ltdl, lt_dlinit, [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], [if test x"$enable_ltdl_install" = xno; then AC_MSG_WARN([libltdl not installed, but installation disabled]) else enable_ltdl_install=yes fi ]) if test x"$enable_ltdl_install" = x"yes"; then ac_configure_args="$ac_configure_args --enable-ltdl-install" LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) else ac_configure_args="$ac_configure_args --enable-ltdl-install=no" LIBLTDL="-lltdl" LTDLINCL= fi # For backwards non-gettext consistent compatibility... INCLTDL="$LTDLINCL" ])# AC_LIBLTDL_INSTALLABLE # AC_LIBTOOL_CXX # -------------- # enable support for C++ libraries AC_DEFUN([AC_LIBTOOL_CXX], [AC_REQUIRE([_LT_AC_LANG_CXX]) ])# AC_LIBTOOL_CXX # _LT_AC_LANG_CXX # --------------- AC_DEFUN([_LT_AC_LANG_CXX], [AC_REQUIRE([AC_PROG_CXX]) AC_REQUIRE([_LT_AC_PROG_CXXCPP]) _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) ])# _LT_AC_LANG_CXX # _LT_AC_PROG_CXXCPP # ------------------ AC_DEFUN([_LT_AC_PROG_CXXCPP], [ AC_REQUIRE([AC_PROG_CXX]) if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP fi ])# _LT_AC_PROG_CXXCPP # AC_LIBTOOL_F77 # -------------- # enable support for Fortran 77 libraries AC_DEFUN([AC_LIBTOOL_F77], [AC_REQUIRE([_LT_AC_LANG_F77]) ])# AC_LIBTOOL_F77 # _LT_AC_LANG_F77 # --------------- AC_DEFUN([_LT_AC_LANG_F77], [AC_REQUIRE([AC_PROG_F77]) _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) ])# _LT_AC_LANG_F77 # AC_LIBTOOL_GCJ # -------------- # enable support for GCJ libraries AC_DEFUN([AC_LIBTOOL_GCJ], [AC_REQUIRE([_LT_AC_LANG_GCJ]) ])# AC_LIBTOOL_GCJ # _LT_AC_LANG_GCJ # --------------- AC_DEFUN([_LT_AC_LANG_GCJ], [AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) ])# _LT_AC_LANG_GCJ # AC_LIBTOOL_RC # ------------- # enable support for Windows resource files AC_DEFUN([AC_LIBTOOL_RC], [AC_REQUIRE([LT_AC_PROG_RC]) _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) ])# AC_LIBTOOL_RC # AC_LIBTOOL_LANG_C_CONFIG # ------------------------ # Ensure that the configuration vars for the C compiler are # suitably defined. Those variables are subsequently used by # AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) AC_DEFUN([_LT_AC_LANG_C_CONFIG], [lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;\n" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}\n' _LT_AC_SYS_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) AC_LIBTOOL_PROG_COMPILER_PIC($1) AC_LIBTOOL_PROG_CC_C_O($1) AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) AC_LIBTOOL_PROG_LD_SHLIBS($1) AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) AC_LIBTOOL_SYS_LIB_STRIP AC_LIBTOOL_DLOPEN_SELF # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix4* | aix5*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) AC_LIBTOOL_CONFIG($1) AC_LANG_POP CC="$lt_save_CC" ])# AC_LIBTOOL_LANG_C_CONFIG # AC_LIBTOOL_LANG_CXX_CONFIG # -------------------------- # Ensure that the configuration vars for the C compiler are # suitably defined. Those variables are subsequently used by # AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], [AC_LANG_PUSH(C++) AC_REQUIRE([AC_PROG_CXX]) AC_REQUIRE([_LT_AC_PROG_CXXCPP]) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(allow_undefined_flag, $1)= _LT_AC_TAGVAR(always_export_symbols, $1)=no _LT_AC_TAGVAR(archive_expsym_cmds, $1)= _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= _LT_AC_TAGVAR(hardcode_minus_L, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_AC_TAGVAR(hardcode_automatic, $1)=no _LT_AC_TAGVAR(module_cmds, $1)= _LT_AC_TAGVAR(module_expsym_cmds, $1)= _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown _LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_AC_TAGVAR(no_undefined_flag, $1)= _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Dependencies to place before and after the object being linked: _LT_AC_TAGVAR(predep_objects, $1)= _LT_AC_TAGVAR(postdep_objects, $1)= _LT_AC_TAGVAR(predeps, $1)= _LT_AC_TAGVAR(postdeps, $1)= _LT_AC_TAGVAR(compiler_lib_search_path, $1)= # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;\n" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_AC_SYS_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} compiler=$CC _LT_AC_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) # We don't want -fno-exception wen compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration AC_PROG_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ grep 'no-whole-archive' > /dev/null; then _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_AC_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_AC_TAGVAR(archive_cmds, $1)='' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 _LT_AC_TAGVAR(hardcode_direct, $1)=yes else # We have old collect2 _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_AC_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_AC_TAGVAR(always_export_symbols, $1)=no _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; darwin* | rhapsody*) case $host_os in rhapsody* | darwin1.[[012]]) _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' ;; *) # Darwin 1.3 on if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' else case ${MACOSX_DEPLOYMENT_TARGET} in 10.[[012]]) _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' ;; esac fi ;; esac _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_automatic, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes if test "$GXX" = yes ; then lt_int_apple_cc_single_mod=no output_verbose_link_cmd='echo' if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then lt_int_apple_cc_single_mod=yes fi if test "X$lt_int_apple_cc_single_mod" = Xyes ; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' else _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' fi _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds if test "X$lt_int_apple_cc_single_mod" = Xyes ; then _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' fi _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else case $cc_basename in xlc*) output_verbose_link_cmd='echo' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac fi ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd[[12]]*) # C++ shared libraries reported to be fairly broken before switch to ELF _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | kfreebsd*-gnu | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_AC_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; hpux9*) _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes; then _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' ;; *) _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix3*) _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' fi fi _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ;; linux*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc*) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC*) # Portland Group C++ compiler _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; openbsd2*) # C++ shared libraries are fairly broken _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd='echo' ;; osf3*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; cxx*) _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' else # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; cxx*) _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ $rm $lib.exp' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' else # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The C++ compiler is used as linker so we must use $wl # flag to pass the commands to the underlying system # linker. We must also pass each convience library through # to the system linker between allextract/defaultextract. # The C++ compiler will combine linker options so we # cannot just pass the convience library names through # without $wl. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; esac _LT_AC_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | grep -v '^2\.7' > /dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. # So that behaviour is only enabled if SCOABSPATH is set to a # non-empty value in the environment. Most likely only useful for # creating official distributions of packages. # This is a hack until libtool officially supports absolute path # names for shared libraries. _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_AC_TAGVAR(GCC, $1)="$GXX" _LT_AC_TAGVAR(LD, $1)="$LD" AC_LIBTOOL_POSTDEP_PREDEP($1) AC_LIBTOOL_PROG_COMPILER_PIC($1) AC_LIBTOOL_PROG_CC_C_O($1) AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) AC_LIBTOOL_PROG_LD_SHLIBS($1) AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) AC_LIBTOOL_CONFIG($1) AC_LANG_POP CC=$lt_save_CC LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ldcxx=$with_gnu_ld with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld ])# AC_LIBTOOL_LANG_CXX_CONFIG # AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) # ------------------------------------ # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <> "$cfgfile" ifelse([$1], [], [#! $SHELL # `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 # Free Software Foundation, Inc. # # This file is part of GNU Libtool: # Originally by Gordon Matzigkeit , 1996 # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="$SED -e 1s/^X//" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # The names of the tagged configurations supported by this script. available_tags= # ### BEGIN LIBTOOL CONFIG], [# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) # Whether or not to disallow shared libs when runtime libs are static allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC # LTCC compiler flags. LTCFLAGS=$lt_LTCFLAGS # A language-specific compiler. CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) # Is the compiler the GNU C compiler? with_gcc=$_LT_AC_TAGVAR(GCC, $1) # An ERE matcher. EGREP=$lt_EGREP # The linker used to build libraries. LD=$lt_[]_LT_AC_TAGVAR(LD, $1) # Whether we need hard or soft links. LN_S=$lt_LN_S # A BSD-compatible nm program. NM=$lt_NM # A symbol stripping program STRIP=$lt_STRIP # Used to examine libraries when file_magic_cmd begins "file" MAGIC_CMD=$MAGIC_CMD # Used on cygwin: DLL creation program. DLLTOOL="$DLLTOOL" # Used on cygwin: object dumper. OBJDUMP="$OBJDUMP" # Used on cygwin: assembler. AS="$AS" # The name of the directory that contains temporary libtool files. objdir=$objdir # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # How to pass a linker flag through the compiler. wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) # Object file suffix (normally "o"). objext="$ac_objext" # Old archive suffix (normally "a"). libext="$libext" # Shared library suffix (normally ".so"). shrext_cmds='$shrext_cmds' # Executable file suffix (normally ""). exeext="$exeext" # Additional compiler flags for building library objects. pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) pic_mode=$pic_mode # What is the maximum length of a command? max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) # Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Compiler flag to prevent dynamic linking. link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) # Compiler flag to generate thread-safe objects. thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) # Library versioning type. version_type=$version_type # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Commands used to build and install an old-style archive. RANLIB=$lt_RANLIB old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) # Commands used to build and install a shared archive. archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) postinstall_cmds=$lt_postinstall_cmds postuninstall_cmds=$lt_postuninstall_cmds # Commands used to build a loadable module (assumed same as above if empty) module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) # Dependencies to place after the objects being linked to create a # shared library. postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) # Dependencies to place before the objects being linked to create a # shared library. predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) # Dependencies to place after the objects being linked to create a # shared library. postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == file_magic. file_magic_cmd=$lt_file_magic_cmd # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) # Flag that forces no undefined symbols. no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # Same as above, but a single script fragment to be evaled but not shown. finish_eval=$lt_finish_eval # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # This is the shared library runtime path variable. runpath_var=$runpath_var # This is the shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # How to hardcode a shared library path into an executable. hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) # If ld is used when linking, flag to hardcode \$libdir into # a binary during linking. This must work even if \$libdir does # not exist. hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) # Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the # resulting binary. hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) # Set to yes if building a shared library automatically hardcodes DIR into the library # and all subsequent libraries and executables linked against it. hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. variables_saved_for_relink="$variables_saved_for_relink" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) # Compile-time system search path for libraries sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" # Set to yes if exported symbols are required. always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) # The commands to list exported symbols. export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) # Symbols that must always be exported. include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) ifelse([$1],[], [# ### END LIBTOOL CONFIG], [# ### END LIBTOOL TAG CONFIG: $tagname]) __EOF__ ifelse([$1],[], [ case $host_os in aix3*) cat <<\EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi EOF ;; esac # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || \ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ]) else # If there is no Makefile yet, we rely on a make rule to execute # `config.status --recheck' to rerun these tests and create the # libtool script then. ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` if test -f "$ltmain_in"; then test -f Makefile && make "$ltmain" fi fi ])# AC_LIBTOOL_CONFIG # AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------------------- AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi ])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE # --------------------------------- AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_PROG_NM]) AC_REQUIRE([AC_OBJEXT]) # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Transform an extracted symbol line into a proper C declaration lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32*) symcode='[[ABCDGISTW]]' ;; hpux*) # Its linker distinguishes data from code symbols if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ;; linux*) if test "$host_cpu" = ia64; then symcode='[[ABCDGIRSTW]]' lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Try without a prefix undercore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if grep ' nm_test_var$' "$nlist" >/dev/null; then if grep ' nm_test_func$' "$nlist" >/dev/null; then cat < conftest.$ac_ext #ifdef __cplusplus extern "C" { #endif EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' cat <> conftest.$ac_ext #if defined (__STDC__) && __STDC__ # define lt_ptr_t void * #else # define lt_ptr_t char * # define const #endif /* The mapping between symbol names and symbols. */ const struct { const char *name; lt_ptr_t address; } lt_preloaded_symbols[[]] = { EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext cat <<\EOF >> conftest.$ac_ext {0, (lt_ptr_t) 0} }; #ifdef __cplusplus } #endif EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_save_CFLAGS" else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -f conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi ]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE # AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) # --------------------------------------- AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], [_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= _LT_AC_TAGVAR(lt_prog_compiler_static, $1)= AC_MSG_CHECKING([for $compiler option to produce PIC]) ifelse([$1],[CXX],[ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | os2* | pw32*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ;; interix3*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix4* | aix5*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; darwin*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files case $cc_basename in xlc*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; esac ;; dgux*) case $cc_basename in ec++*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | kfreebsd*-gnu | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; icpc* | ecpc*) # Intel C++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC*) # Portland Group C++ compiler. _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; vxworks*) ;; *) _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; interix3*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; sysv4*MP*) if test -d /usr/nec; then _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files case $cc_basename in xlc*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; esac ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; newsos6) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; linux*) case $cc_basename in icc* | ecc*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; esac ;; osf3* | osf4* | osf5*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" ;; esac # # Check to make sure the static flag actually works. # wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\" AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) ]) # AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) # ------------------------------------ # See if the linker supports building shared libraries. AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) ifelse([$1],[CXX],[ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in aix4* | aix5*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' else _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw*) _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' ;; *) _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ],[ runpath_var= _LT_AC_TAGVAR(allow_undefined_flag, $1)= _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_AC_TAGVAR(archive_cmds, $1)= _LT_AC_TAGVAR(archive_expsym_cmds, $1)= _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_minus_L, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown _LT_AC_TAGVAR(hardcode_automatic, $1)=no _LT_AC_TAGVAR(module_cmds, $1)= _LT_AC_TAGVAR(module_expsym_cmds, $1)= _LT_AC_TAGVAR(always_export_symbols, $1)=no _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_AC_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. extract_expsyms_cmds= # Just being paranoid about ensuring that cc_basename is set. _LT_CC_BASENAME([$compiler]) case $host_os in cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac _LT_AC_TAGVAR(ld_shlibs, $1)=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>/dev/null` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix3* | aix4* | aix5*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_AC_TAGVAR(ld_shlibs, $1)=no cat <&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. EOF fi ;; amigaos*) _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we can't use # them. _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_AC_TAGVAR(always_export_symbols, $1)=no _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; interix3*) _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; linux*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then tmp_addflag= case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; esac _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test $supports_anon_versioning = yes; then _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ $echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then _LT_AC_TAGVAR(ld_shlibs, $1)=no cat <&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. EOF elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_AC_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_AC_TAGVAR(always_export_symbols, $1)=yes _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' else _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_AC_TAGVAR(archive_cmds, $1)='' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 _LT_AC_TAGVAR(hardcode_direct, $1)=yes else # We have old collect2 _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_AC_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # see comment about different semantics on the GNU ld section _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; bsdi[[45]]*) _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; darwin* | rhapsody*) case $host_os in rhapsody* | darwin1.[[012]]) _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' ;; *) # Darwin 1.3 on if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' else case ${MACOSX_DEPLOYMENT_TARGET} in 10.[[012]]) _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' ;; esac fi ;; esac _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_automatic, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes if test "$GCC" = yes ; then output_verbose_link_cmd='echo' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else case $cc_basename in xlc*) output_verbose_link_cmd='echo' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac fi ;; dgux*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; freebsd1*) _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | kfreebsd*-gnu | dragonfly*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd*) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; openbsd*) _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi ;; os2*) _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' # Both c and cxx compiler support -rpath directly _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' if test "$GCC" = yes; then wlarc='${wl}' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' else wlarc='' _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine linker options so we # cannot just pass the convience library names through # without $wl, iff we do not link with $LD. # Luckily, gcc supports the same syntax we need for Sun Studio. # Supported since Solaris 2.6 (maybe 2.5.1?) case $wlarc in '') _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; *) _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; esac ;; esac _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_AC_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_AC_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7*) _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; esac fi ]) AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no # # Do we need to explicitly link libc? # case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_AC_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_MSG_CHECKING([whether -lc should be explicitly linked in]) $rm conftest* printf "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) _LT_AC_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) then _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no else _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $rm conftest* AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) ;; esac fi ;; esac ])# AC_LIBTOOL_PROG_LD_SHLIBS # _LT_AC_FILE_LTDLL_C # ------------------- # Be careful that the start marker always follows a newline. AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ # /* ltdll.c starts here */ # #define WIN32_LEAN_AND_MEAN # #include # #undef WIN32_LEAN_AND_MEAN # #include # # #ifndef __CYGWIN__ # # ifdef __CYGWIN32__ # # define __CYGWIN__ __CYGWIN32__ # # endif # #endif # # #ifdef __cplusplus # extern "C" { # #endif # BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); # #ifdef __cplusplus # } # #endif # # #ifdef __CYGWIN__ # #include # DECLARE_CYGWIN_DLL( DllMain ); # #endif # HINSTANCE __hDllInstance_base; # # BOOL APIENTRY # DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) # { # __hDllInstance_base = hInst; # return TRUE; # } # /* ltdll.c ends here */ ])# _LT_AC_FILE_LTDLL_C # _LT_AC_TAGVAR(VARNAME, [TAGNAME]) # --------------------------------- AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) # old names AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) # This is just to silence aclocal about the macro not being used ifelse([AC_DISABLE_FAST_INSTALL]) AC_DEFUN([LT_AC_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj, no) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS) ]) AC_DEFUN([LT_AC_PROG_RC], [AC_CHECK_TOOL(RC, windres, no) ]) # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # # LT_AC_PROG_SED # -------------- # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. AC_DEFUN([LT_AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_MSG_RESULT([$SED]) ]) # Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.9.6])]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 7 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE]) AC_SUBST([$1_FALSE]) if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 3 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # So let's grep whole file. if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 12 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.58])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl # test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $1 | $1:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_MKDIR_P # --------------- # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. # # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories # created by `make install' are always world readable, even if the # installer happens to have an overly restrictive umask (e.g. 077). # This was a mistake. There are at least two reasons why we must not # use `-m 0755': # - it causes special bits like SGID to be ignored, # - it may be too restrictive (some setups expect 775 directories). # # Do not use -m 0755 and let people choose whatever they expect by # setting umask. # # We cannot accept any implementation of `mkdir' that recognizes `-p'. # Some implementations (such as Solaris 8's) are not thread-safe: if a # parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' # concurrently, both version can detect that a/ is missing, but only # one can create it and the other will error out. Consequently we # restrict ourselves to GNU make (using the --version option ensures # this.) AC_DEFUN([AM_PROG_MKDIR_P], [if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then # We used to keeping the `.' as first argument, in order to # allow $(mkdir_p) to be used without argument. As in # $(mkdir_p) $(somedir) # where $(somedir) is conditionally defined. However this is wrong # for two reasons: # 1. if the package is installed by a user who cannot write `.' # make install will fail, # 2. the above comment should most certainly read # $(mkdir_p) $(DESTDIR)$(somedir) # so it does not work when $(somedir) is undefined and # $(DESTDIR) is not. # To support the latter case, we have to write # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), # so the `.' trick is pointless. mkdir_p='mkdir -p --' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. for d in ./-p ./--version; do test -d $d && rmdir $d done # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. if test -f "$ac_aux_dir/mkinstalldirs"; then mkdir_p='$(mkinstalldirs)' else mkdir_p='$(install_sh) -d' fi fi AC_SUBST([mkdir_p])]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR indi-0.5/.cvsignore0000644000175000017500000000027710605175720012122 0ustar jrjr*.kidl *_skel.cpp Makefile Makefile.in Makefile.rules.in autom4te.cache config.h config.log config.status libtool stamp-h1 aclocal.m4 config.h.in configure indi.kdevelop.pcs indi.kdevses doc